获得GCC以32位代码(-m32)使用AVX吗?

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

我有一个C程序,该程序只能在要编译代码的Ivy Bridge CPU上运行,在gcc 4.8上,我尝试使用-march=native进行编译以利用CPU的所有特定指令。为了进行一些研究比较,我也希望以32位模式进行编译]

我已经以这种方式为x64编译了程序(请注意我在Linux x64上)

gcc -march=native -s -O2 mycode.c

并且分解代码,我可以看到使用了AVX指令集

并且以这种方式用于32位x86

gcc -m32 -march=native -s -O2 mycode.c

如果我尝试反汇编代码,则看不到任何AVX指令,指令集为Pentium Pro,80x87。类似于FP数学中的fld /fadd/ fstp。添加-mavx无效,结果相同。

我该如何解决?

c linux gcc compiler-optimization avx
2个回答
0
投票

GCC 4.8.3 manual

-m32-m64-mx32

为32位或64位环境生成代码。 -m32选项将int,long和指针类型设置为32位,并生成可在任何i386系统上运行的代码。-m64选项将int设置为32位,将long和指针类型设置为64位,并为x86-64体系结构生成代码。对于达尔文,仅-m64选项还会关闭-fno-pic和-mdynamic-no-pic选项。

-mx32选项将int,long和指针类型设置为32位,并为x86-64体系结构生成代码。

您要使用AVX指令最接近-m32的地方是使用-mx32,但可能不是您想要的。


0
投票

-m32的默认值为-mfpmath=387

GCC4.8 如果使用-O3 -m32 -march=native进行编译,则使用AVX自动矢量化,但是要获得标量AVX数学,例如vmovss xmm0, DWORD PTR [edx+eax*4]也使用-mfpmath=sse

例如

void foo(float *arr){
    for(int i=0;i<4096;i++){
        arr[i] *= 2;
    }
}

在Skylake-X上将on Godbolt with gcc4.8.5 -m32 -O2 -Wall -march=native编译为此:

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

-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可能具有的其他任何功能。


BTW,-o2将输出文件名设置为2-s生成一个剥离的二进制文件,几乎不需要您拆卸。

© www.soinside.com 2019 - 2025. All rights reserved.