OpenMP“parallel for”在特定程序中很奇怪

时间:2011-07-07 22:48:01

标签: c++ parallel-processing openmp

我在一个月前开始编程,最近我一直在尝试用C ++程序中的OpenMP学习多核开发。在我编写的大型程序中,我无法让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];
            }

        }
    }
}

coordX,coordY,response和inputSlice是

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

分别。添加

后会有相当大的减速(50秒运行时间减慢到75秒运行时间)
#pragma omp parallel for

作为此循环上方的行。

我认为我的问题不是来自访问响应和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'尚未在我的程序的主要功能范围内声明。

我在编译程序时链接到其他库,包括在使用gcc4.4进行编译时添加-pthreads,-lguide和-ltiff,以及-fopenmp。

对这个特殊问题的任何帮助,或者我的编码风格一般都会非常感谢!我一直在敲我的键盘一段时间。

2 个答案:

答案 0 :(得分:1)

我弄明白了这个问题。我还链接到intel库libguide.so,它似乎与gnu的OpenMP实现不兼容。我只是将这个链接器选项更改为链接到libiomp5.so(下载库后),这与-fopenmp兼容,现在我有一个超快的程序!

感谢您的支持!

答案 1 :(得分:0)

如果不分析完整的代码,很难看出出了什么问题。但有一些提示:

减速可以来自

  • 访问共享变量时同步锁,
  • 根据numThreads多次做同样的工作,
  • 将大量数据复制到所有线程。

for循环计数器i应该在循环内声明,因此OpenMP可以根据可用线程的数量拆分此循环。另一种可能性是声明它

#pragma parallel for private(i)

另一个问题似乎来自竞争条件,因此所有线程都会打印第1号线。