gpt4 book ai didi

fortran - 崩溃 OpenMP 的特例

转载 作者:行者123 更新时间:2023-12-01 12:31:47 25 4
gpt4 key购买 nike

我有一个可能很简单的问题,但查看 SO 我找不到任何问同样问题的问题。我的问题是:下面 OpenMP 代码中的 collapse 子句是否会正确处理两个内部循环?还是仅在第一个内部循环中崩溃?

!$omp parallel do collapse(2) private(iy, ix, iz)
do iy = 1, ny
do ix = 1, nx
! stuff
enddo
do iz = 1, nz
! different stuff
enddo
enddo
!$omp end parallel do

此代码为我编译并明显显示了并行化的好处。但是,我知道标准说:

All loops associated with the loop construct must be perfectly nested; that is, there must be no intervening code nor any OpenMP directive between any two loops.

所以我的直觉 react 是 OpenMP 只是崩溃了第一个内部循环 (ix)。但是它如何处理第二个内部循环 (iz)?

我显然是在尝试使用代码来执行以下操作,但是以这种方式编写代码更加丑陋和冗长:

!$omp parallel private(iy, ix, iz)
!$omp do collapse(2)
do iy = 1, ny
do ix = 1, nx
! stuff
enddo
enddo
!$omp end do nowait

!$omp do collapse(2)
do iy = 1, ny
do iz = 1, nz
! different stuff
enddo
enddo
!$omp end do nowait
!$omp end parallel do

最佳答案

第一个内部循环是介于外部循环和第二个内部循环之间的代码(据我所知)。如果 nznx,则没有矩形环。无论如何,程序语义是第一个内循环必须在第二个内循环开始之前完成;它可能会执行第二个循环使用的中间计算。给定的 OpenMP 实现可能做你想做的事——我没有尝试测试这个。

请注意,第二个示例更改了程序的语义:执行所有 ix 循环,然后执行所有 iz 循环,而不是每个 ix 循环后跟每个 iz 循环以获得相同的 iy 值。如果您可以并行化 ix 循环,这应该是安全的,因为只有当 ix 计算都不依赖于任何 iz 计算时,您才能这样做,但如果 iz 循环要重新使用相同的数据,则可能效率不高。所以正确的语义将取决于在给定循环运行之前需要发生什么。 iz 循环是否需要 ix 循环首先运行相同的 iy 值?如果没有,您也许可以使用嵌套并行。

关于循环折叠的注意事项:循环折叠通常意味着您采用一对嵌套的循环,例如,

for (i=0;i<100;++i)
for (j=0;j<50;++j)

然后将它们变成一个循环,例如:

for (ij=0;ij<5000;++ij)

如果你有两个不同索引的不同内部循环,你不能这样做,而且编译器不能自动改变建议的执行顺序,因为这会改变程序语义。我不确定每个 OpenMP 实现如何处理这段代码,但我很确定它不会按照您希望的方式工作。

关于fortran - 崩溃 OpenMP 的特例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32530452/

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