使用多版本时的编译时AVX检测

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

我有针对两种不同架构编译的相当大的功能:

__attribute__ ((target ("arch=broadwell"))) void doStuff()
{
    doStuffImpl()
}

__attribute__ ((target ("arch=nocona"))) void doStuff()
{
    doStuffImpl();
}

__attribute__((always_inline)) void doStuffImpl()
{
    (...)
}

我知道这是进行多版本控制的旧方法,但是我使用的是gcc 4.9.3。实际上,doStuffImpl()不是单个函数,而是带有内联的函数,其中doStuff()是最后一个实际的函数调用,但我认为它不会改变任何东西。

函数包含一些由编译器自动向量化的代码,但我还需要在其中添加一些手工制作的内在函数。两种口味明显不同。问题是:如何在编译时识别哪些SIMD扩展可用?我正在尝试类似的东西:

#ifdef __AVX2__
AVX_intrinsics();
#elif defined __SSE4.2__
SSE_intrinsics();
#endif

但是似乎定义来自“全局” -march标志,而不是来自多版本覆盖的标志。

Godbolt(本性是垃圾,但显示了我的意思)

我可以提取这部分并做单独的多版本功能,但这会增加分派和函数调用的成本。有什么方法可以对两个函数的多版本变体进行编译时间区分?

gcc simd avx
1个回答
0
投票

如评论所回答:

我建议将每个CPU目标移动到一个单独的转换单元,该转换单元将使用相应的编译器标志进行编译。通用doStuffImpl功能可以在每个TU中包含的标头中实现。在该标头中,可以使用预定义的宏,例如__AVX__,以测试可用的ISA扩展。 __attribute__((target))属性不再需要,在这种情况下可以删除。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.