【发布时间】:2018-02-12 17:07:58
【问题描述】:
我想用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)
更新
主要问题是,如下所述,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];
}
}
【问题讨论】:
-
您是否有理由不使用
-O3运行?您是否查看过反汇编以表明编译器没有已经矢量化您的循环? (它应该在-O3之下。) -
第一步:丢失
j循环。最后一次迭代覆盖了由较低值j完成的所有工作。实现的操作是,AFAICT,我的伪代码采用 Matlab 语法:c(1:end) = a(1:end) + b(end) -
你的代码的目的是什么?内部循环缩小到
c[i] = a[i] + b[N-1]; -
是的,抱歉应该是
+=而不是=(更新) -
给出的总和真的是你想要的吗?由于它等价于(模舍入误差):foreach i c[i] += N*a[i] + B,其中 B = Sum{ j | b[j]}
标签: c++ for-loop vectorization