将SSE2和AVX内在函数与不同的编译器混合使用

时间:2018-03-12 00:05:54

标签: c x86 sse intrinsics avx

是否可以在同一个编译单元中混合使用VEX和非VEX编码的SIMD内在函数?我想这样做是为了简化代码发布到不同的编译器作为单个文件模块。

1 个答案:

答案 0 :(得分:4)

您不需要这样做,并且通常使用-march=haswell-march=core2或其他东西构建整个文件会更好,因此您可以设置调整选项以及目标指令集

但是单独的编译单元使得内联小函数变得更加困难,所以如果你小心实际上没有SSE-AVX transition penalties混合VEX /非VEX而没有{{1或者将VEX编码指令放入在没有AVX支持的CPU上运行的代码路径中。

IDK在内联时编译器如何尊重目标属性,但链接时优化可以内联使用不同选项编译的编译单元的代码,以及不会导致问题的AFAIK。

GNU C function attributes, yes 。这适用于gcc和clang,但显然不适用于ICC,即使它不拒绝属性语法。

显然它不适用于MSVC,它无论如何都有不同的命令行选项。使用MSVC,可以编译一个使用AVX内在函数但没有vzeroupper的文件,但不要这样做;它只会将VEX编码用于传统SSE无法编码的指令,如_mm_permutevar_ps (vpermilps),从而导致转换惩罚。

GNU C方式:

/arch:AVX

Compiled (on the Godbolt compiler explorer)使用gcc和clang #include <immintrin.h> __m128 addps_sse(__m128 x, __m128 y) { return x+y; // GNU C alternative to _mm_add_ps. } __attribute((target("avx"))) // <<<<<<<<<<< This line __m128 addps_avx(__m128 x, __m128 y) { return x+y; } 使SSE4.2可用(并调整Nehalem),但不启用AVX。

-O3 -march=nehalem

当然,gcc和clang都发出相同的asm。 ICC对这两个版本使用addps_sse: addps xmm0, xmm1 ret addps_avx: vaddps xmm0, xmm0, xmm1 ret (非VEX)。我没有检查ICC是否允许在启用了AVX的函数内部addps内部函数,但是gcc应该。