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)

因此没有发生工作共享,所有线程都在执行完整的循环。

关于附加问题:是的,这是一个严重的问题,您必须解决它。