C ++矢量化双循环

时间:2018-02-12 17:07:59

标签: c++ for-loop vectorization

我想用omp simd向量化一个双for循环。我的问题是以下形式:

#include <vector>

using namespace std;

#define N 8000

int main() {
  vector<int> a;
  vector<int> b;
  vector<int> c;

  a.resize(N);
  b.resize(N);
  c.resize(N);

#pragma omp simd collapse(2)
  for (unsigned int i = 0; i < c.size(); ++i) {
    for (unsigned int j = 0; j < c.size(); ++j) {
      c[i] += a[i] + b[j];
    }
  }
}

当我使用g++ -O2 -fopenmp-simd -fopt-info-vec-all编译时,矢量化报告指出:

note: not vectorized: not suitable for gather load _14 = *_42;

如何转换代码以便编译器自动对其进行矢量化?

(编译器:g++ 5.4.0,CPU支持AVX2

更新

如下所述,主要问题是c的数据依赖性,其中只有内部循环似乎是可矢量化的。解决依赖关系,可以通过切换循环来实现,如下所示。编译器现在为我自动矢量化了。

  for (unsigned int j = 0; j < c.size(); ++j) {
  #pragma omp simd
    for (unsigned int i = 0; i < c.size(); ++i) {
      c[i] += a[i] + b[j];
    }
  }

1 个答案:

答案 0 :(得分:1)

代码的主要问题是循环迭代计数在执行循环之前无法计算。您需要将 c.size()替换为 N

第二个问题是如果你想要矢量化外循环, c [i] = a [i] + b [j] 的陈述导致依赖项。为了解决这些问题,我尝试向量化内部循环,我的代码成功地进行了向量化。

您可以在下面的页面中阅读有关Anti和Flow Dependencies的更多信息: https://en.wikipedia.org/wiki/Data_dependency

矢量化后我达到6.3加速。 最后我的代码如下所示:

for (unsigned int i = 0; i < N; ++i) 
{
        #pragma simd
        for (unsigned int j = 0; j < N; ++j) 
        {
            c[i] = a[i] + b[j];
        }
    }
相关问题