Я новичок в OpenMP, и я пытаюсь paralelize следующий код с помощью OpenMP:OpenMP paralelization ингибирует векторизации
#pragma omp parallel for
for(int k=0;k<m;k++)
{
for(int j=n-1;j>=0;j--)
{
outX[k+j*m] = inB2[j+n * k]/inA2[j*n + j];
for(int i=0;i<j;i++)
{
inB2[k*n+i] -= inA2[i+n * j] * outX[k + m*j];
}
}
}
Paralelize внешний цикл довольно прямо вперед, но оптимизировать его, я хотел paralelize внутренний цикл (один итерация над i). Но когда я пытаюсь сделать это так:
#pragma omp parallel for
for(int i=0;i<j;i++)
{
inB2[k*n+i] -= inA2[i+n * j] * outX[k + m*j];
}
компилятор не векторизации внутреннего цикла («цикл версионным для векторизации из-за возможное наложение»), что делает его работать медленнее. Я скомпилировал его, используя gcc -ffast-math -std=c++11 -fopenmp -O3 -msse2 -funroll-loops -g -fopt-info-vec prog.cpp
Спасибо за любой совет!
EDIT: Я использую ключевое слово __restrict для массивов.
EDIT2: Интересно, что когда я сохраняю только прагму во внутреннем цикле и удаляю ее из внешнего, gcc будет ее векторизовать. Поэтому проблема возникает, когда я пытаюсь парализовать оба цикла.
EDIT3: Компилятор будет векторизовать цикл, когда я использую #pragma omp parallel для simd. Но он все еще медленнее, чем без параллелизма внутреннего контура.
Легче векторизовать вручную, чем распараллеливать. Почему бы просто не сделать это? (и сохранить автоматическое распараллеливание) –