Статическое и динамическое связывание с w.r.t. переносимость, в контексте Go [закрыто]

  1. Переведите контекст в точку на холсте, вокруг которого должен вращаться объект.
  2. Поворот контекста.
  3. Либо: Перевести контекст на отрицательное смещение внутри объект для центра вращения, а затем нарисуйте объект на 0,0 или нарисуйте изображение, используя отрицательное смещение внутри объекта для центра вращения.
  4. , например.

    ctx.save();
    ctx.translate( canvasLocX, canvasLocY );
    ctx.rotate( ballRotationInRadians );
    ctx.drawImage( ball_img, -ballCenterX, -ballCenterY );
    ctx.restore();
    

    Обратите внимание: если вам нужна абсолютная скорость, вместо сохранения и восстановления холста (обработка многих свойств, которые вы не изменили), вы можете просто отменить свою работу:

    ctx.translate( canvasLocX, canvasLocY );
    ctx.rotate( ballRotationInRadians );
    ctx.drawImage( ball_img, -ballCenterX, -ballCenterY );
    ctx.rotate( -ballRotationInRadians );
    ctx.translate( -canvasLocX, -canvasLocY );
    

    Предыдущий бит преждевременной оптимизации был слепо попугаем от кого-то другого;

    Редактировать: я добавил здесь примерный пример: http://phrogz.net/tmp /canvas_beachball.html

-1
задан Florian Weimer 19 January 2019 в 13:06
поделиться

1 ответ

В GNU / Linux почти все исполняемые файлы Go попадают в следующие категории:

  1. Те, которые включают в себя приложение, среду выполнения Go и статически связанную копию (части) glibc.
  2. Те, которые включают только приложение и среду выполнения Go, статически связаны, и ни один из glibc.
  3. Те, которые включают только приложение и среду выполнения Go, статически связаны и динамически связаны с glibc.

К сожалению, инструменты, связанные с ходом, часто объединяют их. Основная причина зависимости от glibc заключается в том, что приложение использует имя хоста и поиск пользователя (такие функции, как getaddrinfo и getpwuid_r). CGO_ENABLED=0 переключается с реализаций, подобных src/os/user/cgo_lookup_unix.go (использует glibc) на src/os/user/lookup_unix.go (не использует glibc). Реализация не-glibc не использует NSS и, таким образом, предлагает несколько ограниченные функциональные возможности (которые обычно не влияют на пользователей, которые не хранят пользовательскую информацию в LDAP / Active Directory).

В вашем случае настройка CGO_ENABLED=0 перемещает ваше приложение из третьей категории во вторую. (Существуют другие инструменты, связанные с Go, которые могут создавать приложения первого рода.) Код поиска, не относящийся к NSS, не очень велик, поэтому увеличение двоичного размера не является значительным. Поскольку среда выполнения Go уже была статически связана, даже возможно, что сокращение накладных расходов от статического связывания приведет к чистому уменьшению размера исполняемого файла.

Наиболее важная проблема, которую следует рассмотреть здесь, заключается в том, что NSS, потоки и статическое связывание не очень хорошо работают в glibc. Все программы Go являются многопоточными, и причиной (статически) связывания glibc с программами Go является именно доступ к функциям NSS. Поэтому статически связывать программы Go с glibc всегда неправильно. Это в основном всегда глючит . Даже если программы Go не были многопоточными, статически связанная программа, использующая функции NSS, нуждается в точно такой же версии glibc во время выполнения, которая использовалась во время сборки, поэтому статическое связывание такого приложения уменьшает портативность.

Все это причины, по которым приложения Go первого типа являются такой плохой идеей. Создание статически связанного приложения с использованием CGO_ENABLED=0 не имеет этих проблем, потому что эти приложения (второго типа) не содержат никакого кода glibc (за счет ограниченной функциональности функций поиска пользователя / хоста).

Если вы хотите создать переносимый двоичный файл, для которого требуется glibc, вам необходимо динамически связать ваше приложение (третий вид) в системе с самым старым glibc, который вы хотите поддерживать. Затем приложение будет работать на этой версии glibc и на всех более поздних версиях (на данный момент Go неправильно связывает libc , поэтому нет гарантии сильной совместимости даже для glibc). Дистрибутивы, как правило, совместимы с ABI, но имеют разные версии glibc. glibc делает все возможное, чтобы убедиться, что приложения, динамически связанные с более старыми версиями glibc, будут продолжать работать на новых версиях glibc, но обратное неверно: если вы связываете приложение с определенной версией glibc, оно может использовать функции (символы), которые просто недоступны в более старых версиях, поэтому приложение не будет работать с этими более старыми версиями.

0
ответ дан Florian Weimer 19 January 2019 в 13:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: