Intel I CC имеет функцию automati c, которая отправляет для выбора оптимизированной версии для каждой архитектуры длиной go. Я не знаю деталей, но похоже, что это относится только к библиотекам Intel. Кроме того, он предназначен только для эффективной версии на процессорах Intel, поэтому будет нечестно по отношению к другим производителям . Для этого есть Dr. Блог Агнера Фога
Позже в G CC 4.8 была введена функция Функция Multiversioning . Он добавляет атрибут target
, который вы объявляете в каждой версии вашей функции
__attribute__ ((target ("sse4.2")))
int foo() { return 1; }
__attribute__ ((target ("arch=atom")))
int foo() { return 2; }
int main() {
int (*p)() = &foo;
return foo() + p();
}
, который дублирует большой объем кода и является громоздким, поэтому G CC 6 добавил target_clones
, который сообщает G CC для компиляции функции для нескольких клонов. Например, __attribute__((target_clones("avx2","arch=atom","default"))) void foo() {}
создаст 3 разные версии foo
. Более подробную информацию о них можно найти в документации G CC о атрибуте функции
Синтаксис был тогда принят Clang и I CC. Производительность может быть даже лучше, чем у глобального указателя на функцию, поскольку функциональные символы могут быть разрешены во время загрузки процесса вместо времени выполнения. Это одна из причин Intel Clear Linux работает так быстро . I CC может также создать несколько версий одного l oop во время автовекторизации
Вот пример из Пример с мультиверсионностью (Часть II) вместе с demo , который о popcnt, но вы поняли
__attribute__((target_clones("popcnt","default")))
int runPopcount64_builtin_multiarch_loop(const uint8_t* bitfield, int64_t size, int repeat) {
int res = 0;
const uint64_t* data = (const uint64_t*)bitfield;
for (int r=0; r<repeat; r++)
for (int i=0; i<size/8; i++) {
res += popcount64_builtin_multiarch_loop(data[i]);
}
return res;
}
Если вы хотите сделать это вручную, вы можете сделать то же самое. Просто запустите функцию при запуске, чтобы вызвать cpuid
, чтобы определить текущую архитектуру, затем указатель функции на правильную версию
Обратите внимание, что PDEP
и PEXT
очень медленны на текущей AMD Процессоры , поэтому они должны быть включены только на Intel