質問

速度のみを目的とした最適化を試みていることを考えると、関数をインライン化するかどうかを決定するための適切なヒューリスティックは何でしょうか?コード サイズが重要であることは明らかですが、(たとえば) gcc または icc が関数呼び出しをインライン化するかどうかを決定するときに通常使用される他の要素はありますか?この地域で何か重要な学術研究が行われたことがありますか?

役に立ちましたか?

解決

ウィキペディアには ある 少し これに関する段落と、下部にリンクがいくつかあります。

  • メモリ サイズとキャッシュの問題に加えて、 もう1つの考慮事項は見当圧力です. 。コンパイラの観点からは、「インライン化されたプロシージャから追加された変数は追加のレジスタを消費する可能性があり、レジスタ圧力がすでに高い領域ではこれによりスピルが強制され、追加の RAM アクセスが発生する可能性があります。」

JIT コンパイラとランタイム クラスの読み込みを使用する言語には、仮想メソッドが静的に知られていないため、別のトレードオフがありますが、JIT はメソッド呼び出し頻度などのランタイム プロファイリング情報を収集できます。

  • ジャストインタイム コンパイラにおける最適化の設計、実装、評価 (Java の場合) 静的メソッドと動的にロードされるクラスのメソッドのインライン化と、そのパフォーマンスの向上について説明します。

  • 柔道の練習:動的最適化下の Java は、「インライン化ポリシーはコード サイズとプロファイリング情報に基づいている」と主張しています。メソッド エントリの実行頻度が特定のしきい値を下回る場合、そのメソッドはコールド メソッドとみなされ、インライン化されません。コードの爆発を避けるため、バイトコード サイズが 25 バイトを超えるメソッドはインライン化されません。。。。深い呼び出しチェーンに沿ったインライン化を避けるために、呼び出しチェーンに沿って累積されたインライン化バイトコード サイズが 40 バイトを超えると、インライン化が停止します。」 彼らはランタイム プロファイリング情報 (メソッド呼び出し頻度) を持っていますが、それでも大きな関数や関数チェーンのインライン化を避けるように注意しています。むくみを防ぐために。

Google Scholar での検索 などの多くの論文が明らかになりました。

Google ブックスでの検索 さまざまなコンテキストでの関数のインライン化に関する論文や章を含むかなりの数の書籍が公開されています。

  • コンパイラ設計ハンドブック:最適化とマシンコード生成 には、コンパイラ設計における統計的および機械学習のテクニックに関する章があり、さまざまなパラメータを設定し、結果をプロファイリングするためのヒューリスティックが含まれています。この章は Vaswani らの論文を参照しています。 コンパイラ最適化のためのマイクロアーキテクチャに敏感な経験的モデル 彼らが「コンパイラの最適化のためのマイクロアーキテクチャに敏感なモデルを構築するための経験的モデリング手法の使用」を提案します。

  • (他の書籍では、プログラマーの観点から inling について説明しています。 ゲームプログラマーのための C++, では、関数を頻繁にインライン化することの危険性と、インライン化とマクロの違いについて説明します。コンパイラは、プログラマのインライン要求が良いことよりも害を及ぼす可能性が高いと判断できる場合、プログラマのインライン要求を無視することがよくあります。これは最後の手段としてマクロでオーバーライドできます。)

他のヒント

関数呼び出しは、いくつかの追加のコード(新しいスタックフレームが設定されている機能のプロローグと、それがクリーンアップだ関数エピローグ)を意味します。あなたのコンパイラは、関数のコードはプロローグとエピローグに比べて小さいことを見ている場合、それは実際の呼び出しを行うためにそれだけの価値はありません決定することができ、および関数をインラインされます。

唯一、私は関数を呼び出す代わりに、それは大きさに関係しているのインライン化を参照の恩恵を受ける。私は、関数をインライン化、ループをアンロールすると、大きなサイズの増加をもたらすことができますね。

私の知る限りのこぎりを持っているように、関数の大きさは、コンパイラがインラインを決定するのに使用される唯一の要因です。プロファイルに基づく最適化(PGO)を行う場合は、私は、コンパイラはこのような呼び出し/コールセットアップ時間数などの他の変数を、使用することであると考えています。

.NETで

はほとんどサイズに基づいてされています。コンパイルされたバイトに親関数のサイズと子関数を測定します。次いで、合わせた機能の大きさを測定します。複合関数が小さい場合、インライン化は良いアイデアです。

この理由は、可能な限りCPUのキャッシュに多くのコードのように突き出すことを可能にすることです。キャッシュ・ミスは、現代のCPUでの関数呼び出しよりもはるかに高価です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top