使用 AVX 矢量警告编译旧版 GCC 代码

use*_*498 3 c++ gcc avx

我一直试图在谷歌上搜索,但找不到任何有用的东西。

typedef int64_t v4si __attribute__ ((vector_size(32)));

//warning: AVX vector return without AVX enabled changes the ABI [-Wpsabi]
// so isn't AVX already automatically enabled? 
// What does it mean "without AVX enabled"?
// What does it mean "changes the ABI"?
inline v4si v4si_gt0(v4si x_);

//warning: The ABI for passing parameters with 32-byte alignment has changed in GCC 4.6
//So why there's warning and what does it mean? 
// Why only this parameter got warning?
// And all other v4si parameter/arguments got no warning?
void set_quota(v4si quota);
Run Code Online (Sandbox Code Playgroud)

Pet*_*des 7

那不是遗留代码。 __attribute__ ((vector_size(32)))表示 32 字节向量,即 256 位,(在 x86 上)表示 AVX。(GNU C 向量扩展

除非您使用-mavx(或-march包含它的设置),否则不会启用 AVX 。没有它,编译器就不能生成使用 AVX 指令的代码,因为这些代码会在不支持 AVX 的旧 CPU 上触发非法指令错误。

所以编译器不能像正常调用约定指定的那样在寄存器中传递或返回 256b 向量。可能它会将它们视为按值传递的那种大小的结构。

请参阅标记 wiki 中的 ABI 链接,或维基百科上的x86 调用约定页面(大部分未提及向量寄存器)。


由于 GNU C Vector Extensions 语法不依赖于任何特定硬件,因此使用 32 字节向量仍将编译为正确的代码。它的性能会很差,但即使编译器只能使用 SSE 指令,它仍然可以工作。(上次我看到,gcc 在生成代码以处理比目标机器支持的向量更宽的向量方面做得非常糟糕。对于具有 16B 向量的机器,vector_size(16)手动使用会得到明显更好的代码。)

无论如何,关键是您会收到警告而不是编译器错误,因为__attribute__ ((vector_size(32)))并不特别暗示 AVX,但需要 AVX 或其他一些 256b 向量指令集才能编译为好的代码。