OMP更新向量问题

时间:2015-07-12 09:21:30

标签: fortran openmp

我有以下代码片段

!$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万)时,它会以某种方式(希望)成为一个问题吗?

1 个答案:

答案 0 :(得分:2)

您刚刚忘记了<{p>}中的DO

!$OMP PARALLEL DO PRIVATE(i)

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

关于其他问题:是的,这是一个严重的问题,你必须解决它。