У меня есть критичный к производительности код, написанный для нескольких процессоров. Я обнаруживаю процессор во время выполнения и на основании этого использую соответствующую функцию для обнаруженного процессора. Итак, теперь я должен использовать указатели функций и вызывать функции, используя следующие указатели функций:
void do_something_neon(void);
void do_something_armv6(void);
void (*do_something)(void);
if(cpu == NEON) {
do_something = do_something_neon;
}else{
do_something = do_something_armv6;
}
//Use function pointer:
do_something();
...
Не то, чтобы это имело значение, но я упомяну, что я оптимизировал функции для разных процессоров: armv6 и armv7 с поддержкой NEON. Проблема в том, что при использовании указателей на функции во многих местах код замедляется, и я бы хотел избежать этой проблемы.
По сути, во время загрузки компоновщик разрешает перемещение и исправляет код с помощью адресов функций. Есть ли способ лучше контролировать это поведение?
Лично я бы предложил два разных способа избежать указателей на функции: создать два отдельных .so (или .dll) для функций, зависящих от процессора, поместить их в разные папки и, основываясь на обнаруженном ЦП, добавить одну из этих папок в поиск. путь (или LD_LIB_PATH). Загрузите основной код и динамический компоновщик выберет необходимые DLL из пути поиска. Другой способ - скомпилировать две отдельные копии библиотеки :)
Недостаток первого метода заключается в том, что он заставляет меня иметь как минимум 3 общих объекта (dll): два для функций, зависящих от процессора, и один для основного кода, который их использует. Мне нужно 3, потому что я должен быть в состоянии обнаружить процессор перед загрузкой кода, который использует эти зависимые от процессора функции. Хорошая часть первого метода заключается в том, что приложению не нужно загружать несколько копий одного и того же кода для нескольких процессоров, оно будет загружать только ту копию, которая будет использоваться. Недостаток второго метода вполне очевиден, об этом говорить не нужно.
Я хотел бы знать, есть ли способ сделать это без использования общих объектов и загрузки их вручную во время выполнения. Одним из способов может быть хакерство, которое включает в себя исправление кода во время выполнения, вероятно, это слишком сложно, чтобы сделать это правильно). Есть ли лучший способ контролировать перемещения во время загрузки? Может быть, разместить зависимые от процессора функции в разных разделах, а затем как-то указать, какой раздел имеет приоритет? Я думаю, что в мачо-формате MAC есть что-то подобное.
Мне достаточно решения только для ELF (для мишени), я не очень люблю PE (dll's).
спасибо