【问题标题】:OpenMP taskloop: synchronization between two consecutive taskloop constructsOpenMP 任务循环:两个连续任务循环结构之间的同步
【发布时间】:2021-06-01 22:17:42
【问题描述】:

两个taskloop 构造之间的同步是如何完成的?具体来说,在下面的伪代码中,如果可用线程数多于第一个循环的任务数,我相信这些空闲线程会在单个构造末尾的隐式屏障处旋转。现在是否允许这些空闲线程同时开始执行第二个循环,从而以这种方式并行化事物是不安全的(由于对数组 A 的相互依赖)?

!$omp parallel
!$omp single

!$omp taskloop num_tasks(10)
DO i=1, 10
    A(i) = foo()
END DO
!$omp end taskloop

!do other stuff

!$omp taskloop
DO j=1, 10
    B(j) = A(j)
END DO
!$omp end taskloop

!$omp end single
!$omp end parallel

我一直没能从 API 规范中找到明确的答案:https://www.openmp.org/spec-html/5.0/openmpsu47.html#x71-2080002.10.2

【问题讨论】:

    标签: parallel-processing synchronization task openmp shared-memory


    【解决方案1】:

    taskloop 构造默认有一个隐含的taskgroup 围绕它。考虑到这一点,您的代码会发生什么,single 构造会从并行团队的可用线程中挑选任何一个线程(我将其称为生产者线程)。然后其他 n-1 个线程被直接发送到 single 构造的屏障并等待工作到达(任务)。

    现在有了taskgroup,生产者线程开始创建循环任务,然后在taskloop 构造结束时等待所有创建的任务完成:

    !$omp parallel
    !$omp single
    
    !$omp taskloop num_tasks(10)
    DO i=1, 10
        A(i) = foo()
    END DO
    !$omp end taskloop  ! producer waits here for all loop tasks to finish
    
    !do other stuff
    
    !$omp taskloop
    DO j=1, 10
        B(j) = A(j)
    END DO
    !$omp end taskloop ! producer waits here for all loop tasks to finish
    
    !$omp end single
    !$omp end parallel
    

    因此,如果您的并行度(= 第一个 taskloop 创建的任务数)少于屏障中的 n-1 个工作线程,那么其中一些线程将空闲。

    如果你想要更多的重叠并且如果“其他东西”独立于第一个taskloop,那么你可以这样做:

    !$omp parallel
    !$omp single
    
    
    !$omp taskgroup
    !$omp taskloop num_tasks(10) nogroup
    DO i=1, 10
        A(i) = foo()
    END DO
    !$omp end taskloop  ! producer will not wait for the loop tasks to complete
    
    !do other stuff
    
    !$omp end taskgroup ! wait for the loop tasks (and their descendant tasks)
    
    !$omp taskloop
    DO j=1, 10
        B(j) = A(j)
    END DO
    !$omp end taskloop
    
    !$omp end single
    !$omp end parallel
    

    唉,从 5.1 版开始的 OpenMP API 不支持 taskloop 构造的任务依赖性,因此您无法轻松描述第一个 taskloop 和第二个 taskloop 的循环迭代之间的依赖性。 OpenMP 语言委员会目前正在着手解决这个问题,但我认为这不是针对 OpenMP API 5.2 版实现的,而是针对 6.0 版实现的。

    PS(编辑):对于第二个 taskloop,因为它正好在 single 构造结束之前,因此就在障碍之前,您也可以轻松地在那里添加 nogroup 以避免额外的一点等待生产者线程。

    【讨论】:

    • 非常感谢!我没有足够的“声誉”来支持答案,但它完整而清晰地回答了我的问题。再次感谢:)
    • @Soheil 你现在拥有它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-30
    • 2014-04-19
    • 2015-12-22
    • 2011-05-28
    • 1970-01-01
    相关资源
    最近更新 更多