web-dev-qa-db-ja.com

最適化をオフにしても有効なプロファイリング結果が得られますか?

アプリケーションのプロファイルにperfを使用しています。結果のコールグラフの解釈を容易にするために、コールグラフで簡単に検索できるmaptable_appendRangeのようにlabel functionsを使用してコアループを分割しました。残念ながら、これらの関数はほとんどがオプティマイザによってインライン化されているため、コールグラフには表示されません。

これを修正するために、最適化なしでコンパイルできます(-O0)。すべてが正常で、label functionsを使用したプロファイリングは至福です。一方、最適化はコードの全体的なパフォーマンスに大きな影響を与えるため、最適化なしのプロファイリングが実際のパフォーマンスを表すかどうかはわかりません。

だからここに私の質問があります:最適化されていないコードをプロファイリングするときに代表的な結果を期待できますか?

7
Johannes Luong

あなたはプロファイリングしている理由を尋ねる必要があります。

  1. 一般的なパフォーマンス測定値を取得します。

  2. コードをさらに高速化する方法を見つける。

答えが1の場合は、最適化されたコードでプロファイラーを実行してください。

答えが2の場合は、しないでください。これが理由です。スピードアップには、実行可能なものと、コンパイラーが実行可能なものの2種類があります。

コンパイラーは、メモリー割り当ての最小化、繰り返し引数で呼び出される関数のメモ化、無害に見えるライブラリー呼び出しが簡単なI/Oを何度も行わないようにするなど、実行できる高速化を検出または修正できません。

オプティマイザによって明らかになる、修正可能な速度のバグはありません。

それができることは、コードをスクランブルする、ランダムにインライン化する、スタックフレームを取り除くなどして、それらを見つけにくくすることです。
そして、それが実際にできる唯一の改善は、それがyourにある場合にのみ、コールスタックの一番下にあることを覚えておいてくださいコード。スタックの上位にあるものはすべて、最小限/無視できるほどの利点です。

一部の人々が使用する戦略は this であり、それが機能する統計上の理由は こちら 。オプティマイザーなしでコードを大幅に高速化するのに十分な処理を行った後、オプティマイザーをオンにします

7
Mike Dunlavey

プロファイリング結果を意味のあるものにしたい場合は、 本番環境で使用する予定の最適化フラグを使用してください

つまり、ほとんどのコンパイラーに特定の関数をインライン化しないように指示できます。たとえば、gccを使用する場合、ラベル関数を __attribute__((noinline)) でマークできます。

__attribute__((noinline)) int func()
{
    ...
}

(他のコンパイラーは通常、同様の拡張機能を提供します。)これにより、最適化が有効な場合でも、ラベル関数がプロファイルに表示されるようになります。この属性はgcc固有であるため、プロファイリングが完了したら削除するか、別のコンパイラーが使用されている場合は何も評価されないマクロでラップしてください。

もちろん、これらの特定の関数のインライン化が実際にパフォーマンスに大きな影響を与える場合、プロファイリング結果はまだ完全に代表的ではない可能性があります。

8
nomadictype