4

ANSI Cプログラムでは、同じ呼び出しリストと戻り値を持つ10個の関数に対して、いくらかランダムな順序で50〜500回の連続呼び出しが、数千回から最大数百万回行われることになっています。関数呼び出しの実際の数とその実行順序は、起動時のランダムな入力データから決定されますが、実行間隔を通じて変更されることはありません。

switchステートメントまたは関数ポインター配列のどちらが高速であるかについては混乱があるようです。関数呼び出しの初期数とその呼び出しシーケンスは、セットアップ時に最初はランダムですが、プログラムの実行中は一定のままです。この状況で、あるメソッドを他のメソッドよりも優れたものにする機能はありますか?また、コンパイラがこの特殊なケースを認識して、いずれかのメソッドのパフォーマンスを向上させるのに役立つ特定のコンパイラ設定またはディレクティブがありますか?XCodeでGCCコンパイラを使用する。

4

2 に答える 2

3

関数がスイッチに比べて時間がかかる場合は、スイッチを最適化しても問題ありません。測る、測る、測る。

関数がスイッチに比べて短時間しかかからない場合は、配列を介した間接関数呼び出しのほぼ確実なパイプライン ブレークのいずれかを選択できます (CPU はこれらをかなり悪く予測します [ただし、間接ジャンプについてはアセンブリ言語のマニュアルを読んでください])、または(適切にコーディングされている場合) 10 個程度の関数 (3 ~ 4 個の分岐、いずれかがパイプラインの中断を引き起こす) から選択するバイナリ検索。CPU の分岐予測子は、実際の統計に基づいて正しい分岐方向を推測しようとします。一般的なケースでは、誤予測率がゼロになる可能性があります。順序が「ある程度」ランダムである場合は、どの呼び出しが最も頻度が高いかを判断し、選択を最も高い確率関数にバイアスする識別ネットワーク (ハフマン ツリー) を構築し、次に次の関数にバイアスをかけることができます。

関数本体をループ内のスイッチにインライン化すると、うまくいくと思います。正しく実行すると、明示的なパラメーターを渡す必要がなくなり、実行時間を短縮できます。

于 2012-06-03T23:03:54.187 に答える
0

これは、コンパイラ、アーキテクチャ、および場合によっては呼び出しシグネチャによって異なります。これは、ジャストインタイムコンパイルの良いユースケースのように思えます(ソースコードを生成し、それを呼び出してgcc、結果の.soファイル、、を呼び出します)。lddlopendlsym

于 2012-06-03T22:33:01.557 に答える