Store AppをGPUViewでキャプチャしてみる

先の記事でWindows SDKをインストールしたので、先の記事で作成したStore AppをGPUViewでキャプチャしてみたいと思います。

GPU Viewのインストール

Windows SDKをインストールする際に、Windows Performance Toolkitをインストールするように設定すればインストールされます。
Windows Software Development Kit (SDK) for Windows 8
http://msdn.microsoft.com/en-us/windows/desktop/hh852363
デフォルトのインストールパスは下記の通りです。
C:Program Files (x86)Windows Kits8.0Windows Performance Toolkit
使い方は以前と変わりません。log.cmdでキャプチャするだけでです。

追記:Windows RT上でもGPU Viewを使用することが出来ます。
Windows RT(ARM)用のWindows Performance Tool KitはWindwos SDK for Windows8 に付帯しています。デフォルトのインストールパスの場合は下記のフォルダに配置されています。
“C:Program Files (x86)Windows Kits8.0Windows Performance ToolkitRedistributablesWPTarm-arm_en-us.msi”
インストール方法や使用方法などは特に変わったことはありません。Win8上と同様にキャプチャすることが出来ました。

テストアプリのキャプチャ結果

結果は以下の通りです。青い線がVSyncのタイミングを表します。VsyncのタイミングでXAMLのコントロールの描画が始まるようです。先のテストアプリで設定したレンダリングのイベントは、XAMLのUIの描画に先だって呼び出されるイベントのようなので、一番初めのほうでDXのRenderTargetのクリアを行う処理が入っているはずです。以降は、子要素であるTextBoxの描画等が行われているのでしょうか。このあたりの詳細は不明です。行っている描画処理の内容に比べてDMAパケットの発行回数が多いのが気になります。呼び出しの間隔は約16msで、いわゆる60FPSの描画となっています。CPUの処理時間は約2ms程度で、2threadをまたいで処理されています。CPUはCorei7-3770を使用しているのですが、CPUの処理時間が、行われている処理の内容の割には少々長いのが気になります。

テストアプリのOnReinderingを変更する

このままではよくわからないので、以下のような変更を加えてキャプチャしてみました。


  • RenderTaregetのクリアを30回行うように変更

  • Present()とTextBoxの内容書き換えの間にCPU負荷コードを追加



この結果から、OnRenderingの呼び出しはSHCORE.dllから行われているのがわかります。CPU負荷が高すぎてVSyncに同期することができません。レンダリングのイベント終了後に、VSyncを待たずに直ちに再び呼び出されています。一方Windows.UI.Xaml.dllはVSyncに合わせて呼び出されています。毎フレームおきにスレッドは起動しますが、おおよそ2フレームに一回描画を行っています。これはTextBoxの内容が書き換わったことによる描画と思われます。内容の書き換えはOnRenderingの最後で行っているので、SHCORE.dllのスレッドが一旦終了した直後のVSyncでは描画動作が行われています。お気づきとは思いますがDXの描画とXAMLのUI描画はそれぞれ別のContextで行われています。したがって、各々でPresentパケットをGPUに送っています。それぞれのコンテキストをGPU側でCompositして表示しているものと思われます。したがって描画の更新周期がどちらかに律速してしまうことは無いものと思われます(GPU Boundの場合は別ですが)。また、OnRenderingの呼び出しはXAMLのUI描画に先だって呼び出されるというよりは、VSyncに同期して並行して呼び出されるものなのかもしれません。

追記:描画の更新周期の律速について

実際にXAMLのUI描画とSwapChainBackgroundPanelが、どちらかに律速してしまうことはないか確かめてみました。
OnRenderingの処理中にCPUに大きな負荷をかけながら、同時にTextBoxの内容を更新し続けてみました。別のスレッドでXAMLのUIが描画されていれば、随時更新されるはずです。
しかし結果は、OnRendering(CompositionTarget::Renderingイベント)の処理中にTextBoxの描画が更新されることはありませんでした。CompositionTarget::RenderingイベントはXAMLのUI描画に先だって呼び出されるイベントのようで、この処理が終了しないとXAMLのUIの更新は行われないようです。

次に、SwapChainBackgroundPanelに対する描画処理をRunAsyncで非同期処理に変更してみました。TextBoxの更新は引き続きOnRendering内で行っています。下図がその時のGPUViewのキャプチャです。
このようにすれば、XAMLのUI描画とSwapChainBackgroundPanelに対する描画は非同期になり、更新周期の異なる描画が可能になります。RunAsyncでオフロードした描画処理はntdll.dllで実行されてるようです。SwapChainBackgroundPanelにの描画処理はRTを300回クリアするもので、CPUQueueは上から3番目のQueueと思われます。XAMLのUI描画は1番目のCPUQueueと思われ、毎フレームPresentが実行されています。SwapChainBackgroundPanelのCPUQueueがGPUで処理中の時は、XAMLのUI描画のパケットの処理が遅延しているのが見て取れます。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中