在 OpenMP 中并行运行 DO 循环和独立子例程调用

问题描述 投票:0回答:1

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 循环创建子进程,但这没有显示加速优势。

尚不清楚这些任务将如何实现这一目标。我可能没抓住重点。

fortran openmp
1个回答
0
投票

建议:

!$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
© www.soinside.com 2019 - 2024. All rights reserved.