如何使用OpenMP在顺序循环中嵌套并行循环

use*_*051 6 c parallel-processing multithreading loops openmp

我目前正在使用OpenMP进行矩阵计算.我的代码中有几个循环,而是调用每个循环#pragma omp parallel for [...](创建所有线程并在之后销毁它们)我想在开头创建所有这些,并且在程序结束时删除它们以避免开销.我想要的东西:

#pragma omp parallel
{
    #pragma omp for[...]
    for(...)

    #pragma omp for[...]
    for(...)
}
Run Code Online (Sandbox Code Playgroud)

问题是我有一些部分必须只由一个线程执行,但是在一个循环中,它包含那些必须并行执行的循环......这就是它的样子:

//have to be execute by only one thread
int a=0,b=0,c=0;
for(a ; a<5 ; a++)
{

    //some stuff

    //loops which have to be parallelize
    #pragma omp parallel for private(b,c) schedule(static) collapse(2)
    for (b=0 ; b<8 ; b++);
        for(c=0 ; c<10 ; c++)
        {
            //some other stuff
        }

    //end of the parallel zone
    //stuff to be execute by only one thread

}
Run Code Online (Sandbox Code Playgroud)

(在我的例子中,循环边界非常小.在我的程序中,迭代次数可以持续到20.000 ......)我的第一个想法之一是做这样的事情:

//have to be execute by only one thread
#pragma omp parallel    //creating all the threads at the beginning
{
    #pragma omp master //or single
    {        
        int a=0,b=0,c=0;
        for(a ; a<5 ; a++)
        {

            //some stuff

            //loops which have to be parallelize
            #pragma omp for private(b,c) schedule(static) collapse(2)
            for (b=0 ; b<8 ; b++);
                for(c=0 ; c<10 ; c++)
                {
                    //some other stuff
                }

            //end of the parallel zone
            //stuff to be execute by only one thread

        }
    }
} //deleting all the threads
Run Code Online (Sandbox Code Playgroud)

它没有编译,我从gcc得到这个错误:"工作共享区域可能不会紧密嵌套在工作共享,关键,有序,主要或显式任务区域内".

我知道它肯定来自"错误"的嵌套,但我无法理解为什么它不起作用.我需要在并行区域之前添加屏障吗?我有点迷茫,不知道如何解决它.

预先感谢您的帮助.干杯.

Hig*_*ark 3

在代码概述的最后一个部分中,您声明了一个并行区域,在该区域内使用主指令来确保只有主线程执行块,并在主块内尝试跨所有线程并行化循环。您声称知道编译器错误是由不正确的嵌套引起的,但想知道为什么它不起作用。

它不起作用,因为将工作分配给只有一个线程执行的代码区域内的多个线程没有任何意义。

您的第一个伪代码更好,但您可能想像这样扩展它:

#pragma omp parallel
{
    #pragma omp for[...]
    for(...)

    #pragma omp single
    { ... }

    #pragma omp for[...]
    for(...)
}
Run Code Online (Sandbox Code Playgroud)

single指令确保它包含的代码块仅由一个线程执行。与该master指令不同的是,该指令single还暗示了退出时的障碍;您可以使用该nowait子句更改此行为。