6

Fortran では、明示的に として宣言しない限り、サブルーチンまたは関数を再帰的に呼び出すことはできませんrecursive。Fortran プログラマーは、このため、コンパイラーはすべてのローカル変数に静的ストレージを割り当てて、プログラムの速度を向上させることができると私に言いました。今日のほとんどのプロセッサはスタックへの高速参照用に最適化されているため、この主張には非常に驚いています。スタックとは対照的に、静的アドレスは他のサブルーチンによって使用されないため、静的アドレスからロードされるローカル変数はおそらく多くのキャッシュミスを引き起こすと思います。

静的アドレスでローカル変数を使用すると、実際に速度が向上しますか? 再帰的なサブルーチンと関数を許可しない、他にどのような最適化が可能ですか?

4

2 に答える 2

7

あなたが相談したFortranプログラマーは逆のことをしています-以前は(仮想の)コンパイラーが変数に静的ストレージしか割り当てることができなかったため、再帰に対する制限が生じました。パフォーマンスは、ほとんどの場合無関係な考慮事項です。ただし、何かをまったく実行できない場合は、それを迅速に実行する可能性は低いと思います。

初期の Fortran (F77 以前) は、プログラムを実行する前に、fortran プロセッサによってプログラム全体のメモリ要件を静的に決定できるように設計されていました。これは、当時の限られたマシン アーキテクチャの一部に適していました。この「静的解析によって総メモリを計算できなければならない」という制限がある一般的なケースでは、再帰 (メモリ要件はプログラムの入力によって異なる場合があります) のようなものを機能させるのは困難です。したがって、言語はそれを許可しませんでした。

特定のプロセッサが実際に言語をどのように実装するかは、彼ら次第でした.ローカル変数にスタックベースのストレージを使用したい場合は、そうすることができました. 標準の境界外で記述している Fortran プログラマーは、静的記憶域 (呼び出し間で値を記憶する保存されていない変数など) を使用することで得られる動作を期待するように歴史的に条件付けられてきた可能性がありますが、基礎となる実装に敏感なプログラムはそうではありませんでした。規格適合。

(この制限のあるアーキテクチャは F90 で廃止されました。その標準では、プログラムの入力に応じてプログラムのメモリ要件が動的に変化する方法がいくつか導入されました。その 1 つが割り当てステートメントですが、現在では自動変数も許可されています。)

保存されていない小さなローカル変数 (スカラー) の場合、関連付けられたストレージがスタックにある方が高速である可能性が高くなります (適切なハードウェアを想定)。

再帰が可能な手続きとそうでない手続きを区別することは、今日でも実用的な価値があります。ローカル変数が大きい場合 (配列または長い文字)、単にスタックに収まらない可能性があります。この状況を回避するには、プロシージャが再帰的とマークされておらず、配列のサイズが既知の場合、fortran プロセッサは静的ストレージを使用できます。これにより、動的メモリ割り当てに関連するオーバーヘッドが回避されますが、これはかなり高価になる可能性があります。プロシージャが再帰的とマークされている (ローカル変数が保存されていない) 場合、または配列のサイズがコンパイル時に不明な場合、Fortran プロセッサには選択の余地がありません。データがスタックに収まることを期待するか、動的メモリを使用するかのいずれかです。割り当て。

于 2012-07-23T01:12:58.727 に答える
2

これは、一部のメインフレーム CPU にはスタックがまったくないためです (s/360 など)。コンパイラは、それをシミュレートするために特別なコードを生成する必要がありました。したがって、再帰的でない関数には、より単純な/少ないコードが含まれていました。これが今日でも関連性があるかどうかはわかりません。

スタック上の場所ではなく特定のアドレスを参照しても、キャッシュ ミスが増えるわけではありません。むしろ静的なアドレスは、オプティマイザーがその使用状況に応じてメモリに配置する可能性があるため、オプティマイザーの作業を容易にします。

于 2012-07-22T23:54:43.910 に答える