C++ GCC-msse2不生成SIMD代码

C++ GCC-msse2不生成SIMD代码,c++,gcc,x86,sse,simd,C++,Gcc,X86,Sse,Simd,我试图弄明白为什么g++不生成SIMD代码 信息GCC/OS/CPU: $ gcc -v gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) $ cat /proc/cpuinfo ... model name : Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz ... 这里是我的C++代码: #include <iostream> #include <cstdlib> //fun

我试图弄明白为什么g++不生成SIMD代码

信息GCC/OS/CPU:

$ gcc -v
gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)

$ cat /proc/cpuinfo
...
model name  : Intel(R) Core(TM)2 Duo CPU     P8600  @ 2.40GHz
... 

这里是我的C++代码:

#include <iostream>
#include <cstdlib>

//function that fills an array with random numbers
template<class T>
void fillArray(T *array, int n){
    srand(1);
    for (int i = 0; i < n; i++) {
        array[i] = (float) (rand() % 10);
    }
}
// function that computes the dotprod of two vectors (loop unrolled)
float dotCPP(float *src1, float *src2, int n){
    float dest = 0;
    for (int i = 0; i < n; i+=2) {
        dest += (src1[i] * src2[i]) + (src1[i+1] * src2[i+1]);                
    }
    return dest;
}

int main(int argc, char *argv[])
{

    const int n = 1200000;           
    float *a = new float[n];   //allocate data on the heap
    float something_else;      //store result
    fillArray<float>(a,n);     //function that fills the array with random numbers
    something_else = dotCPP(a, a, n);  //call function and store return value

    return 0;
}  
并使用gdb检查生成的代码:

$gdb dot
... 
(gdb) b dotCPP
(gdb) r
...
(gdb) disass
Dump of assembler code for function dotCPP(float*, float*, int):
=> 0x08048950 <+0>:     push   %ebx
   0x08048951 <+1>:     mov    0x10(%esp),%ebx
   0x08048955 <+5>:     mov    0x8(%esp),%edx
   0x08048959 <+9>:     mov    0xc(%esp),%ecx
   0x0804895d <+13>:    test   %ebx,%ebx
   0x0804895f <+15>:    jle    0x8048983 <dotCPP(float*, float*, int)+51>
   0x08048961 <+17>:    xor    %eax,%eax
   0x08048963 <+19>:    fldz   
   0x08048965 <+21>:    lea    0x0(%esi),%esi
   0x08048968 <+24>:    flds   (%edx,%eax,4)
   0x0804896b <+27>:    fmuls  (%ecx,%eax,4)
   0x0804896e <+30>:    flds   0x4(%edx,%eax,4)
   0x08048972 <+34>:    fmuls  0x4(%ecx,%eax,4)
   0x08048976 <+38>:    add    $0x2,%eax
   0x08048979 <+41>:    cmp    %eax,%ebx
   0x0804897b <+43>:    faddp  %st,%st(1)
   0x0804897d <+45>:    faddp  %st,%st(1)
   0x0804897f <+47>:    jg     0x8048968 <dotCPP(float*, float*, int)+24>
   0x08048981 <+49>:    pop    %ebx
   0x08048982 <+50>:    ret    
   0x08048983 <+51>:    fldz   
   0x08048985 <+53>:    pop    %ebx
   0x08048986 <+54>:    ret    
End of assembler dump.
现在我是否遗漏了什么,或者gcc是否应该使用xmm寄存器

如果有任何建议能帮助我理解为什么gcc不生成使用xmm寄存器的代码,我将不胜感激

如果您需要任何进一步的信息,请告诉我。

-march=core2意味着gcc可以与64位ISA一起提供SSSE3,例如MMX、SSE、SSE2、SSE3

-mfpmath=sse可以在64位模式下强制使用sse进行浮点运算,而不是在32位m32模式下强制使用387

请参阅手册页中的“英特尔386和AMD x86-64选项”部分


不幸的是,您仍然受到32位模式和32位ABI的限制。e、 例如,仅寄存器XMM0。。XMM7可用;XMM8。。XMM15仅在64位模式下可用。

尝试摆脱dotCPP中的手动循环展开-保持标量代码尽可能简单可能有助于编译器发现SIMD优化的潜力。尽管编译器在SIMD优化方面仍然不是很好,所以如果这真的是性能关键的话,您可能不得不求助于使用SSE内部函数。我也有同样的问题。如果我记得正确的话,我必须使用-Mask=本地或类似的-Max选项来解决这个问题。FWIW我用CLAN尝试了上面的代码,它确实为DOTCPP生成了SSE指令,即使在用-M32—MSSE2编译时,所以你可能想考虑使用CLAN而不是GCC。@保罗:我确实尝试了不展开的循环。同样的结果。嗯,我有一段时间没和叮当声在一起了。但是谢谢,我会试试看。试试:-march=core2和add:-mfpmath=sse
$gdb dot
... 
(gdb) b dotCPP
(gdb) r
...
(gdb) disass
Dump of assembler code for function dotCPP(float*, float*, int):
=> 0x08048950 <+0>:     push   %ebx
   0x08048951 <+1>:     mov    0x10(%esp),%ebx
   0x08048955 <+5>:     mov    0x8(%esp),%edx
   0x08048959 <+9>:     mov    0xc(%esp),%ecx
   0x0804895d <+13>:    test   %ebx,%ebx
   0x0804895f <+15>:    jle    0x8048983 <dotCPP(float*, float*, int)+51>
   0x08048961 <+17>:    xor    %eax,%eax
   0x08048963 <+19>:    fldz   
   0x08048965 <+21>:    lea    0x0(%esi),%esi
   0x08048968 <+24>:    flds   (%edx,%eax,4)
   0x0804896b <+27>:    fmuls  (%ecx,%eax,4)
   0x0804896e <+30>:    flds   0x4(%edx,%eax,4)
   0x08048972 <+34>:    fmuls  0x4(%ecx,%eax,4)
   0x08048976 <+38>:    add    $0x2,%eax
   0x08048979 <+41>:    cmp    %eax,%ebx
   0x0804897b <+43>:    faddp  %st,%st(1)
   0x0804897d <+45>:    faddp  %st,%st(1)
   0x0804897f <+47>:    jg     0x8048968 <dotCPP(float*, float*, int)+24>
   0x08048981 <+49>:    pop    %ebx
   0x08048982 <+50>:    ret    
   0x08048983 <+51>:    fldz   
   0x08048985 <+53>:    pop    %ebx
   0x08048986 <+54>:    ret    
End of assembler dump.