我在一个月前开始编程,最近我一直在尝试用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。
对这个特殊问题的任何帮助,或者我的编码风格一般都会非常感谢!我一直在敲我的键盘一段时间。
答案 0 :(得分:1)
我弄明白了这个问题。我还链接到intel库libguide.so,它似乎与gnu的OpenMP实现不兼容。我只是将这个链接器选项更改为链接到libiomp5.so(下载库后),这与-fopenmp兼容,现在我有一个超快的程序!
感谢您的支持!
答案 1 :(得分:0)
如果不分析完整的代码,很难看出出了什么问题。但有一些提示:
减速可以来自
for循环计数器i应该在循环内声明,因此OpenMP可以根据可用线程的数量拆分此循环。另一种可能性是声明它
#pragma parallel for private(i)
另一个问题似乎来自竞争条件,因此所有线程都会打印第1号线。