2016-03-23 57 views
3

我已經寫下面Fortran代碼測試atomiccritical爲什麼OpenMP原子和關鍵不能給出正確的結果?

program test 
    implicit none 
    integer::i 
    integer::a(10),b(10),atmp(10),btmp(10) 
    a=[1,2,3,4,5,6,7,8,9,10] 
    b=[12,32,54,77,32,19,34,1,75,45] 
    atmp=a 
    btmp=b 
    write(*,'(1X,10I4)') a+b 
    print*,'------------------' 
    !$omp parallel 
    !$omp do 
    do i=1,10 
     B(I) = B(I)+A(I) 
    end do 
    !$omp end do 
    !$omp single 
    write(*,'(1X,10I4)') b 
    !$omp end single 

    a=atmp 
    b=btmp 
    !$omp do 
    do i=1,10 
     !$omp critical 
     B(I) = B(I)+A(I) 
     !$omp end critical 
    end do 
    !$omp end do 
    !$omp single 
    write(*,'(1X,10I4)') b 
    !$omp end single 

    a=atmp 
    b=btmp 
    !$omp do 
    do i=1,10 
     !$omp atomic 
     B(I) = B(I)+A(I) 
     !$omp end atomic 
    end do 
    !$omp end do 
    !$omp single 
    write(*,'(1X,10I4)') b 
    !$omp end single 

    !$omp end parallel 
end program 

輸出是

enter image description here

它意味着atomiccritical是錯誤的這一結果。這很奇怪,我認爲增加他們可以避免賽車狀況。然而,沒有同步的第一個循環給出了正確的答案,這裏沒有比賽嗎?我的代碼有什麼問題?

+0

預期的正確結果是什麼?在線以上嗎?將這些文字包含進去會更好。一段時間後,圖片可能會被主機刪除。 –

+0

我認爲比賽條件實際上是'a = atmp; b = btmp'在平行區域。但是我沒有太久研究代碼。 –

+0

@HighPerformanceMark我在這裏看到了這種用法,在這裏http://openmp.org/mp-documents/openmp-examples-4.0.2.pdf。文檔顯示這是原子的典型用法,是不是正確? – user15964

回答

6

在你的代碼的問題是競爭狀態

!$omp parallel 

... 
    a=atmp 
    b=btmp 
... 
    !$omp end parallel 

所有線程做操作和他們發生衝突。你需要圍繞這些線路omp single

因爲每個線程不同的數組元素進行操作你不需要任何atomiccritical

!$omp do 
do i=1,10 
    B(I) = B(I)+A(I) 
end do 
!$omp end do 

從OpenMP規範的例子的問題是,在

!$OMP PARALLEL DO SHARED(X, Y, INDEX, N) 
DO I=1,N 
    !$OMP  ATOMIC UPDATE 
    X(INDEX(I)) = X(INDEX(I)) + WORK1(I) 

數組或功能INDEX(I)可以用不同的I爲兩個不同的線程返回相同的值,你必須保護這種潛在的競爭條件。

+0

非常感謝您的回答! – user15964

相關問題