5

私は習慣的にたくさんの関数を使ってコードを書いていますが、それがより明確になっていると思います。しかし今、私は非常に効率的である必要があるいくつかのコードをFortranで書いています、そして私は関数を使いすぎるとそれが遅くなるのか、それともコンパイラーが何が起こっているのかを理解して最適化するのか疑問に思っていますか?

Java / Pythonなどでは、各関数がオブジェクトであることを知っているので、多くの関数を作成するには、それらをメモリ内に作成する必要があります。Haskellでは関数が互いに縮小されていることも知っているので、そこではほとんど違いがありません。

誰かがFortranのケースについて知っていますか?インテント/純粋関数の使用/ローカル変数の宣言数の減少/その他との違いはありますか?

4

4 に答える 4

9

関数呼び出しは、Fortranのようなスタックベースの言語のパフォーマンスコストを伴います。スタックなどに追加する必要があります。

このため、可能であれば、ほとんどのコンパイラは関数呼び出しを積極的にインライン化しようとします。ほとんどの場合、コンパイラは、プログラム内の特定の関数をインライン化するかどうかについて正しい選択を行います。

この自動インライン化プロセスは、関数を作成するための追加コストがまったくないことを意味します(まったく)。

これは、コードをできるだけきれいに整理して作成する必要があることを意味し、コンパイラーがこれらの最適化を行う可能性があります。問題を解決するための全体的な戦略が、関数呼び出しのパフォーマンスを心配するよりも最も効率的であることがより重要です。

于 2010-07-09T16:47:09.130 に答える
2

コードをできるだけ単純で構造化された方法で記述し、コードを記述してテストしたら、プロファイルを作成して、最適化が必要なホットスポットがあるかどうかを確認できます。その時点でのみ、マイクロ最適化に関心を持つ必要があります。コンパイラーがその仕事をしている場合は、これは必要ないかもしれません。

于 2010-07-09T16:36:48.407 に答える
1

私は午前中、CとFortranが混在するアプリのチューニングに費やしました。もちろん、多くの機能を使用しています。私が見つけた(そして私が通常見つけた)のは、関数が遅いということではありませんが、特定の関数呼び出し(およびそれらのごく一部)は実際にはまったく実行する必要がないということです。たとえば、メモリブロックをクリアするのは、きちんと整理するためですが、高頻度で実行します。

これは言語の機能ではなく、実際にはインライン化の機能でもありません。関数呼び出しは無料である可能性がありますが、それでも呼び出しツリーが必要以上にふさふさする傾向があるという問題があります。あなたはそれを剪定する場所を見つける必要があります。これは私が頼りにしている「プロファイリング」方法です。

何をするにしても、何を修正する必要があるかを見つけてください。推測しないでください。多くの人はこの種の質問を推測とは考えていませんが、「これはうまくいくでしょうか、それは役に立ちますか?」と自問するとき、彼らは問題がどこにあるかを見つけるのではなく、暗闇の中で突っついています。問題がどこにあるかがわかれば、修正は明らかです。

于 2010-07-09T18:52:53.253 に答える
0

通常、Fortranでのサブルーチン/関数呼び出しのオーバーヘッドはほとんどありません。言語標準では引数の受け渡しメカニズムは指定されていませんが、一般的な実装は「参照による」ため、コピーは必要なく、新しいプロシージャを設定するだけです。ほとんどの最新のアーキテクチャでは、これにはほとんどオーバーヘッドがありません。一般に、適切なアルゴリズムを選択することは、マイクロ最適化よりもはるかに重要です。

クイック呼び出しの例外は、コンパイラが一時配列を作成する必要がある場合です。たとえば、実際の引数が非連続配列サブセクションであり、呼び出されたプロシージャ引数が単純な連続配列である場合です。ダミー引数が次元(:)であると仮定します。次元の配列(:)で呼び出すのは簡単です。呼び出しで非ユニットストライド(配列(1:12:3)など)を要求した場合、配列は連続しておらず、コンパイラーは一時的なコピーを作成する必要がある場合があります。実際の引数が次元(:、:)であると仮定します。呼び出しに配列(:、j)がある場合、Fortranでは最初のインデックスがメモリ内で最も速く変化し、コピーを必要としないため、サブ配列は連続しています。ただし、配列(i、:)は連続しておらず、一時的なコピーが必要になる場合があります。

一部のコンパイラには、必要に応じてコードを変更できるように、一時的な配列コピーが必要になったときに警告するオプションがあります。

于 2010-07-09T17:22:07.763 に答える