次の方法で共有


ELT API を使用したプロファイリング

トレース プロファイラーは、関数の開始と終了をログに記録します。また、呼び出し履歴のグラフを作成することもできます。 この機能の実装を支援するために、.NET Framework には、グローバル静的関数のプロファイルが用意されています。この機能には、enter/leave/tailcall (ELT) API と呼ばれる一連の関連する関数およびインターフェイスがあります。

.NET Framework Version 4 より前、ELT 関数を使用するトレース プロファイラーでは、小さいマネージ関数の数が増えるにつれパフォーマンスが低下しました。.NET Framework 4 以降では、ELT Version 3 (ELT3) API を使用して、ELT のパフォーマンスを向上させることができます。これは、引数または戻り値の検査の必要がない場合に特に有効です。 次の点でパフォーマンスが向上します。

  • ELT の高速パス関数では、Just-In-Time (JIT) コンパイル コードのサイズが小さくなります。

  • 必要な引数 ELT の数が最小限になり、プロファイラーに渡すパラメーターに必要なスタック領域が減ります。

  • スタック フレームのセットアップと引数の検査は必要なとき以外行われないので、実行速度が上がります。

  • フレームおよび引数の情報は、新しい ICorProfilerInfo3 メソッドが呼び出されたときに限定的に初期化されます。

ELT3 インターフェイスは、旧バージョンの .NET Framework の ELT インターフェイス (ELT1 および ELT2) と互換性があります。

.NET Framework 4 では、ELT3 上に ELT2 関数を実装しており、追加のハッシュ テーブルを使用してクライアント ID と関数 ID を対応付けます。 そのため、ELT2 関数を使用すると、同期による負荷が大きくなり、プロファイリングの速度が低下します。 高い負荷がかかっているマルチプロセッサ コンピューターでは、パフォーマンスはさらに低下します。ただし、プロファイラーを ELT3 API に移行するために必要なコード変更は簡単で負担も少ないので、最高のパフォーマンスを得るには、ELT3 を採用することをお勧めします。

ELT3 の関数とメソッド

ELT3 API には、次の 3 種類のメンバーが用意されています。

  • 通知関数。対象アプリケーションの関数に制御が渡されていることをプロファイラーに通知するために、CLR によって呼び出されます。

  • 登録メソッド。高速パスまたは低速パスの検査メソッドを有効にするために、プロファイラーによって呼び出されます。

  • 検査メソッド。引数または戻り値の情報を取得するために、プロファイラーによって呼び出されます。

ELT3 通知関数

.NET Framework 4 以降では、6 つの ELT3 通知関数のうち 3 つを使用して、対象アプリケーション (プロファイリングされているアプリケーション) の関数に制御が渡されていることをプロファイラーに通知できます。 ELT3 通知関数は、高速パス関数と低速パス関数で構成されます。

  • 高速パス関数の特性は、JIT コンパイル コードにおいて、中間コードなしにプロファイラーの ELT メソッドを直接呼び出すことです。

  • 低速パス関数の特性は、JIT コンパイル コードにおいて、中間コード (通常は、CLR DLL にコンパイルされるアセンブリ コードと C コードの組み合わせ) を呼び出してから、最終的にプロファイラーの ELT メソッドを呼び出すことです。

次の 3 つの関数は高速パス関数で、必要なパラメーターは 1 つだけです。パラメーターは、制御が渡される、または返される対象となる関数の ID、または tail 呼び出しを実行しようとしている関数の ID です。

次の 3 つの関数は低速パス関数で、必要なパラメーターは 2 つです。パラメーターは、関数 ID と、スタック フレームに関する情報へのハンドルです。

これらの 3 つの関数では、ランタイムからプロファイラーに渡される 2 番目のパラメーター (eltInfo) は、スタックに割り当てられる _COR_PRF_ELT_INFO_INTERNAL 構造体への非透過なポインターです。 この構造体には、ELT アセンブリ ヘルパーによって生成されるプラットフォーム固有のハンドルが含まれます。 プロファイラーでは、ICorProfilerInfo3::GetFunctionEnter3InfoICorProfilerInfo3::GetFunctionLeave3Info、および ICorProfilerInfo3::GetFunctionTailcall3Info の各メソッドで eltInfo ポインターを使用できます。

ELT3 登録メソッド

次の 2 つの ELT3 登録メソッドを使用して、低速パス ELT 関数と高速パス ELT 関数を設定できます。

アプリケーションの起動時、これらのメソッドのどちらかをプロファイラーの ICorProfilerCallback::Initialize コールバックまたは ICorProfilerCallback3::InitializeForAttach コールバックから呼び出す必要があります。 プロファイラーでは、SetEventMask を使用して目的のイベント フラグを登録する必要があります。その後、高速パス ELT3 を有効にするには SetEnterLeaveFunctionHooks3 メソッド、低速パス ELT3 を有効にするには SetEnterLeaveFunctionHooks3WithInfo メソッドを呼び出します。

高速パス ELT3 フックは低速パス ELT3 フックと共には使用できず、ELT3 フックは ELT1 フックまたは ELT2 フックと共には使用できません。 SetEnterLeaveFunctionHooks3 または SetEnterLeaveFunctionHooks3WithInfo を呼び出す前に、低速パスを必要とする適切なイベント フラグ (COR_PRF_ENABLE_FUNCTION_ARGS、COR_PRF_ENABLE_FUNCTION_RETVAL、または COR_PRF_ENABLE_FRAME_INFO) をプロファイラーで指定していない場合、エラーを示す CORPROF_E_INCONSISTENT_WITH_FLAGS エラー コードが返されます。

ELT3 検査メソッド

ELT3 通知関数では引数または戻り値の情報は提供されません。そのため、プロファイラーでは、次の ICorProfilerInfo3 検査メソッドのいずれかを呼び出して、目的の情報を明示的に要求する必要があります。

これらのメソッドは、対応する低速パス ELT3 関数 (FunctionEnter3WithInfoFunctionLeave3WithInfo、および FunctionTailcall3WithInfo) のプロファイラーの実装から呼び出す必要があり、プロファイラーでは、ELT 通知関数から受け取ったものと同じ eltInfo 値を指定する必要があります。 ELT3 検査メソッドは、ELT3 高速パス通知関数 (FunctionEnter3FunctionLeave3FunctionTailcall3) のプロファイラーの実装からも、ELT1 通知関数または ELT2 通知関数のいずれからも、呼び出すことができない点に注意してください。

参照

概念

プロファイリングの概要

その他の技術情報

プロファイル (アンマネージ API リファレンス)

アンマネージ API リファレンス