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で間違っている
還元(+:b)を指定すると、競合状態を修正できます。 – tim18
このコードは、8つのスレッドが存在すると仮定しているようです。あなたが本当のことではない大型マシンで走っていたら! (numthreads(8)節を追加することは推奨していませんが、明示的にスレッド番号を使用するこのようなコードは悪い考えです...) –
はい、私は8つのスレッドを定義しました。私はこれを言及する必要があります。 – Yongxin