没有for循环的OpenMP不等负载
Posted
技术标签:
【中文标题】没有for循环的OpenMP不等负载【英文标题】:OpenMP unequal load without for loop 【发布时间】:2018-05-04 03:48:44 【问题描述】:我有一个如下所示的 OpenMP 代码
while(counter < MAX)
#pragma omp parallel reduction(+:counter)
// do monte carlo stuff
// if a certain condition is met, counter is incremented
因此,只要计数器低于某个值,并行部分就会由可用线程执行。根据场景的不同(我在这里做 MC 的东西,所以它是随机的),计算可能比其他计算需要更长的时间,因此这里的工作人员之间存在不平衡,由于并行结束时的隐式障碍而变得明显部分。
似乎#pragma omp parallel for 可能有办法规避这个问题(即 nowait 指令/动态调度),但我不能使用它,因为我不知道 for 循环的上迭代次数。
任何想法/设计模式如何处理这种情况?
最好的问候!
【问题讨论】:
【参考方案1】:在单个并行部分中运行所有内容并以原子方式访问counter
。
int counter = 0;
#pragma omp parallel
while(1)
int local_counter;
#pragma omp atomic read
local_counter = counter;
if (local_counter >= MAX)
break;
// do monte carlo stuff
// if a certain condition is met, counter is incremented
if (certain_condition)
#pragma omp atomic update
counter++;
由于原子访问,您不能直接在 while 条件中检查。
请注意,此代码会过冲,即counter > MAX
可能在并行部分之后。请记住,counter
由多个线程共享和读取/更新。
【讨论】:
谢谢您-我会立即尝试。我想减少条款就不再需要了吧?我的意思是,使用原子操作,代码已经在处理这个问题了,对吧? 是的,在这种情况下,减少条款是错误的 - 抱歉,很好。 Atomics 会注意 1)counter
更新的总次数是正确的,并且 2) 你总是读取一个有效的值。
一个更普遍的问题:处理线程必须以只读方式访问复杂结构(例如,动态分配数组的成员)的情况的最佳方法是什么?我目前的方法只是简单地共享,我没有注意到任何问题。但是,我想知道:为什么我需要 #pragma atomic 读取呢?那么 firstprivate 是否更适合该结构?
如果只有来自所有线程的读访问,它可以并且应该在没有原子访问的情况下共享。我的示例中的读取访问是必要的,因为其他线程确实同时写入。注意:声明结构 firstprivate
不会影响指针/动态分配的内存。
谢谢,这真的很有用。我想知道为什么使用 openmp 很难找到一个好的 while 循环示例。以上是关于没有for循环的OpenMP不等负载的主要内容,如果未能解决你的问题,请参考以下文章