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

第2回 Visual Studioのプロファイラを使って性能評価を行う

亀川 和史
2011/05/31
Page1 Page2

 Visual Studio 2010 Premiumエディションおよび、Ultimateエディションには、アプリケーションの性能上の問題を計測、評価、特定するための「プロファイラ」と呼ばれる機能がついている。使いこなせばアプリケーションの性能上の問題を早期に検出できるため、大変有用な機能である。

Visual Studio 2010プロファイラによる性能測定

 Visual Studioには以前のバージョンからプロファイリング・ツールが付属していたが、Visual Studio 2010ではさらに強化された。特に現在販売されているCPUの多くはマルチコアであり、Visual Studio 2010もそれに対応するように、マルチコア対応機能がいくつも追加されている。

 本稿で紹介するプロファイラも例外ではない。従来のようなシングルスレッド・アプリケーションでもプロファイラは十分有用であるが、マルチスレッド対応アプリケーションではさらに有用である。

 特に、.NET Framework 4ではマルチコアを支援するためのタスク並列ライブラリ(Task Parallel Library。以下、「TPL」と略す)が用意されており、TPLを使用すれば比較的少量のコード追加でマルチコアを活用できる。TPLの使い方に関しては、下記のリンク先にあるC# 4入門の記事で解説されているので、そちらを参照してほしい。

 しかし、ただTPLを使っただけではPCの性能を使い切ることは難しい。例えば、CPU処理を並列化しても、処理内でI/O処理を行っていた場合、I/Oに時間を取られてしまい、結局、CPUが遊んでしまうということもあり得る。

 本稿では、Visual Studio 2010のプロファイラ機能を使用して、実際にアプリケーションのボトルネックを調査する方法および、プログラムの改善方法について解説する。

プロファイラで実行情報を採取する

性能測定対象となるサンプル・アプリケーションの準備

 まず、性能測定を行うためのプログラムを用意する。

 今回はCode Galleryにあるレイトレーシング・アプリケーション「Raytracer」を使用して性能測定を行う。

 本稿では紙面の都合上、C#で解説を行っているが、VB(Visual Basic)およびF#のソース・コードもダウンロードできる。ダウンロードしたファイル「Raytracer_CSharp.zip」を展開して、ソリューション(Raytracer_CSharp.slnファイル)をVisual Studioで読み込む。ソリューションには、「ParallelExtensionsExtras」と、「RayTracer_CSharp」という2つのプロジェクトが存在するはずだ。次の画面は、[ソリューション エクスプローラー]でソリューションを表示した例だ。

レイトレーシング・アプリケーション「Raytracer」のソリューションに含まれる2つのプロジェクト、「ParallelExtensionsExtras」と「RayTracer_CSharp」

【コラム】ソリューションをVisual Studioで読み込む際の注意点

 インターネットからダウンロードした.zipファイルを展開して、それに含まれるソリューション(Raytracer_CSharp.slnファイル)をVisual Studioで読み込むと、以下のようなセキュリティ警告が表示される。

ソリューションをVisual Studioで開く際に表示されるセキュリティ警告

 このセキュリティ警告は、インターネット・ゾーンと認識されているサイトからダウンロードした.zipファイルを展開して、その中のソリューション・ファイルをVisual Studioで読み込むと発生する。回避するには、.zipファイルのプロパティから[ブロックの解除]を行う必要がある。次の画面は、「Raytracer_CSharp.zip」ファイルのプロパティ画面である。

インターネットからダウンロードした.zipファイルのプロパティで[ブロックの解除]を行っているところ

 Code Galleryにはほかにも有用なサンプルが多く存在するので、それらのソリューションを開く際には、上記の手順を参考に[ブロックの解除]を行うとよい。

パフォーマンス・ツール環境設定

 パフォーマンス・ツール用の環境設定は、メニューバーの[ツール]メニューの[オプション]から起動されるダイアログの[パフォーマンス ツール]−[全般]/[規則]で設定可能だ(それぞれの設定方法については、以下の画面を参照してほしい)。通常はデフォルト設定のままで問題ないが、特定の現象のみを確認したい場合は、該当の現象のみチェックすればよい。

