2016-03-23 12 views
3

私は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 

をテストするには、以下のFortranコードを書かれている出力は

enter image description here

であることはatomiccriticalの結果が間違っていることを意味しています。これは奇妙なことですが、私はそれらを追加することでレース状態を避けることができたと思いましたしかし、同期のない最初のループは正解ですが、ここにレースはありませんか?私のコードで何が間違っていますか?

+0

期待される正しい結果は何ですか?それはラインの上ですか?これらをテキストとして含める方が良いでしょう。画像はある時間後にホスティングによって削除される可能性があります。 –

+0

私は競合状態が実際に 'a = atmp;だと思います。 b = btmp 'となる。しかし、私はあまりにも長い間コードを研究していませんでした。 –

+0

@HighPerformanceMarkここでは、92ページのこの種の使用方法を見ました。http://openmp.org/mp-documents/openmp-examples-4.0.2.pdf。これは、原子の典型的な使用法として、これは正しくないのですか? – user15964

答えて

6

あなたのコードに問題は競合状態

!$omp parallel 

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

すべてのスレッドがその操作を行うと、彼らは衝突です。これらの行の周りにomp singleが必要です。

各スレッドが異なる配列の要素で動作するので、あなたは

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

内の任意atomiccriticalを必要としません。あなたの例では

問題が

!$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で2つの異なるスレッドに同じ値を返すことができますし、この潜在的な競合状態を保護しなければならないということであるOpenMP仕様から。

+0

素敵な答えをありがとう! – user15964

関連する問題