Если вы обнаруживаете AVX512 только во время компиляции, вам не нужны указатели на функции.
Самый простой способ: вообще не определять разные имена для одной и той же функции , просто выберите определение для компиляции в файле .cpp
, где у вас есть несколько его версий. Это сохраняет диспетчеризацию во время компиляции изолированной от файла, который определяет функцию, невидимой для остальной части вашего кода.
#ifdef __AVX512F__
void func(float *__restrict a, float *__restrict b) {
... // AVX512 version here
}
#elif defined(__AVX2__) && defined(__FMA__)
void func(float *__restrict a, float *__restrict b) { // same name
... // AVX2 version here
}
#else
... // SSE2 or scalar fallback
#endif
Хотя для тестирования вы, вероятно, захотите иметь возможность создавать все его версии и протестируйте + сравните их друг с другом, поэтому вы можете рассмотреть возможность использования #define func _mm512_func
или некоторых уловок препроцессора внутри этого одного файла. Может быть, другой ответ будет лучше для этого.
Я думал, что указатели на функции предпочтительнее макросов в сообществе C ++. Но это делает ту же работу
Возможно, если функциональная точка равна void (*static const func_ptr)()
, тогда вы можете рассчитывать, что она будет встроена / оптимизирована. Вы действительно не хотите добавлять дополнительные накладные расходы на отправку, если они вам не нужны (например, для времени выполнения обнаружения ЦП, установки указателей функций в функции инициализации, которая запускает cpuid
)