同時実行ビジュアライザーのスレッド ビュー

スレッド ビューは、同時実行ビジュアライザーの最も詳細かつ機能豊富なビューです。 スレッド ビューでは、実行セグメント中にコードを実行しているスレッドを特定したり、スレッドが実行されているのか、それとも同期、I/O、その他の理由からブロックされているのか分析したりできます。 スレッド ビューのレポートではまた、呼び出し履歴ツリーの実行やブロック解除スレッドがプロファイルされます。

スレッドの実行中、同時実行ビジュアライザーによってサンプルが収集されます。 スレッドの実行が停止すると、ビジュアライザーによって、そのスレッドに対するオペレーティング システムのコンテキスト スイッチ イベントがすべて調べられます。 コンテキスト スイッチが発生する理由:

  • 同期プリミティブでスレッドがブロックされた。
  • スレッドのクォンタムの期限が切れた。
  • スレッドがブロックの原因となる I/O 要求を実行した。

同時実行ビジュアライザーでは、スレッドとコンテキスト スイッチ イベントが分類され、スレッドの呼び出し履歴から既知のブロッキング API が検索されます。 スレッド ビューの左下にあるアクティブな凡例にスレッド カテゴリが表示されます。 多くの場合、コンテキストの切り替えイベントに対応する呼び出し履歴を調べることにより、ブロック イベントの根本原因を識別できます。

呼び出し履歴に一致するものがない場合、同時実行ビジュアライザーでは、Windows によって提供される待機理由が使用されます。 ただし、Windows のカテゴリは実装の詳細に基づく場合があり、ユーザーの意図を反映しない可能性があります。 たとえば、Windows では、ネイティブのスリム リーダー/ ライター ロックでのブロックの待機理由が、同期ではなく I/O として報告されます。

スレッド ビューでは、スレッド間の依存関係も示します。 たとえば、同期オブジェクトでブロックされているスレッドを特定した場合、そのブロックを解除したスレッドを見つけることができます。 他方のブロックを解除した時点で、呼び出し履歴からブロック解除スレッドを調べることができます。

スレッド ビューは次の目的で使用できます。

  • アプリのユーザー インターフェイス (UI) が特定の実行フェーズ中に応答しない理由を特定します。
  • 同期、I/O、ページ フォールト、その他のイベントでのブロックに費やされた時間を決定します。
  • システム上で実行される他のプロセスからの干渉の程度を明らかにします。
  • 並列実行に関する負荷分散の問題を識別します。
  • 最適な拡張性が得られない、あるいは拡張性がまったくない理由を見つけます。 たとえば、論理コアを追加できるときに、並列アプリのパフォーマンスが改善されない理由です。
  • アプリケーションでのコンカレンシーの程度を理解し、並列処理に役立てることができます。
  • ワーカー スレッドと実行のクリティカル パスの間の依存関係を特定します。

スレッド ビューを使用する

同時実行ビジュアライザーを開始するには、[分析][同時実行ビジュアライザー] の順に選択し、[Launch New Process]\(新しいプロセスの起動\) など、オプションを選択します。

同時実行ビジュアライザーによってアプリが開始され、[コレクションの停止] を選択するまでトレースが収集されます。 次に、ビジュアライザーによってトレースが分析され、トレース レポート ページに結果が表示されます。

レポートの左上にある [スレッド] タブを選択し、[スレッド] ビューを開きます。

Threads view

時間とスレッドを選択し、パフォーマンス分析を開始します。

タイムライン分析

スレッド ビューの上部はタイムラインです。 タイムラインは、プロセス内のすべてのスレッドのアクティビティと、ホスト コンピューター上のすべての物理ディスク デバイスを示します。 GPU アクティビティとマーカー イベントも表示されます。

タイムラインでは、x 軸は時間を示し、y 軸は次のようないくつかのチャネルを示します。

  • システム上のディスク ドライブごとに 2 つの I/O チャネル。1 つのチャネルは読み取り用で、もう 1 つは書き込み用です。
  • プロセス内の各スレッドのチャネル。
  • マーカー チャネル (トレースにマーカー イベントがある場合)。 マーカー チャネルは、それらのイベントを生成したスレッド チャネルの下に最初に表示されます。
  • GPU チャネル。

