インテル® Fortran コンパイラー 19.0 デベロッパー・ガイドおよびリファレンス

配列コピーの影響

Fortran 言語セマンティクスでは、コンパイラーが配列や配列スライスの一時コピーを作成しなければならないことがあります。このような状況は、次のような場合に発生します。

デフォルトでは、これらの一時的な値はスタック上に作成され、ランタイムにスタック・オーバーフロー・エラーを引き起こす可能性があります。スタックのサイズは大きくできますが、オペレーティング・システムに応じて制限があります。heap-arrays コンパイラー・オプションを使用すると、このような一時コピーをスタックではなくヒープに割り当てます。ヒープ割り当てでは、一時的な値を作成する際や削除する際にわずかにオーバーヘッドが生じますが、残りのコードと比べるとそれほど重要ではありません。

一時コピーの必要性を完全に排除することで、さらにパフォーマンスを向上できます。上記のリストの最初の例では、連続していない配列を連続した配列を想定しているプロシージャーに渡す場合、check: arg_temp_created コンパイラー・オプションを有効にすると、渡される引数が連続していないとコンパイラーが判断した際に、ランタイム情報を含むメッセージが発行されます。ランタイムテストで引数が連続していると判断された場合はコピーは作成されません。ただし、このオプションはその他の一時コピーの使用に対しては診断メッセージを発行しません。

配列引数の一時コピーを回避する 1 つの方法として、DIMENSION(:) 属性で配列を形状引き継ぎ配列として宣言するように、呼び出されるプロシージャーを変更する方法があります。そのようなプロシージャーでは、呼び出し元が認識できるよう明示的なインターフェイスが必要です。呼び出されたプロシージャーをモジュールまたは CONTAINS セクションに配置することにより、インターフェイスが提供されます。また、INTERFACE ブロックを宣言することもできます。

POINTER 配列を使用すると、コンパイラーで一時的な値を回避できたかどうかを認識することが難しくなります。可能であれば、特に派生型のコンポーネントは POINTER を ALLOCATABLE に置き換えてください。言語定義は、ALLOCATABLE 配列が POINTER のようにその他の変数と重複することがなく、連続しているとみなすようにコンパイラーに指示します。

一時的な値が作成される別の状況として、ルーチン引数、参照/ホスト結合変数、あるいは COMMON 変数に依存した境界を持つ、プロシージャーのローカル変数である自動配列があります。これらの自動配列はデフォルトでスタック上に作成されます。heap-arrays コンパイラー・オプションは、これらをヒープ上に作成します。そのような配列は、代わりに ALLOCATABLE にすることを検討してください。SAVE 属性を持たないローカルの ALLOCATABLE 変数は、ルーチンの出口で自動で割り当て解除されます。以下に例を示します。 置換前:

SUBROUTINE SUB (N)
INTEGER, INTENT(IN) :: N
REAL :: A(N)

置換後:

SUBROUTINE SUB(N)
INTEGER, INTENT(IN) :: N
REAL, ALLOCATABLE :: A(:)
ALLOCATE (A(N))

関連情報