25

私が大学のプロジェクトに取り組んでいる間、年長の学生が作成したプロジェクト内部のプロファイラーを使用しました。これは非常に基本的でしたが、コードの 2 つのポイント間の時間を減算して統計を与えることであったため、十分に優れていました。

では、プロのプロファイラーはどのように機能するのでしょうか? コードを前処理して、チェックポイントなどを挿入しますか? 関数が呼び出された場所をキャッチするために、デバッグ データを含むバイナリ コードを読み取りますか?

ありがとう。

4

5 に答える 5

29

さまざまな方法で機能するさまざまなプロファイラーがたくさんあります。

一般的に使用されるプロファイラーは、実行中のプログラムを定期的に調べて、現在実行されているアセンブリ命令 (プログラム カウンター) と現在の関数を呼び出したルーチン (コール スタック) を確認します。この種のサンプリングプロファイラーは、標準のバイナリで動作しますが、プログラム内のアドレスが指定されたコード行を解決するためのデバッグ シンボルがある場合により便利です。

定期的にサンプリングするだけでなく、プロセッサ パフォーマンス カウンターを使用して、キャッシュ ミスなどの一定回数のイベント後にサンプリングすることもできます。これにより、メモリ アクセスが原因でプログラムのどの部分が遅くなっているのかを確認するのに役立ちます。

他のプロファイラーでは、プログラムを再コンパイルして命令を挿入し (インストルメンテーションと呼ばれます)、連続する命令セット (基本ブロック) が実行される頻度をカウントしたり、基本ブロックが実行された順序を記録したり、変数の内容を記録したりすることさえあります。特定の場所。

インストルメンテーション アプローチは、必要なすべての精度とデータを提供できますが、プログラムの速度が低下し、パフォーマンス特性が変化します。対照的に、サンプリング ベースのアプローチでは、取得したプロファイル データの精度に対して、プログラムの実行に必要な時間の長さに対するパフォーマンスへの影響を調整できます。

于 2009-01-20T10:25:16.830 に答える
16

2 つの一般的なプロファイリング戦略があります (とにかく VM ベースの言語の場合): インストルメンテーションとサンプリングです。

インストルメンテーションはチェックポイントを挿入し、メソッドが開始および終了するたびにプロファイラーに通知します。これは、JIT/インタープリターによって、または実行可能ファイルを変更するだけの通常コンパイル後の実行前フェーズによって行うことができます。これは、パフォーマンスに非常に大きな影響を与える可能性があります (したがって、タイミング結果が歪められます)。ただし、正確なカウントを取得するには適しています。

サンプリングは、すべてのスレッドのスタック トレースがどのように見えるかを定期的に VM に問い合わせ、その統計を更新します。これは通常、パフォーマンスへの影響は少なくなりますが、呼び出しカウントの精度は低くなります。

于 2009-01-20T10:19:51.163 に答える
3

Jon Skeet が上で書いたように、インストルメンテーションとサンプリングの 2 つの戦略があります。

インストルメンテーションは、手動と自動の両方で行われます。手動の場合: 開発者はコードを手動で挿入して、対象のコード領域の開始/終了を追跡します。たとえば、単純な「StartTimer」と「EndTimer」。一部のプロファイラー ツールは、これを自動的に行うこともできます。そのために、プロファイラーはコードの静的分析を行う必要があります。つまり、コードを解析し、特定のメソッドの開始/終了などの重要なチェックポイントを識別します。これは、リフレクションをサポートする言語 (.net 言語など) で最も簡単です。「リフレクション」を使用すると、プロファイラーはソース コード ツリー全体を (コール グラフと共に) 再構築できます。

プロファイラーによってサンプリングが行われ、バイナリ コードが調べられます。プロファイラーは、プロファイリングを目的として、フックやトラップ Windows イベント/メッセージなどの手法も使用できます。

インストルメンテーションとサンプリングの両方の方法には、独自のオーバーヘッドがあります。オーバーヘッドの量は依存します。たとえば、サンプリング周波数が高い値に設定されている場合、プロファイリング自体がレポートされるパフォーマンスに大きく影響する可能性があります。

インストルメンテーションとサンプリング: 一方が他方よりも優れているというわけではありません。どちらにもそれぞれの場所があります。

最良のアプローチは、サンプリング ベースのプロファイラーから始めて、システム レベル全体を調べることです。つまり、サンプラーを実行して、システム全体のリソースの使用状況 (メモリ、ハードディスク、ネットワーク、CPU) を確認します。

上記から、チョークされているリソースを特定します。

上記の情報を使用して、コードにインストルメンテーションを追加して、犯人を特定できるようになりました。たとえば、メモリが最も使用されるリソースである場合、メモリ割り当て関連のコードをインストルメント化するのに役立ちます。インストルメンテーションでは、コードの特定の領域に集中していることに注意してください。

于 2009-01-20T10:38:45.290 に答える
2

これは、分析されるコードの種類によって異なります。たとえば、.NET CLR はコード プロファイラーの機能を提供します。マネージド コードを扱う場合、中間コードを書き直してカスタム フックを挿入することができます。また、アプリケーションのスタック トレースを分析することもできます。オペレーティング システムはプロファイリングの手段を提供できます。たとえば、Windows にはパフォーマンス カウンターがあります。組み込みコードを扱う場合、基礎となるハードウェアをエミュレート/代用して、システム パフォーマンスを効果的に監視できます。

于 2009-01-20T10:18:30.493 に答える
0

*nix の gprof では、-pg を使用してコンパイルおよびリンクするときに、オブジェクト コードに追加のコードが挿入されます。次に、gprof を実行すると、挿入されたコードによってレポート ファイルが生成されます。

于 2009-01-20T10:24:00.140 に答える