我有以下代码片段
!$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万)时,它会以某种方式(希望)成为一个问题吗?
答案 0 :(得分:2)
您刚刚忘记了<{p>}中的DO
!$OMP PARALLEL DO PRIVATE(i)
因此没有发生工作共享,所有线程都在完成循环。
关于其他问题:是的,这是一个严重的问题,你必须解决它。