2012-03-13 63 views
3

在Visual Studio 2010上,当我在以下代码上启用增强指令集时,执行时间实际上增加了。启用拱形:SSE2使程序变慢

void add(float * input1, float * input2, float * output, int size) 
{ 
    for(int iter = 0; iter < size; iter++) 
    { 
     output[iter] = input1[iter] * input2[iter]; 
    } 
} 

int main() 
{ 

    const int SIZE = 10000000; 
    float *in1 = new float[SIZE]; 
    float *in2 = new float[SIZE]; 
    float *out = new float[SIZE]; 
    for(int iter = 0; iter < SIZE; iter++) 
    { 
     in1[iter] = std::rand(); 
     in2[iter] = std::rand(); 
     out[iter] = std::rand(); 
    } 
    clock_t start = clock(); 
    for(int iter = 0; iter < 100; iter++) 
    { 
     add(in1, in2, out, SIZE); 
    } 
    clock_t end = clock(); 
    double time = difftime(end,start)/(double)CLOCKS_PER_SEC; 

    system("PAUSE"); 
    return 0; 
} 

我一直获得约2.0秒为time变量,支持SSE2,而是1.7秒当“未设置”。我建立在Windows 7 64位,VS 2010专业版,发布配置,优化速度。

有没有解释为什么启用SSE会导致更长的执行时间?

+3

你看过生成的程序集,看它是否使用了任何SSE指令? – 2012-03-13 21:54:34

+0

你是用调试版本还是发行版本来做这个? – 2012-03-13 22:01:50

+0

@RetiredNinja我真的不太了解汇编,但是我可以确认它只使用启用了SSE的版本编译时使用SSE(xmm1和xmm0)所需的寄存器。 – contrapsych 2012-03-13 22:04:31

回答

2

SSE代码中有一个用于将值移入和移出SSE寄存器的开销,如果您只进行非常少的简单计算(如示例中的情况),那么这可能会超过SSE的性能优势。

另请注意,如果您的数据不是16字节对齐,则此开销将显着增大。

+2

这与这种情况无关,因为MSVC没有进行矢量化。所以它只是使用SSE寄存器来代替x87 FPU。没有“移动”。同样,对齐只能用于向量SSE-- MSVC本身不生成。 – Mysticial 2012-03-13 22:43:51

+0

我之前使用过SSE编译器内部函数,并且注意到了加速,所以如果您必须明确地使用SSE,那么首先使用arch:SSE编译器选项有什么意义? – contrapsych 2012-03-13 23:15:47

+0

@Mystical:好点,我实际上并不知道MSVC根本没有矢量化。尽管如此,文档说它可能会使用x87和SSE2代码的混合,这可能会导致一些移动(尽管我很难想象编译器会在这样一个简单的例子中搞砸了)。唯一确定的方法当然是检查组件。 – ComicSansMS 2012-03-13 23:18:47

2

IMO,通常不是一个好主意,依靠编译器来做这些优化。你的代码应该运行得更快(除非编译器已经为你做了,但似乎并非如此)。我建议

1确保您的数组是16字节对齐

2使用上证所内部函数在您的内联添加功能:

#include <xmmintrin.h> 
inline void add(const float * input1, const float * input2, float * output, int size) 
{ 
    // assuming here that 
    // - all 3 arrays are 16-byte aligned 
    // - size is a multiple of 4 
    for(int iter = 0; iter < size; iter += 4) 
    _mm_store_ps(output+iter, _mm_mul_ps(_mm_load_ps(input1+iter), 
              _mm_load_ps(input2+iter))); 
} 

如果这不会产生更快的代码,那么确实是加载和存储为单个乘法操作创建太多开销。