カスタマーサポートでPerfViewを使用する



サポートチームのユーザーからのリクエストを処理する段階の1つは、問題を再現することです。 再生の難しさはさまざまな理由で発生します。ユーザーは、不適切なコード動作を表示するアプリケーションの例を常に提供できるとは限りません。または、問題は特定の環境に固有のものである可能性があります。 現在、膨大な数のソフトウェア、ハードウェア構成、仮想環境が使用されており、これらのコンポーネントで作成されたプログラムが動作します。 ピクセル単位の画面の幅は5倍(800から4kまで)異なります。 また、構成は、メモリサイズ、ディスプレイの数、DPI、セキュリティ設定、ビデオカードとそのドライバーなど、他のパラメーターが異なる場合があります。 この多様性により、特定の構成に固有の顧客からのアプリケーションの安定したフローが提供されます。 たとえば、問題は特定のバージョンのWindows、特定のDPI設定、またはユーザーに3つのモニターがある場合にのみ再現されます。 この問題を解決するために、弊社のサポートチームは数年間Microsoft PerfViewユーティリティを使用しています 。 問題を再現する他のすべての方法が使い果たされた場合、トレースを開始し、結果のファイルを送信する方法に関する簡単な指示をユーザーに提供します。 トレース情報は、問題の原因を正確に理解するのに役立ちます。



この記事では、テクニカルサポートでPerfViewを使用する可能性と、このユーティリティの制限について説明します。



PerfViewはもともと内部使用のために作成され、Windows、.NET CLRおよびVisual Studioのパフォーマンスを最適化するためにMicrosoftによって使用されました。 ユーティリティはWindowsカーネルツール-ETW( Windowsのイベントトレース)を使用します



トレース結果を正しく解釈するには、このユーティリティの動作を理解することが重要です。 どのプログラムも有向グラフの形式で表現でき、その頂点はメソッドになります。 その後、プログラムの呼び出しスタックはいつでもmain()メソッドから現在実行中のメソッドへのパスになります。







理想的な場合、このプログラムの動作を分析するには、各瞬間の状態に関する情報が必要です。 たとえば、そのような情報はデバッグによって提供されます。 しかし、最初に、デバッガーはデバッグされているプロセスに影響を与え、受信したデータは信頼できないことが判明します。 第二に、非同期呼び出しはより一般的になりつつあり、デバッガーはよく分析しません。 多くのタスクでは、分析されたプログラムの状態に関する情報はいつでも必要ありません。 特定の間隔でプログラムステータスのスナップショットを取得できます。 この図は、1つのスレッドで単純なプログラムがどのように機能するかのタイミング図を示しています。 図の下部にある時間軸は、プロセッサーのサイクル長の倍数である等時間間隔に分割されています。 灰色のセグメントの場合、スタックは利用できませんが、緑色の場合、利用できます。







この考えに基づいて、PerfViewプロファイラーが作成されました。 特定のかなり短い間隔で、マシン上のすべてのプロセスのスタック数のスナップショットが取得されます。 PerfViewはインターネットから文字をダウンロードでき、サイズが小さく、簡単なコピーで別のマシンに転送できます。 これにより、PerfViewは、Windowsマシン上のプログラムの動作を分析するための強力なツールになります。 スタックのカウントに加えて、システムイベント、.NETイベントなどが保存されます。 この情報は、多くの場合、問題の本質を理解し、解決策を見つけるのに役立ちます。



PerfViewがテクニカルサポートに役立つ典型的な状況を考慮してください。

1.ユーザーでアプリケーションがフリーズします。 これが最も簡単なことです。 ハングにつながる呼び出しスタックは、トレースに含まれることが保証されています。

2.アプリケーションはエラーで動作を停止します。 同時に、Windowsは問題プロセスを中断し、dwwin.exeデバッグプロセスを呼び出します。 この呼び出しにはショット間の時間よりもかなり長い時間がかかるため、落下するスタックのカウントもトレースに入ると言っても安全です。

3.アプリケーションが期待どおりに機能しません。 たとえば、一部の構成では、ウィンドウのサイズを変更すると、アプリケーションが不快にちらつくことがあります。 この状況では、トレースの結果を「良い」構成と「悪い」構成と比較する必要があります。

4.ユーザーのマシンでのアプリケーションのパフォーマンスが低い。 PerfViewはもともとパフォーマンスプロファイラーとして特別に作成されました。 この場合、ユーティリティはその目的に使用されます。



もちろん、PerfViewは、問題のあるコードがショットの間隔よりも短く表示され、繰り返されない状況では役に立ちません。





指を動かしたときに画面上に線を描く単純なWPFアプリケーションの動作を分析することを提案します。マウスの描画もサポートされています。 完成したアプリケーションはここから取得されました。

これは、分析されたアプリケーションの外観です。







タスク:入力から画面上のラインの表示までの遅延時間を推定し、次のシナリオの遅延時間を調査します

1.アプリケーションは、Acer Iconia W3 810タブレットで開始され、タッチ入力が使用されます。

2. Acer Iconia W3 810でアプリケーションをリモート起動し、タッチの代わりにマウス入力を使用します。