パフォーマンス・ツール用の環境設定([オプション]ダイアログ)
左側のツリーから[パフォーマンス ツール]−[全般]を選択する。
  時間の値をCPUクロック・ティック単位で表示するか、ミリ秒単位で表示するか。
  概要ビューで表示される関数の数を設定する。
  アプリケーションの分析に必要なシンボル情報をシリアル化して保存する。シリアル化されたファイルは「.vsp」ファイルに追加され、元の.exeファイルや.pdbファイルがない状態でもパフォーマンス・レポートの分析が可能になる。
  プロファイラ・レポートで自分のコードのみを有効にする。
  呼び出し先の非ユーザー関数の1レベルを表示する。
  呼び出し元の非ユーザー関数の1レベルを表示する。

パフォーマンスで「警告」「エラー」「情報」として表示される規則の一覧
左側のツリー表示から[パフォーマンス ツール]−[規則]を選択する。

 これらの設定は、次から説明するパフォーマンス・ウィザードで性能情報を採取し、プロファイル・レポートに表示されている[ガイダンスの表示]をクリックすると(詳しくは、後掲の「『CPUサンプリング』プロファイル・レポートの表示」を参照)、このルールに該当するメッセージが表示される。

ガイダンスの表示への切り替えを行うメニュー

 実際に[ガイダンスの表示]をクリックすると、設定されたルールに該当している項目が以下のように表示される。

設定されたルールに該当している項目が表示されている例([エラー一覧]ウィンドウ)

 これらの設定は、これから説明するパフォーマンス・ウィザードを実行した後で使用される。次からパフォーマンス・ウィザードを実行する手順を解説する。

パフォーマンス・ウィザードの起動

 読み込んだRayTrace_CSharpソリューションのパフォーマンス問題を診断する方法を解説する。

 次の画面のように、メニューバーの[分析]にある[パフォーマンス ウィザードの起動]を選択する。

メニューバーの[分析]メニュー
パフォーマンス問題を診断するための機能が、メニューバーの[分析]メニュー配下に集まっている。
  パフォーマンス・ウィザードを起動する。
  すでに採取したパフォーマンス・レポートと比較する。
  プロファイラの詳細機能(プロセスにアタッチなど)を実行するためのメニュー。この配下にさらにメニュー項目が存在する。
  プロジェクトのコード分析を実行する(FxCopを使用)。
  プロジェクトのコード分析の設定画面を開く。
  ソリューション全体のコード分析の設定画面を開く。
  選択したプロジェクトのコード・メトリックスを計算する。
  ソリューション全体のコード・メトリックスを計算する。
  プロファイラ関係のウィンドウ([パフォーマンス エクスプローラー]など)を表示する。

 コード・メトリックスとは、保守容易性、コードの構造上の複雑さといった項目を、あらかじめ決められたルールに従って計算してくれる機能である。Visual Studio 2010以前のバージョンから搭載されている機能だが、本稿ではコード・メトリックスについては扱わない。コード・メトリックスの説明に関しては、下記のリンク先にあるMSDNページを参照してほしい。

パフォーマンス・ウィザードの各ページでの設定(CPUサンプリング)

 実際に[パフォーマンス ウィザードの起動]メニューを選択すると、以下の[パフォーマンス ウィザード]ダイアログが表示される。

[パフォーマンス ウィザード](ページ 1/3)
[プロファイル方法の指定]ページが開かれているところ。
  [CPU サンプリング]は、CPU処理主体でアプリケーションのプロファイル(=プログラム実行時の各種情報を採種すること)を行う。性能測定の場合、まずはこれを選択すればよい。
  [インストルメンテーション]は、ボトルネックを調べるために関数の呼び出し回数とタイミングを調査する場合に選択する。
  [.NET メモリ割り当て]は、マネージ・コード上で使用しているメモリ割り当てを調査する場合に使用する。
  [同時実行]は、マルチスレッド・アプリケーションの測定において、リソースの競合などのマルチスレッド固有の問題を調査するために使用する。

 まず、[CPU サンプリング]によるプロファイリングを行って、性能を調査する。[次へ]ボタンを押してウィザードを進める。

