I'm attempting to make a function SIMD-enabled and vectorize the loop with a function call.
#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;
}
For the code above, if I compile it with icpc:
icpc worker.cc -qopenmp -qopt-report=5 -c
The opt-report shows that the function and loop are both vectorized.
However, if I try to compile it with g++ 6.5:
g++ worker.cc -O3 -fopenmp -fopt-info-vec-missed -funsafe-math-optimizations -c
The output shows note:not vectorized: control flow in loop. and note: bad loop form, and the loop cannot be vectorized.
How can I vectorize the loop with GCC?
EDIT :
If I write the function into a separate file,
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
and library.cc:
#include <cmath>
#pragma omp declare simd
double BlackBoxFunction(const double x) {
return 1.0/sqrt(x);
}
Then I compile it with GCC:
g++ worker.cc library.cc -O3 -fopenmp -fopt-info-vec-missed -funsafe-math-optimizations -c
It shows:
worker.cc:9:31: note: loop vectorized
but
library.cc:5:18: note:not vectorized: control flow in loop.
library.cc:5:18: note:bad loop form.
It makes me confused. I wonder whether it is already vectorized.
BlackBoxFunctiondoes it work?control flow in loopandbad loop form