エイサーの安価で弱いタブレットは偶然ではありません。 それは十分に遅く、他のよりリソースを必要とするソフトウェア開発者を実行するためのメモリがほとんどありません。



分析用のデータを収集することから始めます。 PerfViewのメインウィンドウで、Alt + Cを押します。 ダイアログが表示されます。







オプションをそのままにして、[コレクションの開始]をクリックします。 過剰を分析しないために、データ収集中のアクションの数を減らすことをお勧めします。 たとえば、分析プログラムは、起動時に何が起こるかに興味がない場合、事前に実行できます。 いくつかの線を描画し、「収集を停止」をクリックします。 タブレットの小さな画面では、分析するのが便利ではないため、結果の* .etlファイルを大きなコンピューターに転送します。 トレースを分析するには、トレース時にマシンによって生成されたアセンブリのpdbファイルが必要です。 Collect-> Mergeを実行すると、PerfViewはそれらをetlファイルとともにアーカイブに入れます。 ユーティリティの最新バージョンはデフォルトでこれを行いますが、以前のバージョンではこれを覚えておく必要がありました。 結果のファイルを開きます。







ここで多くのことを話しますが、ここでCPUスタックを選択し、トレース時にタブレットで動作したすべてのプロセスを確認します。







それらのいずれかを見ることができます。 これにより、PerfViewはプロセス間相互作用を分析するための便利なツールになります。 上から3番目のプロセスは私たちのものです。 私たちはそれを選択し、受け取ります。







[時間]列には、時間軸に数値が表示されます。 数値が小さいほど、使用されるプロセッサリソースは少なくなります。 この列のダッシュは、このメソッドを使用したスタックが対応する時点でトレースに到達しなかったことを意味します。 アクティビティの5つのバーストが表示されます。 トレース時に、5本の線が描かれました。 GroupPatsは、グループクラスエントリに最適に設定されます。 このモードでは、テーブルの行はメソッドに対応します。







PerfViewでは、テーブルに数百のメソッドが表示されますが、さらに多くのメソッドがあります。 したがって、より完全な図を表示するには、トレースデータを分析する際の時間間隔を短縮することが重要です。 既に推測したように、時間軸上のアクティビティのバーストは線の描画に対応しています。 2番目のサージを選択します。 これを行うには、[When]列の文字を選択します。PerfViewは間隔の開始と終了を通知します。開始と終了のフィールドに入力する必要があります。 次のビューは、線画の始まりに対応しています。 期間の初めに、アプリケーションプロセスは何もしませんでした。 When列でメソッドを並べると、次のようになります。







このスクリーンショットでは、タッチ入力イベントPresentationCore.ni!PenThreadWorker.ThreadProcを処理することにより、描画プロセスが開始されることがわかります。 これは、トレースの開始から3,735ミリ秒後に発生しました。 タッチ入力イベントはプログラムで処理され、再描画を引き起こすはずです。 メソッドは呼び出し時間順に並べられているので、テーブルをめくり、再描画に関連する呼び出しを探してください。







wpfgfxの呼び出しは約3ミリ秒後に発生しますが、アプリケーションのコードがこの時間間隔で機能しなかったため、これは探していたものではありません。 誤って小さな発見をしたようです-WPFにはタッチ入力の視覚化があります。 アプリケーションがタッチ入力イベントを処理しない場合でも、そのようなイベントが到着するとウィンドウは再描画されます。 再描画の終了は、コールd3d9と見なされます!CSwapChain :: Present。 最初の再描画(私たちのものではない)は3,740ミリ秒で発生しました。 時間軸に沿ってさらに移動します。 タッチ入力イベントは、さらに4ミリ秒後にユーザーコードによって処理されました。 以下は、イベント処理スタックの全数です。







d3d9!CSwapChainへの次の呼び出し:: Presentメソッドは3,767ミリ秒で発生しました。

したがって、タッチ入力イベントからユーザーコードによる再描画に約32ミリ秒が経過しました。 1秒あたり1インチの指の速度では、視覚化の遅延は約3ピクセルです。

タブレットへのリモート接続の場合、遅延時間は、ユーザー入力をリモートマシンに送信する際の遅延、リモートマシンでフレームを生成する際の遅延、リモートデスクトップでフレームを受信およびレンダリングする際の遅延で構成されます。 これらの遅延を評価するには、リモートデスクトップを起動したマシンでトレースするだけで十分です。 分析の結果と興味深い結果のみを示します。 mstsc.exeプロセスを分析します。 入力メッセージの処理に費やされた時間を無視すると、mstscax!CTSProtocolHandlerBase :: SendBufferの呼び出しからmstscax!COP :: PresentContentGDIの呼び出しまでの遅延時間がカウントされます。 ユーザー入力は14,348ミリ秒でリモートマシンに転送されました。







その後、リモートマシンからグラフィックデータを受信し、リモートデスクトップアプリケーションウィンドウを再描画すると、15,139ミリ秒で発生しました。







遅延は791ミリ秒でした。 指の速度が1秒あたり1インチの場合、レンダリングの遅延は約75ピクセルです。



この記事を読んだ後、とらえどころのないバグや、プログラムの動作に関連するあらゆる種類の「奇跡」やあいまいな瞬間がなくなることを願っています。



All Articles