最初にスレッドは、メイン アプリ スレッドが先頭になるように、作成された順に並べられます。 [実行] など、別の基準でスレッドを並べ替えるには、[ファイルの並べ替え] ドロップダウンで別のオプションを選択します。

タイムラインの色は特定の時点でのスレッドの状態を示します。 緑のセグメントは実行されているもの、赤いセグメントは同期のためにブロックされているもの、黄色のセグメントは優先処理によりブロックされているもの、紫色のセグメントはデバイスの I/O で占有されていているものです。

拡大してさらに詳細な情報を表示したり、縮小して表示する時間間隔を長くしたりできます。 カテゴリ、開始時刻、遅延時間、呼び出し履歴の状態に関する詳細を表示するには、グラフ上でセグメントやポイントを選択します。

タイムラインを使用し、並列ループまたは同時実行タスクに関係しているスレッド間の作業負荷バランスを調べます。 あるスレッドが他のスレッドよりも完了に長い時間がかかっている場合、作業負荷がアンバランスになっている可能性があります。 スレッド間で作業負荷を均等に分散すると、プログラムのパフォーマンスが向上することがあります。

ある時点で実行中のスレッドが 1 つしかない場合、アプリケーションがシステム上のコンカレンシーを十分に活用できていない可能性があります。 タイムラインのグラフを使用して、スレッド間の依存関係や、ブロックの原因となっているスレッドとブロックされるスレッドとのテンポラルな関係を確認できます。 スレッドを再配置するには、スレッドを選択してから、ツール バーで上矢印または下矢印アイコンを選択します。

使われていないスレッドや、統計が無関係で、レポートの邪魔になるために完全にブロックされているスレッドは、非表示にできます。 スレッドは、その名前を選択し、ツール バーで [選択したスレッドを非表示にします] アイコンか [選択したスレッド以外をすべて非表示にします] アイコンを選択するという手順で非表示にします。 非表示にするスレッドを確認するには、左下にある [スレッド別の概要] を選択します。 [スレッド別の概要] グラフでアクティビティのないスレッドを非表示にできます。

スレッド実行の詳細

実行セグメントに関する詳細な情報を取得するには、タイムラインの緑セグメント上にあるポイントを選択します。 同時実行ビジュアライザーによって、選択したポイントの上に黒のキャレットが表示され、一番下のウィンドウの [現在] タブにその呼び出し履歴が表示されます。 実行セグメント上の複数のポイントを選択できます。

Note

セグメントの継続時間が 1 ミリ秒未満の場合、同時実行ビジュアライザーは実行セグメント上の選択を解決できないことがあります。

現在選択されている時間の範囲内で隠されていないすべてのスレッドの実行プロファイルを取得するには、左下にある凡例で [実行] を選択します。

スレッドのブロックの詳細

スレッドの特定の領域に関する情報を取得するには、タイムライン上でその領域の上にマウス カーソルを置き、ヒントを表示します。 ヒントには、カテゴリ、開始時刻、遅延などの情報が含まれます。 領域を選択すると、一番下のウィンドウの [現在] タブにその時点での呼び出し履歴が表示されます。 このウィンドウにはカテゴリと遅延も表示され、ブロック API やブロック解除スレッドが存在する場合、それも表示されます。 呼び出し履歴を確認することにより、スレッドをブロックするイベントの根本原因を確認できます。

実行パスには、いくつかのブロック イベントが含まれることがあります。 こうしたイベントをブロック カテゴリごとに調べ、問題のある領域をより迅速に見つけるには、左側の凡例でブロック カテゴリを選択します。

スレッド間の依存関係

同時実行ビジュアライザーでは、スレッド間の依存関係を確認できます。ブロックされたスレッドが何を実行しようとしていたかや、他のどのスレッドがその実行を可能にしたかを判断できます。

どのスレッドが別のスレッドをブロック解除したのかを確認するには、タイムライン上でブロック セグメントを選択します。 コンカレンシー ビジュアライザーがブロック解除スレッドを判断できた場合、ブロック解除スレッドと、ブロック セグメントに続く実行セグメントが、線で結ばれます。 一番下のウィンドウで [ブロック解除スタック] タブを選択すると、関連する呼び出し履歴が表示されます。

プロファイル レポート

