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

OpenMP "parallel for" is weird in specific program

本文关键字:程序 parallel for OpenMP      更新时间:2023-10-16

我大约一个月前开始编程,最近我一直在尝试用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 %dn", 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'没有在我的程序的main函数的作用域中声明。

当编译我的程序时,我正在链接到其他库,包括添加-pthreads, -lguide和-ltiff,除了-fopenmp,当编译gcc4.4时。

任何帮助与这个特定的问题,或我的编码风格一般将非常感激!我的头一直在敲击键盘。

我找到了问题所在。我还链接到英特尔图书馆的图书馆指南。因此,它似乎是已知的与gnu的OpenMP实现不兼容。我只是将这个链接器选项改为链接到libiomp5。所以(下载库后),这是兼容-fopenmp,现在我有一个惊人的快程序!!

感谢您的支持!

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

减速可能来自

  • 访问共享变量时同步锁
  • 根据numThreads多次执行相同的工作,
  • 向所有线程复制大量数据。

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

#pragma parallel for private(i)

另一个问题似乎来自于竞争条件,所以所有线程都打印线程号1