gpt4 book ai didi

c++ - 减轻 openmp 并行延迟的措施

转载 作者:行者123 更新时间:2023-11-30 01:42:29 27 4
gpt4 key购买 nike

我从 Fortran 的角度写了这个问题,但这些问题并不仅限于 Fortran(因此有 c++ 标签)。

我有两个问题。我读到在 OpenMP 并行循环的开始和停止时存在延迟 here .我的问题是:

Q1) 有哪些实用措施可以缓解 openMP 延迟?

Q2)以下哪种方法效果更好?

方法一

 x = 1.0; y = 2.0
!$OMP PARALLEL DO
do k=1,Nz; do j=1,Ny; do i=1,Nx
x(i,j,k) = x(i,j,k)+y(i,j,k)
enddo; enddo; enddo
!$OMP END PARALLEL DO

!$OMP PARALLEL DO
do k=1,Nz; do j=1,Ny; do i=1,Nx
x(i,j,k) = x(i,j,k)*y(i,j,k)
enddo; enddo; enddo
!$OMP END PARALLEL DO
! (x should = 6.0 at this point)

方法二

 x = 1.0; y = 2.0
!$OMP PARALLEL DO
do k=1,Nz; do j=1,Ny; do i=1,Nx
x(i,j,k) = x(i,j,k)+y(i,j,k)
x(i,j,k) = x(i,j,k)*y(i,j,k)
enddo; enddo; enddo
!$OMP END PARALLEL DO
! (x should = 6.0 at this point)

方法三

1) 创建一个包含过程数组的对象

2)调用数组过程如下

 x = 1.0; y = 2.0
!$OMP PARALLEL DO
do k=1,Nz; do j=1,Ny; do i=1,Nx
do t=1,procedure_array%N
call procedure_array%single_procedure(t)%P(x(i,j,k),y(i,j,k))
enddo
enddo; enddo; enddo
!$OMP END PARALLEL DO
! (x should = 6.0 at this point)

假设 procedure_array%N = 2

 procedure_array%single_procedure(1)
procedure_array%single_procedure(2)

指向子例程add (x=x+y) 和multiply (x=x*y ) 分别。

3)清理(解除分配)

评论

首先,很明显方法 2 优于方法 1,因此我对方法 2 与方法 3 的比较很感兴趣。其次,我知道“试试看”是一个有效的答案,但是我想知道是否有方法 3 在实践(或行业)中使用的具体示例,或者方法 3 与方法 2 相比不如方法 2 的概念原因(例如,由于许多过程调用而导致的开销)。最后,如果可以采取某种特殊措施(例如,通过专门指定特定线程)使方法 2 和 3 几乎等效,它们是什么?

感谢您的帮助!

更新

根据评论,我做了以下更正。

  • 修改了操作(谢谢@Gilles)
  • 删除了与 MPI 相关的所有内容,这确实是一个 openmp 问题(谢谢 @Vladimir)
  • 在下面添加了说明(我自己的实现)

感谢@innoSPG,关于缓存内存(和缓存故障)的回答非常有用!

澄清

最后,从评论中,我意识到这个问题的重点实际上是关于过程调用的,与 openmp 并行化没有严格的关系。也就是说,我保留了 openmp 语句,因为那是我更复杂的应用程序中发生的事情,我想尽可能多地保留它。从@Chaosit 的评论看来,过程调用将需要开销,从而减慢方法 3。有什么办法可以解决这个问题吗?

另外,如果我错了,请纠正我,但我相信方法 2 中的两个操作将按书面顺序执行,从而产生正确的最终 x 值。

最佳答案

我的理解是您正在寻找的差异(方法 2 和方法 3)不依赖于并行化。

让我解释一下:

由于方法 2 中不存在的过程调用,方法 3 可能会产生其他开销。我这么说可能是因为我不熟悉过程指针,但是,我的猜测是编译器的优化不会内联如果您使用过程指针,则过程调用。

由于过程调用而产生的开销完全独立于并行化。您仍将在顺序代码中拥有它。它不是并行化延迟的一部分。

现在,我冒着风险回到你不喜欢的选项:试试看。我冒这个风险是因为我相信你所展示的只是你问题的一个例证,你的实际情况更复杂。当您处理复杂的情况时,您可能会惊讶于方法 1 和方法 2 之间的结论不再有效。它可能在很大程度上取决于您手头的问题。一种情况的结论不适用于另一种情况。像现在的编译器一样聪明,他们不会捕获一切。在计算机科学中,缓存内存的概念有时并没有被很好地理解,但我不会详细介绍。您可能会遇到这样一种情况,方法 1 的每个单个循环(数据和/或代码)都保存在缓存中,而情况 2 的组合循环不保存在缓存中。简单的说明是方法 2 在内循环中遇到缓存故障而方法 1 没有的情况。在这种情况下,您会发现对于大循环边界,方法 1 远远优于方法 2。

这就是尝试看看成为标准的地方,这也是现实生活中大多数情况下发生的情况。

关于c++ - 减轻 openmp 并行延迟的措施,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39579057/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com