真正基本的SSE

时间:2011-11-02 05:23:45

标签: c++ performance optimization sse sse3

我有一个非常简单的程序,我正在努力提高性能。我知道的一种方法是帮助使用SSE3(因为我工作的机器支持这个),但我完全不知道如何做到这一点。这是一段代码片段(c ++):

int sum1, sum2, sum3, sum4;
for (int i=0; i<length; i+=4) {
  for (int j=0; j<length; j+=4) {
    sum1 = sum1 + input->value[i][j];
    sum2 = sum2 + input->value[i+1][j+1];
    sum3 = sum3 + input->value[i+2][j+3];
    sum4 = sum4 + input->value[i+3][j+4];    
  {
}

我已经阅读了一些关于此的内容,并理解了这个想法,但我完全不知道如何实现这一点。有人可以帮帮我吗?我认为这很简单,特别是对于我的简单程序,但有时候入门是最难的部分。

谢谢!

1 个答案:

答案 0 :(得分:6)

实际上,在你的情况下,并不是那么简单。就目前而言,您的代码 NOT 可矢量化。 (至少没有明显的循环变换)

这样做的原因是你在内部循环中也改变了索引i。由于内存位置不再相邻且位于矩阵的不同行中,因此可以对j迭代进行矢量化。 (因为你似乎沿着对角线向下运行)

然而,我觉得你是在试图总结矩阵中的所有元素,而你实际上是想让你的循环像这样(你也有一些拼写错误):

int sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0;
for (int i=0; i<length; i++) {
  for (int j=0; j<length; j+=4) {
    sum1 = sum1 + input->value[i][j];
    sum2 = sum2 + input->value[i][j+1];
    sum3 = sum3 + input->value[i][j+2];
    sum4 = sum4 + input->value[i][j+3];    
  }
}

int total = sum1 + sum2 + sum3 + sum4;

如果这是你想要的,那么它是非常可矢量化的。 在使用内在函数的C / C ++中,只需使用SSE2即可完成以下操作:

__m128i sum = _mm_setzero_si128();
for (int i=0; i<length; i++) {
  for (int j=0; j<length; j+=4) {
    __m128i val = _mm_load_si128(&input->value[i][j]);
    sum = _mm_add_epi32(sum,val);
  }
}

请注意,对齐限制将适用。通过进一步展开循环可以获得更多的加速。