COMMON ブロックを使用して、コード全体で使用される配列を格納する mpi バージョンのプログラムがあります。残念ながら、COMMON ブロック サイズで配列を宣言する方法はありません。そのサイズは、実行時にしかわかりません。そこで、回避策として、ALLOCATABLE 配列を受け入れるモジュールにその配列を移動することにしました。つまり、COMMON ブロック内のすべての配列が消去され、代わりに ALLOCATE が使用されました。したがって、これが私のプログラムで変更した唯一のものです。残念ながら、プログラムのパフォーマンスはひどいものでした (COMMON ブロックの実現と比較した場合)。mpi 設定に関しては、各計算ノードに単一の mpi プロセスがあり、各 mpi プロセスには単一のスレッドがあります。似てるの見つけたここで質問されますが、考えないでください(理解できません:))私のケース(各プロセスに単一のスレッドがある場合)にどのように適用できるか。助けていただければ幸いです。
これは、私が話していたことを示す簡単な例です (以下は疑似コードです)。
"ソースファイル":
SUBROUTINE ZEROSET()
INCLUDE 'FILE_1.INC'
INCLUDE 'FILE_2.INC'
INCLUDE 'FILE_3.INC'
....
INCLUDE 'FILE_N.INC'
ARRAY_1 = 0.0
ARRAY_2 = 0.0
ARRAY_3 = 0.0
ARRAY_4 = 0.0
...
ARRAY_N = 0.0
END SUBROUTINE
ご覧のとおり、ZEROSET() には並列または MPI 要素はありません。FILE_1.INC、FILE_2、...、FILE_N.INC は、ARRAY_1、ARRAY_2 ... ARRAY_N が COMMON ブロックで定義されているファイルです。そんな感じ
REAL ARRAY_1
COMMON /ARRAY_1/ ARRAY_1(NX, NY, NZ)
NX、NY、NZ は、PARAMETER ディレクティブを使用して記述された明確に定義されたパラメーターです。モジュールを使用するときは、すべての COMMON ブロックを破棄しただけなので、FILE_I.INC は次のようになります。
REAL, ALLOCATABLE:: ARRAY_I(:,:,:)
そして、上記の「INCLUDE 'FILE_I.INC'」ステートメントを「USE FILE_I」に変更しました。実際、並列プログラムを実行する場合、特定の 1 つのプロセスがドメイン全体 (NX、NY、NZ) を必要としないため、パラメーターを計算してから ARRAY_I を割り当てます (一度だけ!)。
サブルーチン ZEROSET() は、COMMON ブロックで 0.18 秒、モジュールで 0.36 秒実行されます (配列の次元が実行時に計算される場合)。そのため、パフォーマンスは 2 倍悪化しました。
すべてが明確になったことを願っています。大変助かります。