タイムライン グラフの下のウィンドウには、[プロファイル レポート][現在][ブロック解除スタック] というレポート タブがあります。 タイムラインやスレッドの選択を変更すると、レポートが自動的に更新されます。 大規模なトレースの場合、更新が計算されている間はレポート ウィンドウを一時的に利用できないことがあります。

[プロファイル レポート] タブ

[プロファイル レポート] にはフィルターが 2 つあります。

  • ほとんど時間が費やされていないコール ツリーのエントリをフィルターで除外するには、[不要項目の非表示] フィールドに 0 から 99% のフィルター値を入力します。 既定値は 2% です。
  • 自分のコードのみを対象にコール ツリーを表示するには、[マイ コードのみ] チェック ボックスをオンにします。 すべてのコール ツリーを表示するには、このチェックボックスをオフにします。

[プロファイル レポート] タブでは、凡例にカテゴリとリンクのレポートが表示されます。 レポートを表示するには、左側でエントリを 1 つ選択します。

  • 実行実行レポートは、アプリケーションが実行に費やした時間の内訳を示します。

    実行時間が費やされたコード行を検索するには、コール ツリーを展開し、コール ツリー エントリのショートカット メニューで、[ソースの表示] または [呼び出しサイトの表示] を選択します。 [ソースの表示] では、実行されたコード行を検索します。 [呼び出しサイトの表示] では、実行された行を呼び出したコード行を検索します。 呼び出しサイト行が 1 つしか存在しない場合は、そのコードが強調表示されます。 呼び出しサイトが複数存在する場合、ダイアログ ボックスで 1 つ選択し、[ソースに移動] を選択します。 多くの場合、インスタンスが最も多い、または最も多くの時間を費やしている、あるいはそれら両方に当てはまる呼び出しサイト検索することが役立ちます。 詳細については、「実行プロファイル レポート」を参照してください。

  • 同期同期レポートは、同期ブロックの原因となっている呼び出しと、各呼び出し履歴のブロック時間の総計を示します。 詳細については、「同期時間」を参照してください。

  • I/OI/O レポートは、I/O ブロックの原因となっている呼び出しと、各呼び出し履歴のブロック時間の総計を示します。 詳細については、「I/O 時間 (スレッド ビュー)」を参照してください。

  • スリープスリープ レポートは、スリープ ブロックの原因となっている呼び出しと、各呼び出し履歴のブロック時間の総計を示します。 詳細については、「スリープ時間」を参照してください。

  • メモリ管理メモリ管理レポートは、メモリ管理ブロックが発生した呼び出しと、各呼び出し履歴のブロック時間の総計を示します。 この情報を使用し、過剰なページングやガベージ コレクションの問題がある領域を特定します。 詳細については、「メモリ管理時間」を参照してください。

  • 優先優先レポートは、システム上のプロセスが現在のプロセスよりも優先処理された箇所と、現在のプロセス内のスレッドに取って代わった個々のスレッドを示します。 この情報を使用して、優先処理の主な原因となったプロセスとスレッドを特定できます。 詳細については、「優先時間」を参照してください。

  • UI 処理UI 処理レポートは、UI 処理ブロックの原因となっている呼び出しと、各呼び出し履歴のブロック時間の総計を示します。 詳細については、「UI 処理時間」を参照してください。

  • スレッド別の概要[スレッド別の概要] を選択すると、現在選択されている時間間隔を対象に、スレッドの状態を示すグラフが表示されます。 色分けされた列によって、各スレッドが実行、ブロック、I/O、その他の状態にあった時間の総計が示されます。 スレッドの下部にラベルが付けられます。 タイムライン グラフでズーム レベルを調整すると、このグラフは自動的に更新されます。

    ズーム レベルによっては、一部のスレッドがグラフに表示されないことがあります。 その場合、省略記号 (...) が右側に表示されます。 必要なスレッドが表示されない場合は、他のスレッドを非表示にすることができます。 詳細については、「スレッド別の概要レポート」を参照してください。

  • ディスク操作[ディスク操作] を選択すると、現在のプロセスにおいてディスク I/O に関係するプロセスとスレッド、それらが接触したファイル (読み込んだ DLL など)、読み込んだバイト数などの情報が表示されます。 このレポートを使用し、実行中にファイルへのアクセスに費やされる時間を評価できます (特に、I/O バウンドなプロセスと思われる場合に役立ちます)。 詳細については、「ディスク操作レポート」を参照してください。

