启用arch:SSE2会使程序变慢

Enabling arch:SSE2 makes program slower

本文关键字:程序 arch SSE2 启用      更新时间:2023-10-16

在Visual Studio 2010上,当我在以下代码上启用增强指令集时,执行时间实际上会增加。

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;
}

在启用SSE2的情况下,time变量的时间一直是2.0秒,但在"未设置"的情况下大约是1.7秒。我是在Windows 7 64位,VS 2010专业版,发布配置,优化速度。

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

在SSE代码中将值移入和移出SSE寄存器时会产生开销,如果您只进行很少的简单计算,则可能会超过SSE的性能优势,例如您的示例。

还要注意的是,如果您的数据不是16字节对齐的,则此开销会显著增加。

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

1确保您的阵列是16字节对齐的

2在内联添加函数中使用SSE内部函数:

#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) ) );
}

如果这不能产生更快的代码,那么加载和存储确实会为单个乘法运算带来太多开销。