您将如何为AVX2和AVX512编写功能不可知代码?

问题描述 投票:0回答:1

执行此操作的一种方法是创建函数指针,该函数指针根据选择所需功能集的预处理程序指令有条件地指向不同的函数。

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

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

还有更好的方法吗?谢谢。

c++ c-preprocessor intrinsics avx2 avx512
1个回答
3
投票

如果仅在编译时检测到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)(),那么您可以指望它被内联/优化。您确实不想在不需要时增加额外的调度开销(例如,对于runtime CPU检测,在运行cpuid的init函数中设置函数指针)

© www.soinside.com 2019 - 2024. All rights reserved.