让GCC在32位代码(-m32)中使用AVX?
我有一个C程序,只能在我编译代码的常春藤桥CPU上运行,在gcc 4.8上,我尝试使用让GCC在32位代码(-m32)中使用AVX?,c,linux,gcc,compiler-optimization,avx,C,Linux,Gcc,Compiler Optimization,Avx,我有一个C程序,只能在我编译代码的常春藤桥CPU上运行,在gcc 4.8上,我尝试使用-march=native编译,以利用CPU的所有特定指令。 我还想在32位模式下编译它,以便进行一些研究比较 我以这种方式为x64编译了程序(注意,我使用的是Linux x64) 和反汇编代码,我可以看到,AVX指令集的使用 以这种方式,32位x86 gcc -m32 -march=native -s -O2 mycode.c 如果我试图反汇编代码,我看不到任何AVX指令,指令集是奔腾Pro,80x87。类
-march=native
编译,以利用CPU的所有特定指令。
我还想在32位模式下编译它,以便进行一些研究比较
我以这种方式为x64编译了程序(注意,我使用的是Linux x64)
和反汇编代码,我可以看到,AVX指令集的使用
以这种方式,32位x86
gcc -m32 -march=native -s -O2 mycode.c
如果我试图反汇编代码,我看不到任何AVX指令,指令集是奔腾Pro,80x87。类似于FP数学的fld
/fadd
/fstp
。添加-mavx
没有帮助,结果相同
如何解决此问题?来自:
-m32
-m64
-mx32
为32位或64位环境生成代码。-m32选项将int、long和指针类型设置为32位,并生成在任何i386系统上运行的代码。
-m64选项将int设置为32位,将long和指针类型设置为64位,并为x86-64体系结构生成代码。对于Darwin,只有-m64选项还关闭了-fno pic和-mdynamic no pic选项
-mx32选项将int、long和指针类型设置为32位,并为x86-64体系结构生成代码
使用AVX指令,最接近
-m32
的方法是使用-mx32
,但它可能不是您想要的。-m32
的默认值是-mfpmath=387
如果您使用-O3-m32-march=native
编译,GCC4.8将使用AVX自动矢量化,但要获得标量AVX数学,如vmovss xmm0、DWORD PTR[edx+eax*4]
,也使用-mfpmath=sse
e、 g
在-O3
中,它将x87用于标量引入/清除,但仍将vaddps ymm
用于主循环
或者使用-mfpmath=sse
-m32-O2-Wall-march=native
我们可以得到您可能期望的:
foo(float*):
mov edx, DWORD PTR [esp+4]
xor eax, eax
.L3:
vmovss xmm0, DWORD PTR [edx+eax*4]
vaddss xmm0, xmm0, xmm0
vmovss DWORD PTR [edx+eax*4], xmm0
add eax, 1
cmp eax, 4096
jne .L3
rep ret
我使用了-march=native
,因为gcc4.8.5对于-march=ivybridge
来说太旧了,我不想建议使用-march=corei7 avx
或他们以前使用的任何愚蠢的名称。而且肯定不想建议只使用-mavx
,它在不设置调优选项的情况下启用AVX,将其保留在-mtune=generic
。并且无法启用popcnt、BMI或CPU可能具有的任何其他功能
顺便说一句,
-o2
将输出文件名设置为2
。而且-s
生成一个精简的二进制文件,这很难满足您的反汇编要求。-mavx没有告诉编译器它必须使用AVX指令,只是如果它想。。。但也许它决定使用它们不会产生更好的效果code@JonathanWakely我知道,但似乎很奇怪,为x64编译的同一个程序利用了AVX,而在x86中却宁愿避免使用这些。(此外,在x86中,如果没有新的istruction集,生成的代码要长得多。)gcc可能“认为”32位操作系统(和64位操作系统32位仿真)没有256位YMM状态支持-不过mavx应该已经启用了优化功能。人们通常不再关心32位。“如果您想提高性能,请升级到64位。然后我们可以交谈。”甚至Intel也表现出了一点这一点,因为AVX512在32位上会坚持使用8个寄存器,但在64位上会得到32个寄存器。感谢现在的答案,我尝试测试-mx32yes with-mx32似乎也使用AVX istruction,但由于某种原因尝试反编译时生成的程序集完全是一场灾难,几乎无法读取。如果我为x64或使用-m32编译,则在这两种情况下都是可读的
void foo(float *arr){
for(int i=0;i<4096;i++){
arr[i] *= 2;
}
}
foo(float*):
mov edx, DWORD PTR [esp+4]
xor eax, eax
.L3:
fld DWORD PTR [edx+eax*4]
fadd st, st(0)
fstp DWORD PTR [edx+eax*4]
add eax, 1
cmp eax, 4096
jne .L3
rep ret
foo(float*):
mov edx, DWORD PTR [esp+4]
xor eax, eax
.L3:
vmovss xmm0, DWORD PTR [edx+eax*4]
vaddss xmm0, xmm0, xmm0
vmovss DWORD PTR [edx+eax*4], xmm0
add eax, 1
cmp eax, 4096
jne .L3
rep ret