openMP嵌套并行for循环vs内部并行for

Sco*_*gan 23 c++ parallel-processing openmp

如果我像这样使用嵌套并行for循环:

#pragma omp parallel for schedule(dynamic,1)
for (int x = 0; x < x_max; ++x) {
    #pragma omp parallel for schedule(dynamic,1)
    for (int y = 0; y < y_max; ++y) { 
    //parallelize this code here
   }
//IMPORTANT: no code in here
}
Run Code Online (Sandbox Code Playgroud)

这相当于:

for (int x = 0; x < x_max; ++x) {
    #pragma omp parallel for schedule(dynamic,1)
    for (int y = 0; y < y_max; ++y) { 
    //parallelize this code here
   }
//IMPORTANT: no code in here
}
Run Code Online (Sandbox Code Playgroud)

除了创建新任务之外,做外部并行吗?

Hri*_*iev 39

如果您的编译器支持OpenMP 3.0,则可以使用以下collapse子句:

#pragma omp parallel for schedule(dynamic,1) collapse(2)
for (int x = 0; x < x_max; ++x) {
    for (int y = 0; y < y_max; ++y) { 
    //parallelize this code here
    }
//IMPORTANT: no code in here
}
Run Code Online (Sandbox Code Playgroud)

如果没有(例如只支持OpenMP 2.5),有一个简单的解决方法:

#pragma omp parallel for schedule(dynamic,1)
for (int xy = 0; xy < x_max*y_max; ++xy) {
    int x = xy / y_max;
    int y = xy % y_max;
    //parallelize this code here
}
Run Code Online (Sandbox Code Playgroud)

您可以启用嵌套并行性,omp_set_nested(1);并且您的嵌套omp parallel for代码将起作用,但这可能不是最好的主意.

顺便问一下,为什么动态调度呢?是否在非恒定时间内评估每个循环迭代?

  • @ars,两个变量都在并行区域内声明,因此预定为"private".此外,因为外部作用域中不存在变量,所以添加`private(x,y)`将导致错误. (2认同)

Wal*_*ter 11

没有.

第一个#pragma omp parallel将创建一个并行线程团队,第二个将尝试为每个原始线程创建另一个团队,即团队团队.但是,在几乎所有现有实现中,第二个团队只有一个线程:第二个并行区域基本上没有使用.因此,您的代码更像是等同于

#pragma omp parallel for schedule(dynamic,1)
for (int x = 0; x < x_max; ++x) {
    // only one x per thread
    for (int y = 0; y < y_max; ++y) { 
        // code here: each thread loops all y
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你不想这样,但只是内部循环,你可以这样做:

#pragma omp parallel
for (int x = 0; x < x_max; ++x) {
    // each thread loops over all x
#pragma omp for schedule(dynamic,1)
    for (int y = 0; y < y_max; ++y) { 
        // code here, only one y per thread
    }
}
Run Code Online (Sandbox Code Playgroud)