コードプロファイラーはどのように機能しますか?

StackOverflow https://stackoverflow.com/questions/460698

  •  19-08-2019
  •  | 
  •  

質問

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

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

ありがとう。

役に立ちましたか?

解決

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

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

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

他のプロファイラーでは、プログラムを再コンパイルして命令を挿入し( instrumentation として知られています)、命令の連続セット(基本ブロック)が実行される頻度をカウントするか、基本ブロックのシーケンスを記録することも含まれます実行されるか、特定の場所で変数の内容を記録します。

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

他のヒント

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

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

サンプリングは、すべてのスレッドに対してスタックトレースがどのように見えるかを定期的にVMに尋ね、その方法で統計を更新します。これは通常、パフォーマンスへの影響は少なくなりますが、コールカウントの精度は低下します。

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

Jon Skeetが上で書いたように、計装とサンプリングの2つの戦略があります。

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

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

計測とサンプリングの両方の方法には、独自のオーバーヘッドがあります。オーバーヘッドの量は依存します-例えばサンプリング頻度が高い値に設定されている場合、プロファイリング自体が報告されるパフォーマンスに大きく寄与する可能性があります。

計測とサンプリング: 一方が他方のアプローチより優れているというわけではありません。どちらにもそれぞれの場所があります。

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

上記から、詰まっているリソースを特定します。

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top