【问题标题】:Really basic SSE真正基础的 SSE
【发布时间】:2011-12-20 00:59:18
【问题描述】:

我有一个非常简单的程序,我正在尝试提高性能。我知道会有所帮助的一种方法是利用 SSE3(因为我正在工作的机器支持这一点),但我完全不知道如何做到这一点。下面是一段代码sn-p(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];    
  {
}

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

谢谢!

【问题讨论】:

    标签: c++ performance optimization sse sse3


    【解决方案1】:

    其实,在你的情况下,事情并没有那么简单。就目前而言,您的代码不能可矢量化。 (至少不是没有显着的循环转换)

    这样做的原因是您正在更改索引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);
      }
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-12
      • 1970-01-01
      • 2013-02-28
      • 2013-12-30
      • 2013-06-11
      • 1970-01-01
      相关资源
      最近更新 更多