コンパイラがインライン化することが合理的に期待できるものは何ですか?

現代のコンパイラが関数をインライン展開するかどうかを評価するために使用できる一般的な規則はありますか?余分なスタックフレームの相対的なコストはどれくらいですか(私はそれが非常に小さいと知っていますが、一般的にそれを数量化する方法はありますか?

私はまた特に興味があります:

  • コンパイラはインラインメソッドをcppで定義できますか?
  • いくつかのコンパイラがデバッグでもいくつかの最適化を実装していることを知っています(VSはデバッグでRVOを使用しますが、NRVOでは使用しません) - インライン化の状況は何ですか?私は、デバッグのために予想されるコールスタックを見ることができるように、それが無効になっていると思います。

私は現在、メモリトラッキングシステムを最適化しようとしています。特に、最適化を有効にしないで(デバッグ時に)適用します。

1
@dmckeeコンパイラの最適化についてはあまりよく分かりませんので、RVO/NRVOを例として使用します。これらのコンパイラはすべての現代コンパイラで実装されており、すぐに時代遅れになることはありません。私は、類似の最適化がたくさんあると仮定します。また、新しいC ++標準が10年に1回しか出現しないときに、非常に短時間で回答が古くなるのは本当にわかりません。
追加された 著者 David,
@ bk1eあなたは正しいです - 誰かが実験を通して自分自身で把握できる情報を入手する理由はありません。
追加された 著者 David,
コンパイラの中には、インライン展開や他のいくつかの最適化にもかかわらず、デバッグ性を保つのに十分なほどスマートなものもあります。私はVisual Studioのコンパイラができないと思っています。
追加された 著者 Hot Licks,
なぜ簡単に測定できるものを予測するのか尋ねるのはなぜですか?コンパイラ(またはリンカ)が関数をインライン化したかどうかを判断するには、デバッガまたは逆アセンブラを使用します。ベンチマークを作成し、両方の方法で試し、結果を比較することで実行時間の差を測定します。
追加された 著者 bk1e,
...コンパイラに依存しています....あなたが得る答えは非常に短時間で日付が付いています。
追加された 著者 dmckee,

1 答え

予測が簡単で予測が難しい。次のような単純な式。

int a = b + (2 * c):
int d = e + (2 * c);

最も単純な最適化で最適化されます((2 * c) "共通部分式"は一度だけ計算されます)。

C/C ++では、インラインで宣言されたメソッドは(一般的ではありませんが)一般的になります。

トリッキーは、ループの最適化などです。例えば、

for (int i = 1; i < n; i++) {
    a = i + (2 * c);
}

式 "(2 * c)は"グローバル最適化 "を行うコンパイラでループから取り除かれますが、"ローカル最適化 "のみを行うコンパイラでは引き出されません。もちろん、表現ははるかに複雑で畳み込まれることがあります。

上記のループの本体を a = i *(2 * c); に変更すると、「ループ誘導」と呼ばれるグローバルな最適化レベルが少し上がります。 "スマートな"コンパイラはループを通じた各反復の a 2 * c を(あらかじめ計算して)追加するだけでなく、(より高価な)各反復。

それは表面を傷つけるだけです。

しかし、私はVisual Studioコンパイラが何ができるのか分かりません。

2
追加された