現在のタブ

このタブでは、タイムライン グラフ内のスレッド セグメントについて、選択した時点の呼び出し履歴が表示されます。 自分のアプリに関連のあるアクティビティだけが表示されるように、呼び出し履歴は縮小表示されます。

[ブロック解除スタック] タブ

このタブには、選択したスレッドのブロックを解除したスレッドとブロック解除呼び出し履歴が表示されます。

チャネル (スレッド ビュー)

コンカレンシー ビジュアライザーに、スレッド チャネル、ディスク チャネル、マーカー チャネル、GPU チャネルという 4 種類のチャネルが表示されます。

スレッド チャネル

スレッド チャネルには、1 つのスレッドのスレッドの状態が色分けして表示されます。 チャネル名を一時停止すると、特定のスレッドの start 関数が表示されます。 コンカレンシー ビジュアライザーは、いくつかの種類のスレッドを検出します。 次の表は、最も一般的な種類を示しています。

スレッド 説明
メイン スレッド: アプリで開始されたスレッド。
ワーカー スレッド アプリケーションのメイン スレッドにより作成されたスレッド。
CLR ワーカー スレッド 共通言語ランタイム (CLR) によって作成されたワーカー スレッド。
デバッガー ヘルパー Visual Studio デバッガーによって作成されたワーカー スレッド。
ConcRT スレッド Microsoft のコンカレンシー ランタイムによって作成されたスレッド。
GDI スレッド GDIPlus によって作成されたスレッド。
OLE/RPC スレッド RPC ワーカー スレッドとして作成されたスレッド。
RPC スレッド RPC スレッドとして作成されたスレッド。
WinSock スレッド Winsock スレッドとして作成されたスレッド。
スレッド プール CLR スレッド プールによって作成されたスレッド。

ディスク チャネル

ディスクのチャネルは、コンピューターの物理ドライブに対応します。 システム上の物理ドライブごとに読み取りおよび書き込み操作用の個別のチャネルがあるため、各ドライブには、2 つのチャネルがあります。 ディスク番号は、カーネルのデバイス名に対応します。 ディスク チャネルは、ディスクのアクティビティがあった場合にのみ表示されます。

マーカー チャネル

マーカー チャネルは、アプリおよびそれが使用するライブラリによって生成されたイベントに対応します。 たとえば、タスク並列ライブラリ、並列パターン ライブラリ、および C++ AMP は、マーカーとして表示されているイベントを生成します。 各マーカー チャネルは、チャネルの説明の横に表示されるスレッド ID に関連付けられます。 ID は、イベントを生成したスレッドを識別します。 チャネルの説明には、イベントを生成した Event Tracing for Windows (ETW) プロバイダーの名前が含まれています。 チャネルが、コンカレンシー ビジュアライザー SDK からのイベントを表示する場合、系列名も表示されます。

GPU チャネル

GPU チャネルは、システム上の DirectX 11 の活動に関する情報を表示します。 グラフィックス カードに関連付けられている各 DirectX エンジンに個別のチャネルがあります。 個々のセグメントは、DMA パケットの処理に費やした時間を表します。

選択範囲のコピー

レポート タブから呼び出し履歴全体をコピーするには、[コピー] をクリックします。 その後、貼り付けをサポートする任意のプログラムに呼び出し履歴を貼り付けることができます。

現在のタブ

現在のタブをクリックすると、CPU スレッド セグメントが選択されている場合、現在の選択ポイントに最も近い呼び出し履歴 (利用できる場合) が表示されます。 その場合、選択ポイントはタイムラインの上に黒い矢印またはキャレットで表示されます。 ブロッキング セグメントが選択されているとき、実行がないため、キャレットは表示されません。 しかしながら、セグメントは強調表示され、呼び出し履歴が表示されます。

現在タブには、DirectX アクティビティ セグメント、マーカー、I/O アクセスに関する情報も表示されます。 DirectX アクティビティの場合、DMA パケットがハードウェア キューにより処理される方法に関する情報が表示されます。 マーカーの場合、説明とマーカーの種類に関する情報が表示されます。 I/O アクセスの場合、ファイルと読み込まれた (または書き込まれた) バイトの数に関する情報が表示されます。

