2015-07-12 84 views
0

我有下面的代碼片斷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萬),它會以某種方式(希望)變得不那麼成問題?

回答

2

你只是在

!$OMP PARALLEL DO PRIVATE(i) 

忘了DO因此沒有工作共享發生,所有的線程正在做完整的循環。

關於附加問題:是的,這是一個嚴重的問題,你必須解決它。

+0

非常感謝。像大多數錯誤一樣,一旦找到它們,它們就顯得很愚蠢。我確實擔心我必須再次完成大部分生產運行......順便說一句,您提醒我發佈最低工作代碼是正確的,我在機場匆忙行事。無論如何,現在事情已經解決了。 – Nigu

+0

最後,似乎其他循環都可以。我建立在別人的代碼上,他實際上使用了不同的方法來進行工作共享... inode1和inode2的值是THREADPRIVATE變量,對於每個線程都是不同的。但是對於這個具體的例子來說,事實並非如此。不是說我的問題或答案是重要的,而是爲了完整性。 – Nigu