[パフォーマンス ウィザード](ページ 2/3)
[サンプリング メソッドを使用してプロファイルするアプリケーションの選択]ページが開かれているところ。
  プロジェクトをプロファイル対象にする。通常、これを選択すればよい。
  実行可能ファイル(=.exeファイル)を選択する。例えばソース・コードが無いようなアプリケーションおよび、特定のアプリケーションから呼び出されるようなDLL(=.dllファイル)をプロファイリングするときに使用する。
  ASP.NETもしくはJavaScriptを用いたアプリケーションの性能をプロファイルするときに使用する。

 [使用可能な 1 つ以上のプロジェクト]ラジオボタンを選択し、その下の一覧から該当するソリューションを選択して[次へ]ボタンを押す。

[パフォーマンス ウィザード](ページ 3/3)
[新しいパフォーマンス セッションの設定の指定が完了しました]ページが開かれているところ。
  ウィザード終了後、自動的にプロファイルを開始するチェック。通常チェックしておけばよい。

 [完了]ボタンを押せば、プロファイルを自動的に開始する。

パフォーマンス・ウィザードによるプロファイル開始

 プロファイルの開始時に、Windows Vista以降のOSでは特権昇格する必要があるため、以下のようなメッセージボックスが表示されるので、[はい]ボタンを押せばプロファイルが開始される。

プロファイル開始時に表示される特権昇格のメッセージボックス

 通常のデバッグ実行と同様に、プロファイラがプログラム(今回の場合は「Raytracer.exe」ファイル)を起動し、プロファイルが開始される。プロファイラが情報を採取している状態では、Visual StudioのIDE(の中央部分)で以下の表示が行われている。

プロファイラが情報を採取している状態の表示
Visual StudioのIDE(の中央部分)に、このような表示が行われる。
  プロファイルを一時停止する。
  プロファイルを停止する。

 プロファイラにより今回のサンプル・アプリケーション「RayTracer」が実行されると、以下のような画面が表示される。

今回のサンプル・アプリケーション「RayTracer」の実行画面
プロファイラにより、プロフィル対象のプログラムが実行される。
  レンダリングを開始する。レンダリングが開始されると、この[Start]ボタンの表記が[Stop]に変更される。
  並列レンダリングを実行するチェック。
  各スレッドの実行情報を表示する。
  最大使用スレッドを設定する(現在の論理CPU数が上限になる)。

 まずはシングル・スレッドで(=[Parallel]チェックボックスにチェックを付けない状態で)アプリケーションの描画処理を実行して、その性能をプロファイルする。[Start]ボタンを押せば、リアルタイムで以下の画面が描画され、右側のボールが跳ねるアニメーションが見えるはずだ。タイトルバーには秒あたりのフレーム数(この例では「0.8」fps:Frame/sec)が表示されている。CPUを1コアのみ使用し、さらにプロファイラを実行しているため、かなり低いレートでしか描画されない。

シングル・スレッドでアプリケーションの描画処理を実行して、その性能をプロファイルしているところ

 [Stop]ボタンを押して、さらにアプリケーションを終了すれば、プロファイルも停止される。プロファイルが停止されると、次の画面のように[パフォーマンス エクスプローラー]に収集結果が格納されたレポート・ファイル(=.vspファイル)が表示される。

[パフォーマンス エクスプローラー]に表示されたレポート・ファイル(=.vspファイル)

 レポート・ファイルの名前(例えば「Raytracer110531.vsp」)はVisual Studioが自動的に作成するが、採取直後に測定手順や条件など後から見ても分かるようなファイル名にしておいた方がよい。今回の場合は、1つのCPUで採取したので、「Raytracer_1CPU.vsp」というファイル名に変更した。レポート・ファイルはプロジェクト・フォルダに保存されているので、後から別のマシンで参照することもできる。レポートが開かれるまで、かなり時間がかかるので、注意してほしい。

