openmp 中是否有一种高效的方法来执行以下操作: 当使用 openmp 并行执行 do 循环时,调用两个或多个可以独立运行且与循环并行的子例程。
有什么建议吗? 谢谢。
ps:使用section和创建子流程太慢了。子例程调用 GPU 进行独立于循环计算(且在循环之外)的计算。在不创建/销毁子流程的情况下重叠它们将带来巨大的收益。
示例:
!$OMP PARALLEL DEFAULT(SHARED)
!$OMP DO
Do I = 1, N
... compute stuff in here
End Do
!$OMP END DO
!$OMP END PARALLEL
Call GPU_1
Call GPU_2
Call GPU_3
Call GPU_4
在执行循环时,必须运行对 GPU 的调用。正如我所指出的,在 SECTION 中创建和销毁线程太慢了。
编辑:谢谢您的建议。 do 循环计算量很大(没有子调用,只是计算),并且不了解如何插入四个 GPU 调用以与 do 循环并行运行。 我确实尝试了一些部分,其中一个部分包含 do 循环,并专门为 do 循环创建子进程,但这没有显示加速优势。
尚不清楚这些任务将如何实现这一目标。我可能没抓住重点。
建议:
!$OMP PARALLEL DEFAULT(SHARED)
!$OMP SINGLE
Call GPU_1
Call ...
!$OMP END SINGLE NOWAIT
!$OMP DO SCHEDULE(nonmonotic:dynamic)
Do I = 1, N
... compute stuff in here
End Do
!$OMP END DO
!$OMP END PARALLEL
一个线程开始执行 GPU 内容,并且由于
NOWAIT
子句,其他线程继续执行循环。即使执行 GPU 内容的线程需要更多时间,也需要 dynamic
调度来允许这些线程处理所有迭代。
或者,do 循环可以由
TASKLOOP
执行,它自然地使用可用线程处理所有迭代:
!$OMP PARALLEL DEFAULT(SHARED)
!$OMP SINGLE
Call GPU_1
Call ...
!$OMP END SINGLE NOWAIT
!$OMP SINGLE
!$OMP TASKLOOP
Do I = 1, N
... compute stuff in here
End Do
!$OMP END TASKLOOP
!$OMP END SINGLE
!$OMP END PARALLEL
在这两种情况下,一个线程在 GPU 调用期间可能大部分处于不活动状态。可以通过再启动一个线程来缓解这一问题,以便所有核心始终被占用:
nt = omp_get_max_threads() + 1
!$OMP PARALLEL DEFAULT(SHARED) NUM_THREADS(nt)
!$OMP SINGLE
Call GPU_1
Call ...
!$OMP END SINGLE NOWAIT
!$OMP DO SCHEDULE(nonmonotic:dynamic)
Do I = 1, N
... compute stuff in here
End Do
!$OMP END DO
!$OMP END PARALLEL