我正在尝试使一个函数启用SIMD并通过函数调用向量化循环。
#include <cmath>
#pragma omp declare simd
double BlackBoxFunction(const double x) {
return 1.0/sqrt(x);
}
double ComputeIntegral(const int n, const double a, const double b) {
const double dx = (b - a)/n;
double I = 0.0;
#pragma omp simd reduction(+: I)
for (int i = 0; i < n; i++) {
const double xip12 = a + dx*(double(i) + 0.5);
const double yip12 = BlackBoxFunction(xip12);
const double dI = yip12*dx;
I += dI;
}
return I;
}
对于上面的代码,如果我使用icpc
编译它:
icpc worker.cc -qopenmp -qopt-report=5 -c
优化报告显示该函数和循环均被向量化。但是,如果我尝试使用 g++ 6.5
进行编译:
g++ worker.cc -O3 -fopenmp -fopt-info-vec-missed -funsafe-math-optimizations -c
输出显示
note:not vectorized:control flow in loop。
和note:bad loop form
,循环无法矢量化。如何使用GCC矢量化循环?
编辑:
如果我将函数编写到单独的文件中,
worker.cc
:#include "library.h"
double ComputeIntegral(const int n, const double a, const double b) {
const double dx = (b - a)/n;
double I = 0.0;
#pragma omp simd reduction(+: I)
for (int i = 0; i < n; i++) {
const double xip12 = a + dx*(double(i) + 0.5);
const double yip12 = BlackBoxFunction(xip12);
const double dI = yip12*dx;
I += dI;
}
return I;
}
library.h
:
#ifndef __INCLUDED_LIBRARY_H__
#define __INCLUDED_LIBRARY_H__
#pragma omp declare simd
double BlackBoxFunction(const double x);
#endif
和 library.cc
文件:
#include <cmath>
#pragma omp declare simd
double BlackBoxFunction(const double x) {
return 1.0/sqrt(x);
}
然后我使用GCC编译它:
g++ worker.cc library.cc -O3 -fopenmp -fopt-info-vec-missed -funsafe-math-optimizations -c
它显示:
worker.cc:9:31: note: loop vectorized
但是
library.cc:5:18: note:not vectorized: control flow in loop.
library.cc:5:18: note:bad loop form.
这让我感到困惑。我想知道它是否已经矢量化。