2014-01-27 3 views
3

У меня есть цикл for на C++, который занимает много времени на вычисление и что я хотел бы распараллеливать с помощью OpenMP (у меня есть 16 ядер). Другие, более простые для циклов и БПФ моего кода уже распараллеливаются с OpenMP и отлично работают. Я попробовал некоторые варианты, но результаты были ничем (разница в порядках величины), подобная той, которую вычисляли последовательно.параллельное суммирование массивов с openmp в C++

Моя соответствующая часть моего кода выглядит, по существу, как следующее:

for (i1=1;i1<N;i1++){ 
    function(Nx, Ny, i1, k, vector_1, vector_2); 
    for (i=0;i<(Nx*Ny);i++){ 
     vector_3[i] = I*kx[i/Ny]*vector_2[i]; 
    } 
    for (i=0;i<(Nx*Ny);i++){ 
     sum[i1-1] -= vector_2[i]; 
    } 

    fftw_execute(p_c2r_4); 
    #pragma omp parallel for default(shared) 
    for (i=0;i<(Nx*Ny);i++){ 
     vector_4[i] = vector_4[i]/norm; 
    } 

    for (i2=1;i2<N;i2++){ 
    function(Nx, Ny, i2, k, vector_1, vector_2); 
     for (i=0;i<(Nx*Ny);i++){ 
      Trans[(i1-1)*N + (i2-1)] -= creal(vector_2[i]*vector_4[i]); 
     } 
    } 
} 

Один из за-петель уже распараллеливание, так что моя цель состоит в том, чтобы распараллелить другие. Для сумм я видел других, используя reduction(+:sum), но в моем случае sum - это массив, и я получаю сообщение об ошибке при компиляции.

Может кто-нибудь дать мне подсказку, потому что это большое узкое место в моем коде?

+0

Что такое #pragmas, который вы положили? – ChronoTrigger

+0

Ну, я пробовал '#pragma omp parallel для default (shared)' в каждом цикле, но результат был совершенно неправильным. Затем я попытался сделать некоторые переменные частными, например 'private (i1, k, vector_1, vector_2)', но это была просто отчаянная попытка, и она не сработала. –

+0

Беспорядок вокруг с графиком. Если ваши подсчеты цикла не скомпилированы, константы динамические или ориентированные могут работать лучше. –

ответ

3

Первый цикл цикла должен работать аналогично третьему.

С суммой небольшая проблема заключается в том, что массив sum [] индексируется с использованием первого индекса цикла и, следовательно, кажется, путает компилятор. Для облегчения работы машины вы можете попробовать:

double subsum=0.0; 
#pragma omp parallel for default(shared) reduction(+:subsum) 
for (i=0;i<(Nx*Ny);i++){ 
    subsum += vector_2[i]; 
} 
sum[i1-1] -= subsum; 

С четвертым вы, вероятно, можете использовать подобный трюк.

+0

Нужно ли, чтобы инициализация 'double subsum = 0.0' была выполнена после' #pragma ... 'и перед циклом for? –

+0

Извините за введенную синтаксическую ошибку, переменная, конечно, должна быть объявлена ​​до использования директивой omp. И установите значение 0 во время каждого внешнего цикла. – ssavec

Смежные вопросы