「CPUサンプリング」プロファイル・レポートの参照

 レポート・ファイルを開くと、Visual Studio内に以下のような画面が表示される([Shift]+[Alt]+[Enter]キーで、Visual Studioを全画面表示に切り替えると見やすい)。

「CPUサンプリング」プロファイル・レポートの表示
レポート・ファイルを開くと、このような性能に関する各種情報を閲覧できる。
  プロファイラのビューを変更する。「概要」「コール ツリー」「モジュール」など、さまざまなビューの切り替えを行える。
  フィルタ操作および、データ・エクスポート用ボタン。
  CPU使用率のグラフ。グラフを選択して、プロファイル範囲を特定の領域だけフィルタすることができる。操作デモの動画を以下に公開している。
  プロファイルした範囲内で、「どの処理が最も呼び出されているか」を示すレポート(最も呼び出し割合が高いパスを示す[ホット・パス]と、[最も頻繁に個別の作業を実行している関数]の2種類がある)。もちろんプロファイル時間によってレポート内容も変わるため、CPU使用率の高そうな範囲を変更しながら調査する。[ホット パス]グラフで、赤い、炎のようなアイコンが左端に出ているコードが「最も呼び出し割合が高い」と考えられる場所になる。
  すべてのコード(参照可能な外部アセンブリを含める)とマイ・コードを切り替える。
  画面下部にあるガイダンス一覧にフォーカスを切り替え、ガイダンス・レポートを表示する。表示される項目は、「パフォーマンス・ツール環境設定」で解説した方法で設定する。
  レポートの表示が大きくなりすぎることを防ぐため、「あるしきい値未満のデータを表示しない」という設定が行える。ここをクリックすると、「トリミングされた状態の」呼び出しツリーを表示する(=コール・ツリー・ビュー)。もちろんコール・ツリー・ビューからトリミング範囲の調整を行うことも可能だ。
  ソース・コードの行単位で、「どこが最も呼び出されているか」を一覧にして表示する。
  複数のレポートを比較する。採取レポートを比較する。チューニングを行ったプログラムで、「どのくらいプロファイラの実行情報が変化したか」を調査する。
  レポート・データをCSV形式もしくはXML形式に出力する。
  レポート・データを別の場所などに保存する。
  スレッドID、プロセスID、時間などの条件を指定して、レポート・データをフィルタリングする。

  のCPU使用率のグラフで、プロファイル範囲をフィルタする方法は以下のデモ動画を参考にしてほしい。

YouTube:Visual Studio 2010プロファイラ・レポート操作

 [現在のビュー]コンボボックスには、次のようなビューが提供されている。

「CPUサンプリング」プロファイル・レポートの[現在のビュー]コンボボックスで提供されているビュー

ホット・パスの参照

 それでは、このレポート情報の中で最も使うと思われる[ホット パス]を参照する。

 このレポートのホット・パスで最も呼び出し頻度が高いと思われる41.20%のレコードをクリックして選択する。

「CPUサンプリング」プロファイル・レポートの[ホット パス]で最も呼び出し頻度が高いレコードをクリックして選択

 これにより、以下のようなレポートに切り替わる。

[ホット パス]で最も呼び出し頻度が高いレコードの詳細情報
[ホット パス]でレコードをクリックして選択すると、このような表示に切り替わる。
  選択されたホット・パスを呼び出している関数。
  選択されたホット・パスから呼び出される関数。
  選択されたホット・パスに対応するソース・コード。

 このように、処理時間の割合から対応するソース・コードを簡単に閲覧できる。

 以上が、シングルスレッド・アプリケーションのプロファイル手順である。

 続いて、マルチスレッド・アプリケーションのプロファイルについて説明していこう。


 INDEX
  アプリケーションのギアを上げよう ― Visual Studio 2010でアプリケーションのパフォーマンス・チューニング
  第2回 Visual Studioのプロファイラを使って性能評価を行う
  1.プロファイラで実行情報を採取する
    2.マルチスレッド・アプリケーションの競合状態を収集する

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


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