使用 AVX 矢量警告编译遗留 GCC 代码

Compiling legacy GCC code with AVX vector warnings

我一直在尝试在 google 上搜索,但找不到任何有用的信息。

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);

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

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

因此编译器无法传递或 return 寄存器中的 256b 向量,就像正常调用约定指定的那样。可能它将它们视为与按值传递的那种大小的结构相同。

请参阅维基百科 tag wiki, or the x86 Calling Conventions 页面中的 ABI 链接(大部分未提及向量寄存器)。


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

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