pragma omp for inside pragma omp master或single

时间:2013-01-17 17:43:21

标签: c++ openmp

我正坐在这里试图让孤儿工作,并通过减少#pragma omp parallel的调用来减少开销。 我正在尝试的是:

#pragma omp parallel default(none) shared(mat,mat2,f,max_iter,tol,N,conv) private(diff,k)
{
#pragma omp master // I'm not against using #pragma omp single or whatever will work
{
while(diff>tol) {
    do_work(mat,mat2,f,N);
    swap(mat,mat2);
    if( !(k%100) ) // Only test stop criteria every 100 iteration
         diff = conv[k] = do_more_work(mat,mat2);
    k++;
} // end while
} // end master
} // end parallel

do_work取决于前一次迭代,因此while循环必须按顺序运行。 但我希望能够并行运行'do_work',所以它看起来像是:

void do_work(double *mat, double *mat2, double *f, int N)
{
int i,j;
double scale = 1/4.0;
#pragma omp for schedule(runtime) // Just so I can test different settings without having to recompile
for(i=0;i<N;i++)
    for(j=0;j<N;j++)
         mat[i*N+j] = scale*(mat2[(i+1)*N+j]+mat2[(i-1)*N+j] + ... + f[i*N+j]);
} 

我希望这可以通过某种方式实现,我只是不确定如何。所以我能得到的任何帮助都非常感谢(如果你告诉我这是不可能的话)。顺便说一句,我正在使用open mp 3.0,gcc编译器和sun studio编译器。

1 个答案:

答案 0 :(得分:5)

原始代码中的外部并行区域仅包含一个序列段(#pragma omp master),这没有任何意义,并且有效地导致纯串行执行(无并行性)。由于do_work()取决于上一次迭代,但您希望并行运行它,因此必须使用同步。 openmp工具是(显式或隐式)同步障碍。

例如(类似于你的代码):

#pragma omp parallel
for(int j=0; diff>tol; ++j)    // must be the same condition for each thread!
#pragma omp for                // note: implicit synchronisation after for loop
  for(int i=0; i<N; ++i)
    work(j,i);

请注意,如果任何线程仍在处理当前j,则隐式同步可确保没有线程进入下一个j

替代

for(int j=0; diff>tol; ++j)
#pragma omp parallel for
  for(int i=0; i<N; ++i)
    work(j,i);

应该效率较低,因为它在每次迭代时创建一个新的线程团队,而不仅仅是同步。