2016-03-20 10 views
1

Fortran 90の配列に対して要素ごとの計算を行い、openmpでコードを並列化したい。エラーなし割り当て可能な配列のOpenMP並列ワークシェアレット

real(8),dimension(:,:,:,:),allocatable :: x,r 
allocate(x(n,n,n,n)) 
allocate(r(n,n,n,n)) 

が、シリアルでプログラム実行することと:私は割付け配列と静的配列xとRを置き換えるために、今したいので、私は入力し

program test 
implicit none 

integer,parameter :: n=50 
integer :: i 
integer(8) :: t1,t2,freq 
real(8) :: seq(n),r(n,n,n,n) 
real(8),dimension(n,n,n,n) :: x 

call system_clock(COUNT_RATE=freq) 

seq=[(i,i=1,n)] 
x=spread(spread(spread(seq,2,n),3,n),4,n) 

call system_clock(t1) 

!$omp parallel workshare 
! do some array calculation 
r=atan(exp(-x)) 
!$omp end parallel workshare 

call system_clock(t2) 

print*, sum(r) 
print '(f6.3)',(t2-t1)/real(freq) 

end program test 

:私は今、次のコードを持っていますコンパイラは "!$ omp parallel workshare"という行を考慮しません。

この場合、どのようなオプションを使用して並列化する必要がありますか?私はループでomp parallel doを試しましたが、はるかに遅いです。

私はWindows上でのgfortran 5.1.0で、私のコードをコンパイルしています:

gfortran -ffree-form test.f -o main.exe -O3 -fopenmp -fno-automatic 
+0

* "しかし、$ omp並列作業共有は割り当て可能な配列では機能しません" *なぜですか?それは何を意味するのですか?どういう意味ですか*「それはうまくいかない」*意味のないこれらのフレーズは使用しないでください。試したことと何が起こったのかを教えてください。 BTW、 'real(8)'は醜いです:http://stackoverflow.com/questions/838310/fortran-90-kind-parameter/856243#856243 http://stackoverflow.com/questions/3170239/fortran-integer4- vs-integer4-vs-integerkind-4/3170438#3170438 –

+0

これはプログラムがエラーなくシリアルで実行され、コンパイラは "!$ omp parallel workshare"という行を考慮しないことを意味します。 – x1hgg1x

+1

関連:https://stackoverflow.com/questions/17812003/parallelization-of-elementwise-matrix-multiplication/17832699#17832699 –

答えて

4

私は前にgfortranでこの問題に遭遇してきました。溶液は、次の形で配列を指定することである:ここ

!$omp parallel workshare 
! do some array calculation 
r(:,:,:,:) = atan(exp(-x)) 
!$omp end parallel workshare 

referenceあります。

+0

それは私のために働く。実際、私はすでに静的な配列でそれを試しましたが、私はそれを削除したので違いは見えませんでした。だから違いは割り当て可能な配列にしか見えません。 – x1hgg1x

+0

@VladimirF gfortran 5.3.1を使用している私のマシンでは、この問題は依然として存在しています。 –

+3

おそらく、 'r = atan(exp(-x)) 'バージョンではなく、rが割り当て可能な_and_が全体として割り当てられている間に、解答のバージョンが機能する理由が考えられます。つまり、再割り当てが必要になる可能性があり、並行作業シェアを無効にする可能性があります。一方、 'r(:、:、:、:) :)を使うと、式の結果を_existing_配列rに代入することができます。もしあなたのビルド構成に応じて境界が互換性がないならば、 –

関連する問題