C++ 用于循环的openMP嵌套并行与用于循环的内部并行

C++ 用于循环的openMP嵌套并行与用于循环的内部并行,c++,parallel-processing,openmp,C++,Parallel Processing,Openmp,如果我对这样的循环使用嵌套并行: #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 i

如果我对这样的循环使用嵌套并行:

#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
}
#计划的pragma omp并行(动态,1)
对于(int x=0;x
这是否等于:

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
}
for(int x=0;x
除创建新任务外,外部并行是否用于执行任何操作?

第一个
#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
    }
}
#计划的pragma omp并行(动态,1)
对于(int x=0;x
如果您不希望这样做,但仅并行内部循环,则可以执行以下操作:

#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
    }
}
#pragma omp并行
对于(int x=0;x
如果您的编译器支持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
}
计划(动态,1)折叠(2)的pragma omp并行 对于(int x=0;x 如果不支持(例如,仅支持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
}
#计划的pragma omp并行(动态,1)
对于(int xy=0;xy
您可以使用
omp\u set\u nested(1)启用嵌套并行性
和嵌套的
omp并行for
代码可以工作,但这可能不是最好的主意


顺便问一下,为什么要动态调度?每个循环迭代都是在非恒定时间内计算的吗?

我明白了,我考虑过这一点,但这似乎太违反直觉了。因此,如果我想在所有迭代中都使用“并行for”,我应该在内部循环中使用“并行for”?@Bunnit我不知道你想要什么,但我在我的答案中添加了它。@Bunnit我认为我的第二个解决方案至少应该达到与Hrito Iliev的第二个解决方案相同的速度,但在概念上要清楚得多。如果内部循环中的工作负载在
y
的不同值之间没有太大差异,那么第一个解决方案甚至更可取。在所有情况下,您都可以并行双循环,即每对线程(
x
y
)只被整个线程组调用一次。我使用的是VS2008,所以我认为我不能使用collapse,我考虑过使用您提到的第二种方法,但希望不必对代码进行重大更改。它是用于光线跟踪器的,因此某些主光线可能比其他光线占用的时间长10倍。显然,即使VS2010也只支持OpenMP 2.0。请注意,整数除法和模运算的成本相对较高。如果循环体几乎不起作用,则开销可能很大。在上一个示例中,
x
y
是否应该标记为
private
?@ars,这两个变量都在并行区域内声明,因此预先确定为
private
。此外,由于外部范围中不存在变量,因此添加
private(x,y)
将导致错误。