您将如何为 AVX2 和 AVX512 编写与功能无关的代码?
How would you write feature agnostic code for both AVX2 and AVX512?
一种方法是创建函数指针,根据选择所需功能集的预处理器指令有条件地指向不同的函数。
#if defined(__AVX512__)
void (*func_ptr)() = _mm512_func;
#else
void (*func_ptr)() = _mm256_func;
#endif
int main()
{
func_ptr();
return 0;
}
有更好的方法吗?谢谢
如果您仅在编译时检测 AVX512,则不需要函数指针。
最简单的方法:根本不要为同一个函数定义不同的名称,只需 select 在具有多个版本的 .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
,或在该文件中使用一些预处理器技巧.也许另一个答案对此有更好的主意。
I thought function pointers were preferred over macros in the C++ community. But this does the same job
也许如果功能点是 void (*static const func_ptr)()
那么您可以指望它被内联/优化掉。如果不需要,您真的不想为调度添加额外的开销(例如,对于 runtime CPU 检测,在运行 cpuid
)
一种方法是创建函数指针,根据选择所需功能集的预处理器指令有条件地指向不同的函数。
#if defined(__AVX512__)
void (*func_ptr)() = _mm512_func;
#else
void (*func_ptr)() = _mm256_func;
#endif
int main()
{
func_ptr();
return 0;
}
有更好的方法吗?谢谢
如果您仅在编译时检测 AVX512,则不需要函数指针。
最简单的方法:根本不要为同一个函数定义不同的名称,只需 select 在具有多个版本的 .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
,或在该文件中使用一些预处理器技巧.也许另一个答案对此有更好的主意。
I thought function pointers were preferred over macros in the C++ community. But this does the same job
也许如果功能点是 void (*static const func_ptr)()
那么您可以指望它被内联/优化掉。如果不需要,您真的不想为调度添加额外的开销(例如,对于 runtime CPU 检测,在运行 cpuid
)