带有 pragma omp 并行的嵌套循环,混乱起来

Posted

技术标签:

【中文标题】带有 pragma omp 并行的嵌套循环,混乱起来【英文标题】:nested loops with pragma omp parallel for, jumbling up 【发布时间】:2017-04-14 12:02:35 【问题描述】:

我正在尝试并行化代码以在脉冲神经元网络上运行一些模拟。这涉及一个双循环,我在主循环之外放置了一条语句“#pragma omp parallel for”。代码如下:

int main(void)

    int i,j,count[200];

    #pragma omp parallel for
    for(i=0;i<200;i++)
        count[i] = 0;
        for (j=0;j<200;j++)
            if (j!=i)
                count[i]++;
                printf("i: %d j: %d count[i]:%d, count[i]-j:%d\n",i,j,count[i], count[i]-j);
            
        

    

    return 0;

查看结果,count[i] 的某些值超过了 200,即使循环仅从 1 变为 200。count[i]-j 可以是 0,1 或 -1,但值差异很大,即使每个线程都可以处理 i 的一个值,并且 count 数组仅取决于 i 的当前值。如何重写代码以便安全地增加计数?

【问题讨论】:

最终值是多少?您可以在此之后添加一个循环来打印所有值吗? #pragma omp parallel 放在第二个循环之前。 @purplepsycho 这是错误的,会在count[i] 上创建竞争条件。 【参考方案1】:

您必须将j 声明为私有。您可以通过以下方式明确执行此操作:

#pragma omp parallel for private(j)

i 隐含 private 是工作共享循环的循环变量。 count 是隐式共享,因为它是在循环之外定义的。这两个在这里都是可取的。

但是,我强烈建议始终尽可能在本地声明变量,尤其是在使用 OpenMP 时。这样,隐式 private/shared 几乎总是正确的,它避免了许多微妙的未定义值读取。这通常是一个好习惯

int count[200];

#pragma omp parallel for
for(int i=0;i<200;i++)
    count[i] = 0;
    for (int j=0;j<200;j++)

顺便说一句:count[i]-j 的打印输出可以显示完全任意的值。它访问可能由其他线程同时写入的数据。

【讨论】:

以上是关于带有 pragma omp 并行的嵌套循环,混乱起来的主要内容,如果未能解决你的问题,请参考以下文章

在另一个并行循环中调用函数时,函数中的“pragma omp parallel for”无效

了解#pragma omp 并行

嵌套并行 omp v. 2.0 性能

如何优化并行嵌套循环?

在 OpenMP 中,我们如何并行运行多个代码块,其中每个代码块包含 omp single 和 omp for 循环?

OpenMP #pragma omp for v/s #pragma omp parallel for 之间的区别?