アプリケーションのギアを上げよう
― Visual Studio 2010でアプリケーションのパフォーマンス・チューニング ―

第3回 WPFアプリケーション・チューニング

亀川 和史
2011/08/26
Page1 Page2 Page3

WPF Performance SuiteでGPU描画性能測定

 次は、Perforatorを紹介する。

 こちらはシステム環境が提供するグラフィックス機能の描画性能を調査するためのツールだ。WPF(やSilverlight)では、アニメーションの処理が間に合わない場合、途中の描画は省略される。つまり、アニメーションの終了時間に指定されたイメージで描画されることが仕様で保証されている。

 しかし、いくら保証されているとはいえ、ターゲットとなる環境で見た目に影響が出るくらい、途中のアニメーションが省略されているようでは困るので、対象とする環境で問題ない描画レベルのアニメーションが実行できるかを調査する必要がある。そのためのツールが、Perforatorである(次の画面を参照)。

Perforatorによる性能測定の例
上部の[Perforator]タブを選択すると、この画面が表示される。Perforatorは、グラフィックス機能の描画性能の測定に役立つ。
  アプリケーションが画面を書き換える速度(以下、フレームレート)。もしもアニメーションがない場合、限りなく「0」に近づく。液晶モニタの場合、多くは60Hzになっていると思われるので、画面描画が発生する場合、1秒当たり60枚の書き換えを維持していれば、ディスプレイ上では途切れなくきれいに見える。注意事項として、この値がときどき「0」でキープされることがある。
  描画の必要があると判断された四角形領域の数。.NET Framework 4でBitmapEffectクラス(System.Windows.Media.Effects名前空間)を使用している場合にのみ発生する。
  1フレームあたりで、ソフトウェア描画が発生した回数。BitmapCache/DrawingBrush/VisualBrushクラス(System.Windows.Media名前空間)を使用する場合や、WPF画面上のOpacityプロパティ値(=透明度)プロパティ値を変更した場合、TileBrush派生クラス(System.Windows.Media名前空間)のTileMode(=タイル・モード)プロパティ値を「Tile」に設定した場合に発生する。過剰なソフトウェア描画は性能面で著しく不利になる可能性があるので、極力、避けるべきである。
  1フレームあたりで、ハードウェア描画が発生した回数。BitmapCache/DrawingBrush/VisualBrushクラス(System.Windows.Media名前空間)を使用する場合や、WPF画面上のOpacity(透明度)プロパティ値を変更した場合、TileBrush派生クラス(System.Windows.Media名前空間)のTileMode(=タイル・モード)プロパティ値を「Tile」に設定した場合に発生する。この値が「5」以上といった大きな値を常時維持している場合、グラフィックス機能に負荷がかかりすぎているので、描画そのものを見直すべきである。
  WPFアプリケーションでどのくらいGPUのビデオ・メモリを使用しているかを表す。
  左側にあるボタンで、性能データ採取の一時停止/再開を指示する。スライダで、採取間隔を調整する。最大1分間隔まで調整できる。
  各種レンダリング・オプションを変更する。例えば[Draw Software rendering with purple tint]チェックボックスをチェックすれば、ソフトウェア描画している場所を紫色で塗りつぶしてくれるので、ソフトウェア描画対象箇所を判定する際に役立つ。

 Perforatorを試すために、実際にアニメーションを行うWPFアプリケーションを用意しよう。

 本稿では、次の画面のように、LightWaveというCGツールでドーナツ型の形状を作成し、図形に対し頂点数を機械的に8192ポリゴンまで増やした。アニメーションが分かりやすいように色分割している。

図形の作成

 この図形をWavefront OBJ形式(拡張子は「.obj」)で出力し、WPF/Silverlightデザイン・ツールの「Expression Blend」に取り込み、アニメーションを付ける。1つのアニメーションでは負荷がかからないので、4種類の異なるアニメーションを付けた(次の画面を参照)。

4種類の異なるアニメーションを付けた図形

 8192ポリゴンの図形が、異なる4種類のアニメーションを行うWPFプログラムが作成できたので、これを実行し、Perforatorで描画性能を調査する。使用するビデオ・カードは、nVidia社のGeForce 9800GTと現在ではかなり旧世代に属するものだ。

 実行方法は、前述のVisual Profilerの場合と同じ。[F5]キーを押せば、次の画面の[Launch Process]ダイアログが表示されるので、実行対象のWPFアプリケーションを選択する。

Perforatorにおける、任意のWPFアプリケーションの指定
[F5]キーを押して(もしくは、メニューバーから[Actions]−[Launch Process]メニューを選択して)、[Launch Process]ダイアログが表示されたところ。

 [Launch Process]ダイアログの[Launch]ボタンを押すと、次のようなWPFアプリケーションが実行される。

