有没有办法用 gcc 自动生成 MMX 指令(不是 SSE)

Posted

技术标签:

【中文标题】有没有办法用 gcc 自动生成 MMX 指令(不是 SSE)【英文标题】:Is there a way to auto-generate MMX instructions (not SSE) with gcc 【发布时间】:2019-09-29 00:59:31 【问题描述】:

gcc 似乎很乐意自动矢量化简单示例,并发出 SSE 指令。有没有办法只发出 MMX 指令?

例如,如果我在 Godbolt 上尝试以下示例:

int sumint(int *arr) 
    int sum = 0;
    for (int i=0 ; i<2048 ; i++)
        sum += arr[i];
    
    return sum;

在 GCC 9.2 上使用 -mmmx -O3 -m32 -msse2 编译,我明白了

sumint:
        mov     eax, DWORD PTR [esp+4]
        pxor    xmm0, xmm0
        lea     edx, [eax+8192]
.L2:
        movdqu  xmm2, XMMWORD PTR [eax]
        add     eax, 16
        paddd   xmm0, xmm2
        cmp     edx, eax
        jne     .L2
        movdqa  xmm1, xmm0
        psrldq  xmm1, 8
        paddd   xmm0, xmm1
        movdqa  xmm1, xmm0
        psrldq  xmm1, 4
        paddd   xmm0, xmm1
        movd    eax, xmm0
        ret

但如果没有 sse(即-mmmx -O3 -m32 -mno-sse2),它会退回到仅使用通用寄存器,并且没有 mmx 指令:

sumint:
        mov     eax, DWORD PTR [esp+4]
        xor     edx, edx
        lea     ecx, [eax+8192]
.L2:
        add     edx, DWORD PTR [eax]
        add     eax, 4
        cmp     eax, ecx
        jne     .L2
        mov     eax, edx
        ret

我想运行一些基准测试,比较仅使用 x87-fpu、MMX、SSE 和 SSE2 运行的效果,但是如果 gcc 不会发出 MMX 指令,那么在 x87 和编译之间不会有任何区别x87+mmx。

【问题讨论】:

IDK 如果旧版本的 GCC 知道如何为 MMX 自动矢量化。也许在 Godbolt 上尝试最古老的 GCC,尽管这可能仍然行不通。 添加标志 -fopt-info-vec-missed 给出:missed: not vectorized: relevant stmt not supported: sum_10 = _4 + sum_15; 所以可能 MMX-autovectorization 只是没有实现 【参考方案1】:

GCC 无法使用 MMX 或 3DNow 进行自动矢量化!因为它缺乏正确插入 EMMS/FEMMS 的能力。您必须将 ICC 用于 MMX。见https://gcc.gnu.org/ml/gcc-patches/2004-12/msg01955.html

【讨论】:

vzeroupper 在使用 YMM 寄存器后(在 AVX 指令中)是同样的问题,现在已经解决了。如果有人关心过时的 MMX,修改 GCC 以以同样的方式插入 EMMS 可能不是大量的工作,允许重新启用 MMX auto-vec(如果它没有被禁用 15 年后被 bit-rot 剪掉或变得无用)。不太可能值得任何人在现实生活中的时间,只是一个观察。感谢您发布此信息;我有时想知道为什么即使使用-march=pmmx,现代 GCC 似乎也无法使用 MMX 自动 vec

以上是关于有没有办法用 gcc 自动生成 MMX 指令(不是 SSE)的主要内容,如果未能解决你的问题,请参考以下文章

MMX 是不是真的支持 PADDD 指令,即使英特尔的手册中没有它?

有没有办法用avx2自动替换avx512?

如何使用 gcc 生成 Intel 语法的汇编代码?

GCC 标志忽略指令依赖

使用 MMX 指令添加压缩字节/字

将 MMX/SSE 指令移植到 AltiVec