Как бы вы написали код функции c как для AVX2, так и для AVX512? - PullRequest
0 голосов
/ 18 июня 2020

Один из способов сделать это - создать указатели на функции, которые условно указывают на различные функции в зависимости от директивы препроцессора, которая выбирает желаемый набор функций.

#if defined(__AVX512__)
    void (*func_ptr)() = _mm512_func;
#else
    void (*func_ptr)() = _mm256_func;
#endif

int main()
{
    func_ptr();
    return 0;
}

Есть ли лучшие способы сделать это? Спасибо.

1 Ответ

3 голосов
/ 18 июня 2020

Если вы обнаруживаете 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)

...