【问题标题】:OpenMP parallel loop without using $OMP DO不使用 $OMP DO 的 OpenMP 并行循环
【发布时间】:2014-06-06 22:05:26
【问题描述】:

我正在研究一个使用 FORTRAN 版本的 OPENMP 的程序。在那里我遇到了一个相当奇怪的结构。为了使“do”循环并行,使用了以下构造

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 构造可能会充当瓶颈并导致一些减速。我认为,如果线程以不同的速度执行,则使用非标准方法进行工作共享可能是有益的。但是,我不确定我的想法有多准确。

提前谢谢你

亚历克斯

【问题讨论】:

    标签: parallel-processing fortran openmp


    【解决方案1】:

    您的想法是正确的,原始代码的作用相当于:

    !$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) 以提高性能。

    【讨论】:

    • 感谢您的回复。很高兴我的卑微假设得到证实。我怀疑这会变成软肥皂。
    【解决方案2】:

    如果不使用!$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 次,并并行进行个别调用。可能有更优雅的方法来实现这一点。

    【讨论】:

    • 您好,感谢您的回复。事实证明,我最初的假设确实是正确的。
    猜你喜欢
    • 1970-01-01
    • 2022-11-29
    • 1970-01-01
    • 2013-03-04
    • 1970-01-01
    • 2015-11-01
    • 2013-12-08
    • 1970-01-01
    相关资源
    最近更新 更多