2016-08-24 14 views
1
program main 
use omp_lib 
implicit none 
integer :: n=8 
integer :: i, j, myid, a(8, 8), b, c(8) 

! Generate a 8*8 array A                       
!$omp parallel default(none), private(i, myid), &                 
!$omp shared(a, n)                        
myid = omp_get_thread_num()+1 
do i = 1, n 
    a(i, myid) = i*myid 
end do 
!$omp end parallel                        

! Array A                           
print*, 'Array A is' 
do i = 1, n 
print*, a(:, i) 
end do 

! Sum of array A                         
b = 0 
!$omp parallel reduction(+:b), shared(a, n), private(i, myid)              
myid = omp_get_thread_num()+1 
do i = 1, n 
    b = b + a(i, myid) 
end do 
!$omp end parallel                        
print*, 'Sum of array A by reduction is ', b 

b = 0 
c = 0 
!$omp parallel do                         
do i = 1, n 
    do j = 1, n 
     c(i) = c(i) + a(j, i) 
    end do 
end do 
!$omp end parallel do                        
print*, 'Sum of array A by using parallel do is', sum(c) 

!$omp parallel do                         
do i = 1, n 
    do j = 1, n 
     b = b + a(j, i) 
    end do 
end do 
!$omp end parallel do                        
print*, 'Sum of array A by using parallel do in another way is', b 

end program main 

私はOpenMPを実装するために上記のFortranコードを書いて、3つの異なる方法で8 * 8配列のすべての要素を集計しました。最初のものは縮小を使用し、動作します。次に、8要素の1次元配列を作成しました。私は並列領域の各列を集計し、それらを合計します。そしてこれも同様に機能します。 3番目は、配列のすべての要素を合計し、それを並列領域に配置するために整数を使用しました。この結果は正しくなく、毎回変化します。なぜこのような状況が起こるのか分かりません。なぜなら、publicとprivateを指定しなかったか、変数bがプロシージャで上書きされたからですか?が間違ってFortranで間違っている

+1

還元(+:b)を指定すると、競合状態を修正できます。 – tim18

+0

このコードは、8つのスレッドが存在すると仮定しているようです。あなたが本当のことではない大型マシンで走っていたら! (numthreads(8)節を追加することは推奨していませんが、明示的にスレッド番号を使用するこのようなコードは悪い考えです...) –

+0

はい、私は8つのスレッドを定義しました。私はこれを言及する必要があります。 – Yongxin

答えて

5

3番目のシナリオでは、bに競合状態があります。いくつかのスレッドは、適切な同期/民営化を行わずに同じ変数を読み書きしています。

2番目のシナリオで競合状態が発生しないことに注意してください。各スレッドは他の誰もアクセスしていないデータ(つまりc(i))を更新しています。

最後に、あなたの最後のシナリオにはいくつかの解決策は:

  1. b = b + c(j,i)式の前にpragma omp atomicディレクティブを追加プラグマに
  2. あなたは手動民営化を実装することができreducion(+:b)句を追加
+0

彼は最後のループで同じ問題を抱えているようですが、bはすべてのスレッドによって読み込まれ更新されています。 – Jauch

+0

私はその1つを参照しています、Aの合計を計算する他の2つの並列ループは、罰金です – smateo

+0

あなたが言ったbシナリオは、第3のシナリオではなく、第4のシナリオです:) – Jauch

関連する問題