OpenMP "параллель для" странный в конкретной программе - PullRequest
0 голосов
/ 08 июля 2011

Я начал программировать около месяца назад, и недавно я пытался изучить многоядерную разработку с OpenMP в программах на C ++.Я не могу заставить OpenMP правильно работать для меня в большой программе, которую я написал.Я хочу выполнить следующий цикл параллельно.

for(int iAngle=0; iAngle<int(nAngles); iAngle++){
    for(int k=0; k<int(nRadSamples); k++){
        int x=coordX[k][iAngle];
        int y=coordY[k][iAngle];
        for(int i=yMin; i<int(yMax); i++){
            int iy=i+y;
            for(int j=xMin; j<int(xMax); j++){
                response[iAngle][i][j] += inputSlice[iy][j+x];
            }

        }
    }
}

координирование, координата, ответ и inputSlice равны

vector<vector<int> >
vector<vector<int> >
vector<vector<vector<float> > > 
vector<vector<float> >

соответственно.При добавлении

#pragma omp parallel for

в качестве строки над этим циклом происходит значительное замедление (время выполнения 50 секунд замедляется до 75 секунд).

Я не думаю, что мои проблемы связаны с доступом к общим переменным response и inputSlice, потому что даже базовый код OpenMP странным образом выполняется в этой конкретной программе.Например, базовая программа

#include <stdio.h>
#include <omp.h>

int main() {

//////////////////////
#pragma omp parallel for
for(int i = 0; i<2; i++){
    int thread = omp_get_thread_num() + 1 ;
    int numThreads = omp_get_num_threads();
    printf("Thread %d of %d printing %d\n", thread, numThreads,i);
}
 ////////////////////


return 0;
}

выводит

Thread 2 of 8 printing 1
Thread 1 of 8 printing 0

, но когда я копирую и вставляю код внутри границ ///////////////в функцию

int main(int argc, char* argv[])

моей большой программы она выводит

Thread 1 of 1 printing 0
Thread 1 of 1 printing 1
Thread 1 of 1 printing 0
Thread 1 of 1 printing 1
Thread 1 of 1 printing 0
Thread 1 of 1 printing 1
Thread 1 of 1 printing 0
Thread 1 of 1 printing 1
Thread 1 of 1 printing 0
Thread 1 of 1 printing 1
Thread 1 of 1 printing 0
Thread 1 of 1 printing 1
Thread 1 of 1 printing 0
Thread 1 of 1 printing 1
Thread 1 of 1 printing 0
Thread 1 of 1 printing 1   

Как будто каждый поток выполняет весь цикл for отдельно, не видя друг друга, что по понятным причинам замедлит мойвремя выполнения программы.'i' не было объявлено в области действия основной функции моей программы.

При компиляции моей программы я ссылаюсь на другие библиотеки, включая добавление -pthreads, -lguide и -ltiff в дополнение кfopenmp, при компиляции с gcc4.4.

Любая помощь с этой конкретной проблемой, или мой стиль кодирования в целом, будет принята с благодарностью!Я уже некоторое время стучу головой о клавиатуру.

Ответы [ 2 ]

1 голос
/ 08 июля 2011

Я разобрался в проблеме.Я также связывался с библиотекой intel libguide.so, которая, по-видимому, несовместима с реализацией OpenMP в GNU.Я просто изменил этот параметр компоновщика для ссылки на libiomp5.so (после загрузки библиотеки), который совместим с -fopenmp, и теперь у меня есть потрясающая быстрая программа !!

Спасибо за поддержку!

0 голосов
/ 08 июля 2011

Трудно увидеть, что происходит, не анализируя полный код.Но несколько советов:

Замедление может происходить из-за

  • синхронизации блокировок при доступе к общим переменным,
  • , выполняющих одну и ту же работу несколько раз в соответствии с numThreads,
  • копирование большого количества данных во все потоки.

Счетчик цикла i должен быть объявлен внутри цикла, чтобы OpenMP мог разделить этот цикл в соответствии с количеством доступных потоков.Другая возможность состоит в том, чтобы объявить это

#pragma parallel for private(i)

Другая проблема, похоже, связана с состоянием гонки, поэтому все нити печатают нить № 1.

...