我正在使用FORTRAN版本的OPENMP查看程序。我遇到了一个相当奇怪的结构。制作"做"循环并行使用以下构造
count = 0
!$OMP PARALLEL
do
if (count > N ) exit
!$OMP CRITICAL
count = count + 1
!$OMP END CRITICAL
call WORK ! do some work here
end do
!$OMP END PARALLEL
我不确定,上面的代码是否真的使do循环并行。我知道这样做的标准方法是使用以下工作共享构造。
!$OMP PARALLEL
!$OMP DO
do count = 1,N
call WORK ! do some work here
end do
!$OMP ENDDO
!$OMP END PARALLEL
我已经测试了两种可能性,通过实现标准的工作共享结构,并在使用时观察了一些加速。我可以想象$OMP CRITICAL
结构可能会起到瓶颈的作用并导致一些减速。我认为使用非标准的工作共享方法,如果线程以不同的速度执行,可能会有所帮助。但是,我不确定我的想法有多准确。
提前谢谢
Alex
答案 0 :(得分:2)
您的想法是正确的,原始代码的作用相当于:
!$OMP PARALLEL DO SCHEDULE(DYNAMIC)
do count = 0,N
call WORK ! do some work here
end do
!$OMP END PARALLEL DO
基本上它以非常笨拙和低效的方式实现动态循环调度。如果call WORK
总是花费相同的时间,即没有导致工作不平衡的条件,则SCHEDULE(DYNAMIC)
子句可以替换为SCHEDULE(STATIC)
以提高性能。
答案 1 :(得分:1)
如果未使用!$omp do
,则每个线程都与其他线程相同。 omp do
指令用于划分线程之间循环索引的空间。线程不做同样的工作,但运行编号循环的不同迭代。在你的情况下,这里没有索引,所以没有什么可分,所有线程都将运行相同的代码。
如果只是更新计数omp atomic
可以使用,但如果WORK
需要足够长的时间来计算它,则可以忽略不计。我担心原始代码中的条件读数也有问题。
count = 0
!$OMP PARALLEL
do
!$OMP ATOMIC READ
count2 = count
if (count2 > N ) exit
!$OMP ATOMIC UPDATE
count = count + 1
call WORK ! do some work here
end do
!$OMP END PARALLEL
这里的意图是呼叫WORK
N次并且并行进行单独呼叫。可能有更优雅的方法来实现这一目标。