Perforatorを試すために実行したWPFアプリケーション
実際に動作させた際のキャプチャ動画をYouTubeに「WPF toroid Demo」というタイトルで公開している。

 次の画面に示すPerforatorの実行結果を見ると、今回のWPFアプリケーション程度のアニメーションでは、かなり古いGPU(を搭載するビデオ・カード)に属するGeForce 9800GTでも1秒当たり58フレームで描画できていることが分かる。GeForce 9800GT以上の性能を持つGPUでは、今回のアニメーションは問題なく描画されることが期待できる。

Perforatorによる性能測定の例

 もっと負荷をかけるアプリケーションが、WPF Performance Suiteの中にサンプルとして用意されている。既定では「C:\Program Files\Microsoft Windows Performance Toolkit\WPF Performance Suite\Demo Applications」にインストールされている「BeetleMania.exe」というプログラムだ。

 BeetleMania.exeファイルを実行すると、以下のウィンドウが起動する。このアプリケーションは、いろんな効果を付けたBeetle(昆虫)を表示させ、数と種類によってWPFの描画性能を測定するためのプログラムだ。

WPFの描画性能を測定するためのプログラム「BeetleMania.exe」の実行例
このWPFアプリケーションは、WPF Performance Suiteに添付されている。いろんな効果を付けたBeetle(昆虫)を表示させ、数と種類によってWPFの描画性能を測定できる。
  表示させる効果を持った昆虫を選択する。例えば「BlurBeetle」であれば「ぼかし効果」、「OpacityBeetle」であれば「透明効果」、「VisualBrushBeetle」であれば「VisualBrush効果」を持つ昆虫になる。下ののボタンを押したタイミングで表示・消去が行われる。
  選択した効果の昆虫を1匹表示する。
  選択した効果の昆虫を10匹表示する。
  表示している昆虫を消去する。
  すべての効果の昆虫を1つずつ表示する。
  ソフトウェア・レンダリングを使用する。

 いくつかの効果の昆虫を追加すると、以下のような画面になる。

いくつかの効果の昆虫を追加した場合の実行例

 この状態でPerforatorを使用して性能測定してみよう。次の画面のようになる。

いくつかの効果の昆虫を追加した場合の、Perforatorによる性能測定の例

 このくらい負荷がかかる効果をいくつも同時に出していると、フレームレートも1秒当たり30フレームに落ちていることが分かる。ソフトウェア描画は行われていない、描画更新も時間によって凹凸があることが分かる。

 この状態で(「WPFの描画性能を測定するためのプログラム「BeetleMania.exe」の実行例」のとして示した)[Render in Software]チェックボックスにチェックを入れる(=ソフトウェア・レンダリングを使用する)と、どのような違いが起きるか調べてみよう。それを行っているのが次の画面だ。

ソフトウェア・レンダリングを使用した場合の、Perforatorによる性能測定の例

 赤枠で囲んでいるところが[Render in Software]チェックボックスにチェックを入れていた時間帯である。[SW IRTs per Frame]が発生しているかわりに[HW IRTs per Frame]および[Video Memory Usage]が全く発生していないことがわかる。

 このようにPerforatorを使って、「性能基準となるハードウェアで、どのくらいの描画性能があるか」を早い段階から調べておくとよい。

ユーザー・インターフェイスを調べるツール

 UIの階層あるいは「WPFが標準コントロールを内部的にどのように描画しているのか」を知りたいときはないだろうか?

 アンマネージのWindowsアプリケーションのUI階層であれば、いちいちソース・コードを調べなくても、「Spy」を使えば調べられる。

 Spyは、最新のWindows SDKでは「Spy++」と改名されており、64bit版Windows SDKをインストールした場合は(次の画面のように)64bit版と32bit版の2種類が存在する。32bit版のWindows SDKでは、もちろん32bit版のSpy++しかインストールされていない。

64bit版と32bit版のSpy++([スタート]メニューから選択できるプログラム・メニュー項目)

 「Spy++」と名前は変わったが、次の画面に示すように、機能そのものは(「Spy」から)変わっていない。

アンマネージのWindowsアプリケーションのUI階層を調べられる「Spy++」の実行例

 Spy++は、「特定のウィンドウに対して、どのようなメッセージが、どのような順番でWindowsから送信されているか」を調査する際に大変便利なユーティリティである。恐らく多くの開発者がWindowsフォーム・アプリケーションやMFCアプリケーションなどで使用したことだろう。

 しかし、ウィンドウ・メッセージを使用しないWPFアプリケーションには、このSpy++を使用することはできない。ウィンドウ検索で、外枠のウィンドウを検索することはできる。しかし、選択しても「利用できません」と表示される(次の画面を参照)。これはウィンドウ・メッセージを処理するウィンドウ・プロシージャが存在しないためである。

