Я пытаюсь включить функцию с поддержкой 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
opt-report показывает, что функция и цикл векторизованы.
Однако, если я попытаюсь скомпилировать его с 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.
Это меня смущает. Интересно, векторизовано ли оно уже?