OMP更新向量问题
OMP update vector issue
我有以下代码片段
!$OMP PARALLEL PRIVATE(i)
do i = inode1,inode2
if (mod(CEILING(Rat(1,i)*checkerDivider),2).ne.mod(CEILING(Rat(2,i)*checkerDivider),2)) then
H0(i) = H0(i)
else
H0(i) = H0(i) + onsiteShift
endif
end do
!$OMP END PARALLEL
onsiteShift 等于 0.02,H0(i) 等于 0。对于这个例子,我在 16 个处理器上工作。每当我输入 else
子句时,它显然应该将 H0(i) 的值设置为 0.02。但是,在这种情况下,我最终得到 0 到 0.32 之间的随机值(步长为 0.02)。显然,我多次输入子句以获得相同的 i
值。我也尝试使用 !$OMP ATOMIC UPDATE
,但最终得到的值正好是 0.32(= 16*0.02...)。
此外,我认为通过使用临时 H0_temp
变量,我可以避免不同的线程出现这种竞争条件问题。
!$OMP PARALLEL PRIVATE(i, H0_temp)
do i = inode1,inode2
H0_temp = H0(i)
if (mod(CEILING(Rat(1,i)*checkerDivider),2).ne.mod(CEILING(Rat(2,i)*checkerDivider),2)) then
H0_temp = H0_temp
else
H0_temp = H0_temp + onsiteShift
endif
H0(i) = H0_temp
end do
!$OMP END PARALLEL
还是不行。我也尝试了一些减少的方法......
基本上,如何使用OMP改变H0(i)的值? H0 的最终结果应该是 0 或 0.02。没有其他价值。如果我只使用一个处理器就没有问题...
我的第二个问题,这样的问题对我之前的计算有多大的影响。我只注意到这个案例的问题,但我怀疑我的许多其他循环可能也有同样的问题。或者当 inode2
的值非常大(我的生产运行大约 2000 万)时,它是否(希望)以某种方式变得不那么成问题?
您刚刚忘记了DO
!$OMP PARALLEL DO PRIVATE(i)
因此没有发生工作共享,所有线程都在执行完整的循环。
关于附加问题:是的,这是一个严重的问题,您必须解决它。
我有以下代码片段
!$OMP PARALLEL PRIVATE(i)
do i = inode1,inode2
if (mod(CEILING(Rat(1,i)*checkerDivider),2).ne.mod(CEILING(Rat(2,i)*checkerDivider),2)) then
H0(i) = H0(i)
else
H0(i) = H0(i) + onsiteShift
endif
end do
!$OMP END PARALLEL
onsiteShift 等于 0.02,H0(i) 等于 0。对于这个例子,我在 16 个处理器上工作。每当我输入 else
子句时,它显然应该将 H0(i) 的值设置为 0.02。但是,在这种情况下,我最终得到 0 到 0.32 之间的随机值(步长为 0.02)。显然,我多次输入子句以获得相同的 i
值。我也尝试使用 !$OMP ATOMIC UPDATE
,但最终得到的值正好是 0.32(= 16*0.02...)。
此外,我认为通过使用临时 H0_temp
变量,我可以避免不同的线程出现这种竞争条件问题。
!$OMP PARALLEL PRIVATE(i, H0_temp)
do i = inode1,inode2
H0_temp = H0(i)
if (mod(CEILING(Rat(1,i)*checkerDivider),2).ne.mod(CEILING(Rat(2,i)*checkerDivider),2)) then
H0_temp = H0_temp
else
H0_temp = H0_temp + onsiteShift
endif
H0(i) = H0_temp
end do
!$OMP END PARALLEL
还是不行。我也尝试了一些减少的方法......
基本上,如何使用OMP改变H0(i)的值? H0 的最终结果应该是 0 或 0.02。没有其他价值。如果我只使用一个处理器就没有问题...
我的第二个问题,这样的问题对我之前的计算有多大的影响。我只注意到这个案例的问题,但我怀疑我的许多其他循环可能也有同样的问题。或者当 inode2
的值非常大(我的生产运行大约 2000 万)时,它是否(希望)以某种方式变得不那么成问题?
您刚刚忘记了DO
!$OMP PARALLEL DO PRIVATE(i)
因此没有发生工作共享,所有线程都在执行完整的循环。
关于附加问题:是的,这是一个严重的问题,您必须解决它。