gpt4 book ai didi

asynchronous - fortran openmp 同步

转载 作者:行者123 更新时间:2023-12-02 01:58:16 24 4
gpt4 key购买 nike

我正在尝试通过 OpenMP 并行化一个 Fortran 循环。循环本质上只包含两个命令:

do i=1,LSample
calcSslice(Vpot(:,:,i), Sslice)
rpold = rp
combine_rp_matrices (rpold, Sslice, rp)
end do

calcSslice 子例程读取 Vpot(:,:,i),执行一些计算并将结果存储在矩阵 Sslice 中。 combine_rp_matrices 使用 rpold 和 Sslice 来更新 rp。 rp 充当运行变量,是程序所需的输出。来自不同迭代的 Sslice 矩阵与 rp 组合的顺序无关紧要。我第一次尝试并行化这个循环是这样的:

!$OMP PARALLEL DO DEFAULT(SHARED), PRIVATE(Sslice), SCHEDULE(DYNAMIC)
do i=1,LSample
calcSslice(Vpot(:,:,i), Sslice)
!$OMP CRITICAL
rpold = rp
combine_rp_matrices (rpold, Sslice, rp)
!$OMP END CRITICAL
end do
!$OMP END PARALLEL DO

这会编译并运行,但会产生错误的结果。使用以下代码我得到了正确的结果但执行速度慢得多(尽管仍然比序列化代码快):

!$OMP PARALLEL DO DEFAULT(SHARED), PRIVATE(Sslice), SCHEDULE(DYNAMIC)
do i=1,LSample
!$OMP CRITICAL(Crit2)
calcSslice(Vpot(:,:,i), Sslice)
!$OMP END CRITICAL(Crit2)
!$OMP CRITICAL
rpold = rp
combine_rp_matrices (rpold, Sslice, rp)
!$OMP END CRITICAL
end do
!$OMP END PARALLEL DO

所以显然 calcSslice 存在一些同步问题。但是,我不太明白这会发生在哪里。 Vpot 仅在 calcSslice 中读取而不写入,并且 Sslice 是线程私有(private)变量。 calcSslice 中使用的任何全局变量也只能从中读取。变量 rpold 和 rp 在 DO 循环所属的子例程范围内声明,因此不能被 calcSslice 访问。 calcSslice 中声明的变量使用以下属性:intent(in)、intent(out)、target、pointer。

哪里出了问题?

编辑:问题已解决,原因是声明期间 calcSslice 中变量的初始化,这意味着 save 属性。

最佳答案

我的猜测是 calcSslice 不是线程安全的。确保此子例程不访问除只读以外的全局变量,并且不使用 save 属性(如果在声明期间初始化变量,请注意隐式保存!)。您可以使用英特尔提供的线程检查器来查找代码中的竞争条件。如果您无法访问此类软件,我会从一个虚拟程序开始,然后逐步填充例程以查看它失败的地方。

另一件让我困惑的事情是循环体的最后两行。每个线程备份整个矩阵,然后添加他的切片。收集所有切片(例如通过 reduction 子句)然后将那个大切片合并一次不是更好吗?

关于asynchronous - fortran openmp 同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18677905/

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