空のタイムライン セグメント

コンカレンシー ビジュアライザーでは、タイムラインのセクションが空になる (白の背景を持つ) の理由は、チャネルの種類によって異なります。

  • CPU スレッド チャネルの場合は、タイムラインのこの部分の間にスレッドが存在しなかったことを意味します。 スレッドについて知りたい場合は、ズーム コントロールまたは水平スクロールを使って、実行セクションを見つけることができます。

  • I/O チャネルの場合は、その時点でターゲット プロセスに対するディスク アクセスが発生しなかったこと意味します。

  • DirectX チャネルの場合は、タイムラインのこの部分の間にターゲット プロセスに対する GPU 処理が実行されなかったことを意味します。

  • マーカー チャネルの場合は、マーカーが生成されなかったことを意味します。

[エクスポート] ボタン (コンカレンシー ビジュアライザー)

[エクスポート] ボタンでは、独自のレコードのためや、Microsoft Excel など、別のツールで使用するために、.csv ファイルとして呼び出し履歴をエクスポートできます。

[マイ コードのみ] (スレッド ビュー)

このオプションを選択すると、呼び出し履歴がフィルター処理され、自分のコードに加え、呼び出された関数が 1 レベルだけ表示されます。

このオプションを有効にすると、呼び出し履歴が大幅に簡素化され、特定の問題の診断が簡単になります。

このオプションを選択すると、ブロック呼び出しがフィルターで除外されることがあります。 決定に詳細な呼び出し履歴が必要になる場合、このオプションの選択を解除し、呼び出し履歴をすべて公開してください。

チャネルの管理

コンカレンシー ビジュアライザーのスレッド ビューでは、プロセスのチャネルを整理して、特定のパターンを調べることができます。 チャネルを並べ替えしたり、上下に移動したり、非表示/表示を切り替えることができます。

並べ替え順

[並べ替え] コントロールを使用して、現在のズーム レベルに基づいて、異なる基準でスレッドを並べ替えることができます。 これは、特定のパターンを探しているときに特に便利です。 次のような条件で並べ替えることができます。

基準 定義
開始時間 開始時刻でスレッドを並べ替えます。 これが既定の並べ替え順序です。
終了時間 終了時刻でスレッドを並べ替えます。
実行 実行に費やした時間の割合でスレッドを並べ替えます。
同期 同期に費やした時間の割合でスレッドを並べ替えます。
I/O 入出力 (データの読み取りと書き込み) に費やした時間の割合でスレッドを並べ替えます。
Sleep スリープに費やした時間の割合でスレッドを並べ替えます。
ページ分割 ページングに費やした時間の割合でスレッドを並べ替えます。
優先 優先処理に費やした時間の割合でスレッドを並べ替えます。
UI 処理 ユーザー インターフェイス処理に費やした時間の割合でスレッドを並べ替えます。

選択したチャネルを上下に移動

これらのコントロールを使用して、一覧でチャネルを上または下に移動できます。 たとえば、関連するチャネルを隣同士に配置すると、特定のパターンまたはスレッド間の関係を確認する助けになります。

選択したチャネルを一番上または一番下に移動

選択したチャネルを一覧の一番上または一番下に移動することにより、特定のパターンを確認することができ、他のチャネルを確認できたときに一部のチャネルを除外することができます。

選択したチャネルを非表示にする

チャネルを非表示にするには、このコントロールを選択します。 たとえば、あるスレッドがマネージド プロセスの有効期間中に 100% の同期を示している場合は、他のスレッドを分析するときにはそれを非表示にすることができます。

Note

スレッドを非表示にすると、アクティブな凡例およびプロファイル レポートに示される計算時間からも除外されます。

すべてのチャネルを表示

1 つまたは複数のチャネルが表示されていないときに、このコントロールはアクティブになります。 これを選択すると、すべての非表示の要素が表示され、時間の計算に再び含められます。

マーカーを先頭へ移動

トレースにマーカー イベントが含まれている場合は、このコマンドを使用して、マーカーのチャネルをタイムラインの先頭に移動することができます。 それらの相対順序は保持されます。

スレッド別にマーカーをグループ化

