12

C++ では、特に関数が非常に頻繁に呼び出され、プログラムの実行時間の >= 10% を占める場合 (例: ブルート フォースの評価関数または確率的最適化プロセス)。インライン化は最終的には私の手に負えなくなるかもしれませんが、私はまだ興味があります。

4

6 に答える 6

6

一般的な答えはありません。これは、ハードウェア、引数の数とタイプ、および関数で何が行われるかによって異なります。そして、それがどのくらいの頻度で、どこで呼ばれるか。たとえば、Sparcでは、引数(および戻り値)がレジスタに渡され、各関数は16個の新しいレジスタを取得します。関数が十分に複雑な場合、これらの新しいレジスタは、関数がインライン化された場合に発生するスピルを回避できます。非インラインバージョンは、インラインバージョンよりも速くなる可能性があります。レジスタが貧弱で、レジスタに引数を渡すIntelでは、同じプログラムの同じ関数に対して、正反対のことが当てはまる可能性があります。より一般的には、インライン化によってプログラムのサイズが大きくなり、局所性が低下する可能性があります。または、非常に単純な関数の場合、プログラムのサイズが小さくなる可能性があります。しかし、それもアーキテクチャに依存します。知る唯一の可能な方法は、両方を試すことです。時間を測定します。そしてそれでも、その特定のハードウェア上で、その特定のプログラムについてのみ知ることができます。

于 2011-08-18T13:19:34.797 に答える
1

一部のアーキテクチャでの関数呼び出しと戻りは、それぞれわずか 1 つの命令しか必要としません (ただし、これらは通常、RISC のような単一サイクルの命令ではありません)。一般に、関数の本体で表されるサイクル数と比較できます。 . 単純なプロパティ アクセスは 1 つの命令にすぎない可能性があるため、それをインライン化されていない関数に配置すると、実行する命令の数が 3 倍になります。明らかにインライン化の優れた候補です。一方、印刷用に文字列をフォーマットする関数は数百の命令を表す可能性があるため、さらに 2 つ追加してもまったく違いはありません。

于 2011-08-18T12:52:45.367 に答える
1

インライン化によって節約されるのはすべて、関数の入口/出口コストであるため、関数がほとんど何もしない場合にのみ検討する価値があります。確かに、関数自体に関数呼び出しが含まれている場合は、おそらく考慮する価値はありません。

関数がほとんど実行しない場合でも、関数の高速化が顕著になる前に、かなりの割合の時間、プログラム カウンターを所有するほど多くの関数を呼び出す必要があります。

于 2011-08-18T14:17:42.007 に答える
1

ボトルネックが再帰関数にあり、再帰のレベルが最小ではない (つまり、平均的な再帰が数レベルではない) と仮定すると、インライン化よりも関数内のアルゴリズムを使用する方が適切です。

可能であれば、再帰をループまたは末尾再帰(コンパイラーによって暗黙的にループに変換できる) に変換するか、関数内のどこでコストが費やされているかを判別してみてください。内部操作の影響を最小限に抑えるようにしてください (おそらく、自動保存期間を持つメモリを動的に割り当てているか、一般的な操作をラッパー内の関数の外部で実行し、追加の引数として渡すように因数分解することができます)。 ..)

*再帰が意図されたものではなく、反復であるというコメントの後に編集*

コンパイラが関数の定義にアクセスできる場合、ほとんどの場合、コンパイラは正しい決定を下します。定義にアクセスできない場合は、コードを移動して認識できるようにします。おそらく、関数をstatic関数にして、他の場所では使用されないという追加のヒントを提供するか、(これがインライン化を強制しないことを知って) としてマークすることさえできますが、インライン化を強制inlineする特別な属性の使用は避けてください。コードを見ずに生成できる単純なヒューリスティックよりも優れています。

于 2011-08-18T13:00:09.137 に答える
0

計算集約型の C++ を 20 年以上書いてきた私たちの経験から、インライン化は特効薬ではありません。インライン化によってパフォーマンスが向上するかどうかを確認するには、コードをプロファイリングする必要があります。低レベルの 2D および 3D の点とベクトルの操作を除いて、インライン化は時間の無駄です。クロックティックを細かく管理しようとするよりも、より優れたアルゴリズムを開発する方がはるかに優れています。

于 2011-08-18T13:44:35.057 に答える
0

ここでの動作は、多少コンパイラに依存します。再帰関数を使用すると、明らかにインライン化の動作は理論上無限になる可能性があります。「インライン」キーワードは、コンパイラへのヒントにすぎません。コンパイラは、それで何もできない場合、無視することを選択できます。一部のコンパイラは、再帰関数を特定の深さまでインライン化します。

「これによりどれだけ速度が上がるか」については、残念ながら、「依存する」ため、その質問に対する答えを提供することはできません。テストを設定して見てみませんか?

于 2011-08-18T12:53:24.093 に答える