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

标签 c++ gcc x86 sse simd

我想弄清楚为什么 g++ 不生成 SIMD 代码。

信息 GCC/操作系统/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;
}  

我编译代码:

makefile:
CXX = g++
CXXFLGS = -g -Wall -std=c++11 -msse2 -O3
SRC = main.o dot.o 
EXEC = dot

$(EXEC): $(SRC)
    $(CXX) $(CXXFLGS) $(SRC) -o $(EXEC)
main.o: dot.cpp
    $(CXX) $(CXXFLGS) -c dot.cpp -o main.o

并使用 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 然后可以强制使用 SSE 进行浮点运算(64 位模式下的默认值),而不是 387(32 位模式下的默认值 - m32 模式)。

请参阅:手册页中的“Intel 386 和 AMD x86-64 选项”部分。

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

关于c++ - GCC -msse2 不生成 SIMD 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28235484/

相关文章:

c - 将 C 程序翻译成 IA32 程序集(非常快)

assembly - 你如何区分 "MOV r/m64, imm32"和 MASM64 中的 "MOV r/m32, imm32"?

c++ - 如何在 C++ 代码中使用 "c-style flags enum"?

c++ - 删除 msvc dll 依赖以运行 qt 应用程序

c++ - 未生成隐式移动函数

gcc - 了解新的 gcc 序言

linux - 如何编译独立的 FFTW 库?

linux - 在 Linux 中编译 Visual C++ 代码?

c++ - 在Qt main函数中,QApplication是如何获知Mainwindow的?

c - 使用函数 _mm_clflush 刷新大型结构的正确方法