トレースにマーカー イベントが含まれている場合は、このコマンドを使用して、それらのマーカー イベントを生成したスレッドの下にマーカーのチャネルをグループ化することができます。 ディスクのチャネルはチャネルの一覧の先頭に移動し、GPU チャネルは、一番下に移動します。

測定モード オン/オフ

このツールを使用すると、タイムラインの時間の長さを正確に測定できます。 測定モードを有効にするには、測定ボタン (ルーラー アイコン付き) をクリックし、タイムラインにドラッグします。 ドラッグすると、ポインターの下の領域が黄色で強調表示され、測定された時間は、ボタンの右側にあるツール バーに表示されます。 この値は、ドラッグ時に動的に計算されるため、特定のイベントにかかる時間がすぐにわかります。 マウス ボタンを離しても、時間の値は表示されたままです。

測定プロセスは繰り返せますが、表示されるのは最新のものだけです。 測定ボタンをもう一度クリックし、測定モードをオフにします。

不要項目の非表示の割合

既定では、不要項目の非表示の割合の設定値は 2 です。 この設定値以上の包括時間の割合を持つエントリだけが、コール ツリーに表示されます。 設定を変更することによって、コール ツリーに表示されるエントリの数を制御できます。 たとえば、値を 10 に変更すると、10% 以上の包括時間を持つエントリだけがコール ツリーに表示されます。 この設定値を増やすと、プロセスのパフォーマンスに対する影響が大きいエントリに集中することができます。

表示された時間範囲に基づいたレポート

プロファイル ビューには、現在表示されている時間範囲およびチャンネルに基づいたレポートが表示されます。 データのさまざまなサブセットの詳細を表示するには、凡例内の項目をクリックします。

データについて詳しくは、スレッド ビュー レポートに関する記事を参照してください。

スレッド準備完了コネクタ

ブロッキング セグメントをクリックして呼び出し履歴とそのブロック解除スタックを表示すると、スレッド準備完了コネクタも表示されることがあります。 現在のプロセス内の別のスレッドでブロック解除イベントが発生した場合、そのスレッドとブロックされたスレッドが実行再開できるようにした実行セグメントを、スレッド準備完了コネクタが視覚的に示します。

タイムライン キャレット

実行中のスレッド セグメントのタイムライン上のポイントを選択すると、その上にタイムライン キャレットが表示されます。 現在のスタック タブ上に表示される呼び出し履歴が、セグメントでクリックした場所の時間に最も近い呼び出し履歴になります。 キャレットは、[現在] タブの下に表示される呼び出し履歴を、サンプリングされた瞬間に関連付けるために使用されます。 キャレットはその呼び出し履歴、つまりユーザーが選択した場所に最も近い呼び出し履歴の正確な位置を示します。

ブロック解除スタック

現在選択されているスレッドの要素が、現在のプロセスの別のスレッドによってブロック解除された後に実行を開始するブロック セグメントを表している場合、ブロック解除を行ったスレッドの呼び出し履歴がこのタブに表示されます。

表示されているタイムライン プロファイル

スレッド ブロック ビューの [表示されているランタイム プロファイル] には、統計情報とレポートへのリンクが表示されます。 拡大、縮小、水平方向へのスクロール、またはチャネルの非表示と表示の切り替えを行うと、アクティブな凡例の数値が現在の表示内容に応じて変更されます。 凡例の項目に関するレポートを表示するには、その項目をクリックします。

ズーム コントロール (スレッド ビュー)

ズーム コントロールは、タイムラインの表示を拡大縮小するのに役立つスライダーです。このコントロールを使用して、興味のある領域を集中的に見ることができます。 このコントロールではタイムライン ビューの中央が拡大の中心点になるため、拡大する前に、対象となる領域が中央に置かれるように調整してください。

タイムライン ビュー内でのドラッグによる拡大

タイムライン ビュー内でドラッグして拡大すると、領域が黄色で強調表示されます。 マウス ボタンを離すと、タイムライン ビューの選択した範囲が拡大されます。

マウス ホイールを使用した拡大縮小

タイムライン上の任意の点をクリックし (マウス フォーカスを確実に置くため)、Ctrl キーを押しながらマウス ホイールを移動します (拡大するには前方へ、縮小するには後方へ)。