减少openmp并行延迟的措施
Measures to mitigate openmp parallel latency
我是从Fortran的角度来写这个问题的,但这些问题并不局限于Fortran(因此有c++标签)。
我有两个问题。我读到在OpenMP并行循环的开始和结束处存在延迟。我的问题是:Q1)有哪些实际措施可以减少openMP延迟?
Q2)以下哪种方法性能更好?
方法1
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)
方法2
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)
方法3 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
)。
首先,很明显方法2优于方法1,所以我对方法2和方法3的比较很感兴趣。其次,我知道"试一试看看"是一个有效的答案,但我想知道是否有具体的例子说明方法3在实践中(或工业中)被使用,或者为什么方法3比方法2差的概念原因(例如,由于许多过程调用造成的开销)。最后,如果可以采取某种特殊的措施(例如,通过特别指定特定的线程)使方法2和方法3实际上相等,那么它们是什么?
谢谢你的帮助!
根据评论,我做了以下更正。
- 修改了操作(谢谢,@Gilles)
- 删除了所有与MPI相关的内容,这真的是一个开放的mp问题(谢谢你,@Vladimir)
- 在下面添加了澄清(我自己意识到)
谢谢你,@innoSPG,关于你关于缓存内存(和缓存故障)的答案,这是非常有益的信息!
最后,从评论中,我意识到这个问题的重点实际上是关于过程调用,而不是严格地与openmp并行化相关。也就是说,我留下了openmp语句,因为这是在我的更复杂的应用程序中发生的事情,我希望尽可能地保留它。从@Chaosit的评论看来,过程调用将需要开销,减慢方法3。有什么办法可以绕过这个吗?
如果我错了,请纠正我,但我相信方法2中的两个操作将按照书面顺序执行,从而产生正确的最终x
值。
我的理解是,您正在寻找的差异(方法2和方法3)并不取决于并行化。
让我解释一下:
方法3可能会由于方法2中不存在的过程调用而产生另一个开销。我说可能是因为我不熟悉过程指针,但是,我的猜测是,如果您使用过程指针,编译器的优化将不会内联过程调用。
过程调用的开销与并行化完全无关。您仍然会在顺序代码中拥有它。它不是并行化延迟的一部分。
现在,我要冒险回到你不喜欢的选项:试着看看。我之所以冒这个险,是因为我相信你所展示的只是你的问题的一个例证,你的实际情况要复杂得多。当你遇到复杂的情况时,你可能会惊讶地发现方法1和方法2之间的结论不再有效。这很大程度上取决于你手头的问题。一种情况下的结论不适用于另一种情况。尽管现在的编译器很聪明,但它们不会捕获所有内容。在计算机科学中,有一个缓存内存的概念有时不是很好理解,但我不会详细介绍。可以有这样一种情况,方法1的每个单循环(数据和/或代码)保存在缓存中,而情况2的组合循环不保存在缓存中。最简单的例子是方法2在内部循环中遇到缓存错误,而方法1没有。在这种情况下,您将看到对于大循环边界,方法1远远优于方法2。
这就是Try and see
成为标准的地方,这就是现实生活中大多数情况下发生的情况。
- OpenMP阵列性能较差
- 如何仅为一个函数添加延迟
- OpenMP卸载说'fatal error: could not find accel/nvptx-none/mkoffload'
- 使用 GCC 卸载的 OpenMP 卸载失败,并出现"Ptx assembly aborted due to errors"
- OpenMP:并行更新数组总是需要减少数组吗
- 以在Qt中的IF语句中设置时间延迟
- 如何使用OpenMP并行这两个循环
- 从python调用openMP共享库时,未定义opnMP函数
- 如何使用OpenMP并行化此矩阵时间矢量运算
- 如何使用OpenMP使这个循环并行
- 如何通过替换顺序代码的while循环来添加OpenMP for循环
- 查找最近配对时的OpenMP竞赛条件
- 使用输入打破 OpenMP 中的循环
- 模板化类中静态成员的延迟初始化
- 为什么 openmp 的并行不适用于矢量化色彩空间转换?
- 在 Windows 8/10 技术中完全实时的屏幕捕获,没有延迟
- 在 openmp 中,omp_get_thread_num是否绑定到物理线程?
- Openmp:所有线程由于一个线程中的延迟而停止
- OpenMP线程、数据访问延迟和STL数据容器
- 减少openmp并行延迟的措施