Spy++ではWPFアプリケーションを選択しても「利用できません」と表示される

 それでは、WPFアプリケーションの場合は何を使えばよいのだろうか?

 WPFアプリケーション向けには、2種類のツールが提供されている。

 1つは「UI Spy」である。このツールは、「Windows SDK for Vista Update」および、「Windows SDK for Windows Server 2008 and .NET Framework 3.5」に付属しているが、最新のWindows SDK for Windows 7 and .NET Framework 4および、Visual Studio 2010付属のWindows SDKには付属していない。MSDNの記述によると、サポート終了になったようだ。

 代わりに「Inspect」(プログラム・メニューには、次の画面のように「Inspect Objects」で登録されている)というアプリケーションが添付されている。「UI SpyではUI Automationしか対応していなかったが、InspectはMicrosoft Active Accessibility(以下、MSAA)にも対応しているから」というのが、UI Spyを廃止して、代わりにInspectを提供する理由のようだ。

Inspect Objects([スタート]メニューから選択できるプログラム・メニュー項目)

 Inspectを起動すると、以下のウィンドウが表示される。Spy++とは少し違った形で表示されている。以下はUI Automationモードで表示した場合である。

Inspect(UI Automationモード)の実行例
WPFアプリケーションを含めて、実行中のアプリケーション・ウィンドウにおけるUI階層などの各種情報が表示されている。
  現在起動しているプログラムの一覧。
  選択されたウィンドウのプロパティ一覧。

 アンマネージ・アプリケーションをSpy++で見たときと比べて、特に右側のプロパティ一覧がかなり異なる(もちろん、Spy++で表示されているのと同じ項目も、プロパティ一覧にいくつか存在する。具体的には「ClassName」や「IsEnabled」といったプロパティ項目)。Inspectを使用すれば、このようにマネージ・アプリケーション、アンマネージ・アプリケーションを問わず、ウィンドウ階層構造を調べることができる。

 同じプログラムを起動した状態でMSAAモードに切り替えた場合を以下に示す(上の画面と見比べてほしい)。選択したウィンドウ(コントロール)に対して自動的に左側のツリーのフォーカスが位置付くので、UI Automationモードのときと違うウィンドウが選択されているが、MSAAモードではUI Automationでは表示されていないウィンドウも表示されていることに気が付く。UI Automationでは、プログラムからの操作のためのウィンドウだけを列挙しているためであると考えられる。

Inspect(MSAAモード)の実行例

【コラム】Microsoft Active Accessibility(MSAA)について

 MSAAとは、WindowsベースのUIに関する要素情報をプログラムからアクセスするための方式である。「プログラムからアクセスする」という点において、UI Automationがすでに用意されているが、UI AutomationはUIを異なるプログラムからテストするために使用する機能であり、主に開発者が使用する機能である。一方のMSAAはエンド・ユーザーが使用するための機能である。よって、両者の機能では利用対象者が異なっている。

 MSAAを使用すれば、UIを音声や点字のような代替手段で表示させることもできるため、身体上の理由でマウスやWindowsの標準UIが使用できないようなエンド・ユーザーにも有益なものとなっている。

 MSAAについてさらに詳しい情報は、下記のリンク左記を参照してほしい。

Silverlightのパフォーマンス

Silverlight Spy

 ここまではWPFでのコントロールの調査方法を紹介してきたが、Silverlightでは残念ながら、これらのツールは使用できない。たとえ完全信頼でOut of Browserモードで実行していても使えない。しかし、First Floorというサード・パーティから「Silverlight Spy」というツールがリリースされており、制限はあるがフリー版も提供されているので、試してみるといいだろう。

 フリー版と商用版の機能制限に関しては、ライセンスのページ(英語)で紹介されている。パフォーマンス・モニタ系の機能は商用版を購入しないと使えないが、「ボリューム・ライセンス」「3ライセンス購入すれば5ライセンス分の割引」「個人向けライセンス」といくつかの価格があるので、Silverlightのパフォーマンス・チューニングを行う場合には購入を検討してもいいだろう。

 次回はデータベース・アクセス、LINQ、Webサービス系について解説するend of article


 INDEX
  アプリケーションのギアを上げよう ― Visual Studio 2010でアプリケーションのパフォーマンス・チューニング
  第3回 WPFアプリケーション・チューニング
    1.WPF Performance Suiteで描画性能測定
    2.描画性能の測定手順/TreeView&DataGridコントロールにおける「UIの仮想化」
  3.WPF Performance SuiteでGPU描画性能測定/Silverlightのパフォーマンス

インデックス・ページヘ 「アプリケーションのギアを上げよう」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH