私はこの質問をFortranの観点から書いていますが、質問はFortranだけに限定されていません(したがってC++タグ)。openmp並列待ち時間を緩和するための対策
私には2つの質問があります。私は、OpenMP並列ループhereの開始と停止時にレイテンシが存在することを読んだ。私の質問は次のとおりです:
Q1)OpenMPの待ち時間を緩和するための実践的な措置はありますか?
Q2次のいずれの方法が優れていますか?
方法1
x = 1.0; y = 2.0
!$OMP PARALLEL DO
do k=1,Nz; do j=1,Ny; do i=1,Nx
x(i,j,k) = x(i,j,k)+y(i,j,k)
enddo; enddo; enddo
!$OMP END PARALLEL DO
!$OMP PARALLEL DO
do k=1,Nz; do j=1,Ny; do i=1,Nx
x(i,j,k) = x(i,j,k)*y(i,j,k)
enddo; enddo; enddo
!$OMP END PARALLEL DO
! (x should = 6.0 at this point)
方法2
x = 1.0; y = 2.0
!$OMP PARALLEL DO
do k=1,Nz; do j=1,Ny; do i=1,Nx
x(i,j,k) = x(i,j,k)+y(i,j,k)
x(i,j,k) = x(i,j,k)*y(i,j,k)
enddo; enddo; enddo
!$OMP END PARALLEL DO
! (x should = 6.0 at this point)
方法3
1)手順
の配列を含むオブジェクトを作成します2)
x = 1.0; y = 2.0
!$OMP PARALLEL DO
do k=1,Nz; do j=1,Ny; do i=1,Nx
do t=1,procedure_array%N
call procedure_array%single_procedure(t)%P(x(i,j,k),y(i,j,k))
enddo
enddo; enddo; enddo
!$OMP END PARALLEL DO
! (x should = 6.0 at this point)
はのは、サブルーチンadd
(x=x+y
)とそれぞれmultiply
(x=x*y
)にそのprocedure_array%N = 2
と
procedure_array%single_procedure(1)
procedure_array%single_procedure(2)
ポイントを仮定しよう、次のような手順の配列を呼び出します。
3)クリーンアップ(DEALLOCATE)
コメント
まず、それは方法2は、方法1よりも優れていることは明らかですので、私は方法3方法2との比較では、本当に興味があります。第2に、「試してみる」というのは有効な答えですが、方法3が具体的な例が実際に使用されているかどうか、または方法2が方法2に比べて劣っている概念的理由があるかどうかを知りたい(例えば、多くのプロシージャコールによるオーバーヘッド)。最後に、方法2と3を実質的に同等にするために(例えば、特定のスレッドを具体的に指定することによって)何らかの特別な注意が払われる場合、それらは何ですか?
ご協力いただきありがとうございます。コメントの光で
アップデート
、私は次の修正を加えました。
- は、MPIに関連するすべてのものを削除
- (、@Gillesをありがとう)、これは本当にOpenMPの質問(、@Vladimirをありがとうございました)(私自身の実現)以下
- 追加の明確化 ある操作を修正しました
キャッシュメモリー(およびキャッシュフォルト)についてのご質問、ありがとうございました。非常に参考になりました。
明確化最後に
、コメントから、私はこの質問の焦点は、プロシージャ・コールについて、実際には厳密OpenMP並列に関連していないことに気づきました。つまり、私はopenmpステートメントを残しました。これは、もっと複雑なアプリケーションで起こっていることであり、可能な限り保存したいからです。 @ Chaositのコメントから、プロシージャコールにはオーバーヘッドが必要であり、メソッド3を遅らせるようです。これを回避する方法はありますか?
また、私が間違っている場合は私を修正してください。しかし、方法2の2つの操作は書面による順序で実行され、正しい最終x
の値になります。
スニペットの両方の計算が意味をなさないことを除いて(OK、ちょうど私たちが何らかの計算を行うことを示しています)、**メソッド1 **と**メソッド2 **は同等ではないことが判明しています。注文事項(この場合は多く)。したがって、メソッド2が**メソッド1 **から得られた結果であれば、メソッド2 **が間違っているので、「メソッド2がメソッド1よりも優れている」というあなたの主張は非常に疑わしいです( 'a = b = 0'を除いて)。私は知っている、これはあなたのポイントではありませんが、私は効率の前にすべて正しいです。 – Gilles
*「MPI並列化ループ」*とはどういう意味ですか?そのようなことはありません。 –