parallel-processing - OpenMP 任务循环:两个连续任务循环结构之间的同步
问题描述
两个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
解决方案
默认情况下,该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
因此,如果您的并行度(= first 创建的任务数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 构造的任务依赖性,因此您无法轻松描述 firsttaskloop
和 second的循环迭代之间的依赖性taskloop
。OpenMP 语言委员会目前正在研究此问题,但我认为这不是针对 OpenMP API 5.2 版实现的,而是针对 6.0 版实现的。
PS(编辑):对于第二个taskloop
,因为它就在single
构造结束之前,因此就在障碍之前,您也可以轻松地添加nogroup
那里以避免额外的等待生产者线程。
推荐阅读
- python - 我应该如何以及在哪里添加检查条件以查看用户在 Django 中是否超过 18 岁?
- django - 页面匹配查询不存在 - Django
- cmd - 除非指定输出文件,否则 VBScript 的 Shell 命令不会执行
- wordpress - 如何在 WordPress 中正确设置永久链接
- javascript - 播放暂停按钮切换按钮
- docker - 在 Rancher/Kubernates (RKE) 中为 internal_address 打开端口?
- vb.net - Accord.net 的 Cobyla 优化约束
- github - 如何在 GIthub 上创建新分支而不在本地签出和推送?
- php - 访问 PHP 类方法
- java - 如何使用循环将字符串变成只有小写字母(没有空格、撇号)的新字符串