带有 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”无效