我有下面的代碼片斷OMP更新向量問題
!$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萬),它會以某種方式(希望)變得不那麼成問題?
非常感謝。像大多數錯誤一樣,一旦找到它們,它們就顯得很愚蠢。我確實擔心我必須再次完成大部分生產運行......順便說一句,您提醒我發佈最低工作代碼是正確的,我在機場匆忙行事。無論如何,現在事情已經解決了。 – Nigu
最後,似乎其他循環都可以。我建立在別人的代碼上,他實際上使用了不同的方法來進行工作共享... inode1和inode2的值是THREADPRIVATE變量,對於每個線程都是不同的。但是對於這個具體的例子來說,事實並非如此。不是說我的問題或答案是重要的,而是爲了完整性。 – Nigu