C 矢量化双回路

C++ vectorize double loop

本文关键字:回路 矢量化      更新时间:2023-10-16

我想用 omp simd矢量化循环。我的问题是以下形式:

#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(

update

主要问题是,如下所述,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];
    }
  }

代码的主要问题是循环迭代计数在执行循环之前无法计算。您需要用 n 。。

第二个问题是,如果您要矢量化外循环,则 c [i] = a [i] b [j] 的说明会导致 flow >抗依赖项。对于OveCome,我尝试将内部循环进行矢量化,并且我的代码成功地为矢量化。

您可以在下面的页面中阅读有关反和流依赖性的更多信息:https://en.wikipedia.org/wiki/data_dependency

i在矢量化后达到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];
        }
    }