Unity を検索

Unity のパフォーマンスベンチマーキング - 導入ガイド

2018年9月25日 カテゴリ: Engine & platform | 22 分 で読めます
取り上げているトピック
シェア

Is this article helpful for you?

Thank you for your feedback!

Unity 開発者の目標は、スムーズで快適なプレイ体験をすべてのプラットフォームで実現し、ユーザーにゲームを気に入って楽しんでもらうことでしょう。これを応援すべく Unity では、パフォーマンスのベンチマーク作成をより簡単に行えるようにしました。パフォーマンスを考慮しながらゲームや Unity ツールを制作する方法を知りたい方は、ぜひこの先を読み進めてください!

本記事ではいくつかの Unity ツールの使用方法をご説明します。これらのツールを使用すると、パフォーマンスメトリックの収集と、それを使ったベンチマークの作成が簡単に開始できます。これらのツールとは、Unity Test Runner(Unity エディターに搭載)、Unity Performance Testing Extension、そして Unity Performance Benchmark Reporter です。

Unity でパフォーマンスのベンチマーキングを行う目的

Unity 開発者の皆様は、「ついこの前までプロジェクトが迅速・スムーズに実行されていたのに、1 つ 2 つ修正を加えたらシーンが目に見えて重くなり、フレーム落ちなどのパフォーマンス問題が発生するようになってしまった」という状況に直面することがあるかも知れません。こうしたパフォーマンスの低下がどの修正によって引き起こされたのか特定することは、時として困難です。

Unity パートナーの皆様なら、異なる SDK、ドライバー、プラットフォーム、パッケージ、その他アーティファクトのすべてにおいてパフォーマンス状況の変化を把握したいことでしょう。あるいは、バージョンの異なる Unity におけるプロジェクトのパフォーマンスメトリックを収集したいのに、その実行と比較の方法がよく分からないという場合もあるかも知れません。

パフォーマンスのベンチマークの確立は、様々な状況において非常に役立ちます。上記はそのほんの一握りの例に過ぎません。以下、パフォーマンスメトリックを収集し、それを使ってベンチマークを作成し、パフォーマンスメトリックの変化を視覚化する方法をご紹介します。

サンプルプロジェクトのダウンロード

以降の解説は、サンプルパフォーマンステストプロジェクト『UnityPerformanceBenchmark』内のテストコードを使って進めて行きます。

GitHub から最新版の XRAutomatedTests を入手してください。UnityPerformanceBenchmark プロジェクトは PerformanceTests のサブディレクトリ内にあります。

Unity Test Runner でパフォーマンステストを記述する

UnityPerformanceBenchmark プロジェクトには多様なサンプルシーンが含まれています。これらは Unity Performance Testing Extension を使った Unity Performance テスト内で順番に使われます。

まず始めに、Unity Test RunnerUnity Performance Testing Extension を使ってパフォーマンステストを記述する方法を解説します。その前に、これら 2 つのツールに関する背景情報を少しご紹介します。

Unity Test Runner

Unity Test Runner はパフォーマンステストの実行に使用します。Unity Test Runner は Unity エディター組み込みのテスト実行フレームワークで、これを使用すると、ターゲットプラットフォームのプレイヤー(スタンドアロン、Android、iOS など)で、編集モードと再生モードの両方でコードのテストを行うことができます。Unity Test Runner に馴染みのない方は、Unity Test Runner に関するドキュメンテーションをご覧ください。

Unity Performance Testing Extension

Unity Performance Testing Extension は、Unity エディターのパッケージで、API とテストケース属性を提供し、Unity プロファイラーのマーカーと(Unity プロファイラー以外の)カスタムのメトリックの両方を、Unity エディターやプレイヤー上でサンプリングおよび集計できるようにするものです。詳細は Unity Performance Testing Extension に関するドキュメンテーション(英語)でお読みいただけますが、本記事ではいくつかの例をご紹介します。

Unity Performance Test Extension には、バージョン 2018.1 以降の Unity が必要となります。Unity 2018.1 以降のバージョンをお使いであれば、UnityPerformanceBenchmark プロジェクト内で、あるいは Unity Performance Test Extension の使用中いつでも、サンプルパフォーマンステストを行うことができます。

コマンドラインを使用してサンプルプロジェクトを開く

UnityPerformanceBenchmark プロジェクトは、Unity Test Runner の要素のひとつである IPrebuildSetup インターフェースを実装します。これにより、Unity Test Runner がテストを実行する前に自動的に呼び出される Setup メソッドを実装することができます。

UnityPerformanceBenchmark プロジェクトの IPrebuildSetup.Setup メソッドはまず、コマンドライン引数をパースして、プレイヤービルドの設定値を取り出します。これにより、同じ Unity プロジェクトを使った、異なる条件(プラットフォーム、レンダースレッドモード、プレイヤーグラフィックス API、スクリプト実装、ステレオレンダリングパスや VR SDK などの XR 向け設定)でのパフォーマンステストのためのプレイヤーを、自在にビルドできるようになります。

したがって、Unity でコマンドラインから UnityPerformanceBenchmark プロジェクトを開いて、Unity Test Runner でのテスト実行時に使用したいプレイヤービルドオプションを渡す必要があります。

例:UnityPerformanceBenchmark プロジェクトを Windows から起動して Android プレイヤーをビルドする:

Unity.exe -projectPath
C:\XRAutomatedTests-2018.2\PerformanceTests\UnityPerformanceBenchmark
-testPlatform Android -buildTarget Android -playergraphicsapi=OpenGLES3 -mtRendering -scriptingbackend=mono

ここでは、Windows で Unity を起動して「OpenGLES3 グラフィックス API、マルチスレッドレンダリング、Mono スクリプティングバックエンド」の設定で Android 向けにビルドしています。

例:UnityPerformanceBenchmark プロジェクトを OSX から起動して iOS プレイヤーをビルドする

./Unity -projectPath /XRAutomatedTests-2018.2/PerformanceTests/UnityPerformanceBenchmark
-testPlatform iOS -buildTarget iOS -playergraphicsapi=OpenGLES3 -mtRendering -scriptingbackend=mono
-appleDeveloperTeamID=
-iOSProvisioningProfileID=

ここでは、OSX で Unity を起動して「OpenGLES3 graphics API、マルチスレッドレンダリング、Mono スクリプティングバックエンド」の設定で iOS 向けにビルドしています。また、iOS デバイスにデプロイするために必要な Apple Developer Team ID および Provisioning Profile の情報も提供しています。

上の例のように UnityPerformanceBenchmark プロジェクトを Unity でコマンドラインから開く場合、コマンドライン引数がメモリ内に入るので、IPrebuildSetup.Setup メソッドがそれを解析したり、プレイヤーをビルドする際に使用できるようになります。

Unity Test Runner でテストを実行する時、必ずしもこのようにコマンドラインから起動しなければならない訳ではありませんが、この方法であれば、異なるプレイヤー設定毎に別々のテストプロジェクトを使用しなくて済むのでお勧めです。

このテストプロジェクトの Wiki ページに、コマンドラインからプロジェクトを開始する(または単純にテストを実行する)ためのコマンドラインのオプションに関する詳細説明を掲載しました(How to Run the Unity Performance Benchmark Tests(英語))。テストプロジェクト内でプレイヤービルド設定の解析がどのように行われているかについては、UnityPerformanceBenchmark テストプロジェクトの Scripts ディレクトリ内にある RenderPerformancePrebuildStep.cs ファイルをご覧ください。

Test Runner ウィンドウを開く

UnityPerformanceBenchmark を開いたら、Unity エディター内で Unity Test Runner ウィンドウを開く必要があります。

  • Unity 2018.1 をご使用の場合は、メニューを Window > Test Runner の順に進んでください。
  • Unity 2018.2 をお使いの場合は、メニューを Window > General > Test Runner の順に進んでください

Unity Test Runner ウィンドウが、下の画像のように開かれます。

Unity Test Runner にテストが表示された状態

様々な Unity Performance テストが表示されています。これらは、エディターでウィンドウの左上にある「Run」ボタンで実行するか、実際のデバイスまたはプラットフォームでウィンドウの右上にある「Run all in player」ボタンで実行できます。

デバッグのヒント

IPrebuildSetup.Setup メソッド内でコードをデバッグしたい場合は、以下の手順に従ってください。

  1. Visual Studio で IPrebuildSetup.Setup コード内にブレークポイントを設定する
  2. 拡張機能「Visual Studio Tools for Unity」で Unity エディターにアタッチする
  3. エディターで、Unity Test Runner ウィンドウの「Run All」または「Run Select」ボタンを使ってテストを実行する

上記を行うと、必要に応じて Visual Studio デバッガーが、コード中のデバッグ可能な部分でコードの実行を停止できるようになります。

Unity Performance テストの例

Performance テストの例を見ながら、その機能する仕組みを確認して行きましょう。

例:Unity Performance テスト内で Profiler Marker をサンプリングする

[PerformanceUnityTest]
public IEnumerator SpiralFlame_RenderPerformance()
{
	yield return SceneManager
			.LoadSceneAsync(spiralSceneName, LoadSceneMode.Additive);

	SetActiveScene(spiralSceneName);

	// Performance テストオブジェクトをシーン内にインスタンス化する
	var renderPerformanceTest =
		SetupPerfTest<DynamicRenderPerformanceMonoBehaviourTest>();

	// 測定を行う前に、「落ち着く」までの時間を設ける
	yield return new WaitForSecondsRealtime(SettleTime);

	// Performance Test Extension から ProfilerMarkers API を使用する
	using (Measure.ProfilerMarkers(SamplerNames))
	{

		// CaptureMetrics フラグを TRUE に設定する
		// メトリックのキャプチャリングを開始する
		renderPerformanceTest.component.CaptureMetrics = true;

		// MonoBehaviour テストを実行する
		yield return renderPerformanceTest;
	}

	yield return SceneManager.UnloadSceneAsync(spiralSceneName);
}

この例の中で、テストメソッドは SpiralFlame_RenderPerformance と表記されています。メソッドのデコレーター [PerformanceUnityTest] から、これが Unity Performance テストであることが分かります。

UnityPerformanceBenchmark テストプロジェクトに含まれるすべてのテストは、このテストメソッドと同じパターン(以下)に従っています。

  1. テスト用のシーンを読み込む
  2. シーンをアクティブに設定してテストメソッド内でインタラクトできるようにする
  3. DynamicRenderPerformanceMonoBehaviourTest タイプのテストオブジェクトを作成してテストシーンに追加する(これは SetupPerfTest<T> メソッド内で行われます。)
  4. テストオブジェクトのシーンへの読み込み・追加後、シーンが「落ち着く」まで一定時間待機してからサンプルプロジェクトを開始する
  5. Profiler Marker を、Performance Test Extension API によるキャプチャー用にセットアップする
  6. メトリックのキャプチャーを開始する準備が整ったことをPerformance テストに伝える
  7. テストオブジェクト(IMonoBehaviourTest)を yield return してレンダリングループ中にメトリックをキャプチャーする

カスタムのメトリック(Unity の Profiler Marker やフレームカウントや実行時間に当てはまらないメトリック)も、(MonoBehaviour から継承される)RenderPerformanceMonoBehaviourTestBase ベースクラス内でサンプリングされます。

例:カスタムのメトリックを MonoBehaviour スクリプト内でサンプリングする

private void Update()
{
	if (CaptureMetrics)
	{
		FrameCount++;
		SampleFps();
#if ENABLE_VR
		if (XRSettings.enabled)
		{
			SampleGpuTimeLastFrame();
		}
#endif
	}

	if (IsMetricsCaptured)
	{
		EndMetricCapture();
	}
}
private void SampleFps()
{
	Fps = GetFps();
	Measure.Custom(FpsSg, Fps);
	startFrameCount = Time.renderedFrameCount;
}
private void SampleGpuTimeLastFrame()
{
	var gpuTimeLastFrame = GetGpuTimeLastFrame();
	Measure.Custom(GpuTimeLastFrameSg, gpuTimeLastFrame * 1000);
}
public void EndMetricCapture()
{
	CaptureMetrics = false;
#if UNITY_ANALYTICS && UNITY_2018_2_OR_NEWER
	Measure.Custom(startupTimeSg, appStartupTime);
#endif
}

上の例でキャプチャーしているのは、FPS と、GpuTimeLastFrame(XR が有効になっている場合)と、アプリケーションの起動時間(Unity Analytics が有効になっており 2018.2 以降の Unity で実行していて必要な API が利用可能な場合)です。

IsTestFinished プロパティ

最後に、同じ RenderPerformanceMonoBehaviourTestBase ベースクラス内にプロパティ public bool IsTestFinished が実装されていることにご注目ください。RenderPerformanceMonoBehaviourTestBase は IMonoBehaviourTest インターフェースを実装するため、このプロパティの実装が必要となります。

このプロパティは重要です。Unity Test Runner はこれを使ってテスト停止のタイミングを知るからです。値が True である場合はテストが終了します。Unity Test Runner がテストを終了するタイミングを決定するためのロジックを実装するかどうかはあなた次第です。

例:IsTestFinished プロパティ内でカスタムのメトリックをサンプリングする

public bool IsTestFinished
{
	get
	{
		bool isTestFinished = false;

		if (IsMetricsCaptured)
		{
			Measure.Custom(objCountSg, RenderedGameObjects);
			Measure.Custom(trianglesSg, Tris);
			Measure.Custom(verticesSg, Verts);
			isTestFinished = true;
		}

		return isTestFinished;
	}
}

この最後の例では、テストの終了時に、シーン内にレンダーされたゲームオブジェクトとトライアングルと頂点の数をキャプチャーします。

SampleGroupDefinition

以上、メトリックをサンプリングするために Performance Testing Extension への呼び出しを行う方法が理解できたところで、その設定方法をまずご説明します。

Measure.* メソッドは基本的に、SampleGroupDefinition というパラメーターとして構造体を 1 つ取ります。新しい SampleGroupDefinition を作成する際に、収集したいサンプル用のいくつかのプロパティを定義します。

例:新しい SampleGroupDefinition を GpuTimeLastFrame 用に定義する(サンプリング単位はミリ秒、最小値を使ってサンプルを集計)

下記は GpuTimeLastFrame 用の SampleGroupDefinition です。サンプルを収集して GpuTimeLastFrame 用に集計する方法が、これによって Performance Testing Extension に伝えられます。

この SampleGroupDefinition は動的シーンのレンダリングパフォーマンステストの例から取ったものなので、ここでは、収集された最小値を使用してサンプルを集計する方法を採っています。しかしなぜ、中央値や平均値などの、より一般的な集計基準を用いないのでしょうか?

その理由は、シーンが動的だからです。動的シーン内ではレンダリングに変化が生じるので、中央値や平均値による集計を使用すると信頼性が低くなり、同じシーンを同じコードで実行しても一貫した結果が得られません。動的シーンで特定のレンダリングメトリックの単一の集計をトラッキングしたい場合、この方法が大体においては最も適しています。しかし、これと似た SampleGroupDefinition を静的シーン用に定義する場合は、もちろん中央値による集計を用います。

new SampleGroupDefinition(GpuTimeLastFrameName, SampleUnit.Millisecond, AggregationType.Min)

例:FPS 用の新しい SampleGroupDefinition を定義する(サンプリング単位は none、中央値を使用してサンプルを集計、値が大きくなるほど良い)

下記は FPS(1 秒当たりのフレーム数)用の SampleGroupDefinition です。FPS には固有の測定単位がなく、単純に FPS なので、ここでは SampleUnit.None を指定します。ここでは中央値による集計を使用します。これは静的なシーンなので予測不能なレンダリング体験が起こる心配はありません。しきい値 15% をサンプリンググループ用に明示的に確立しており、FPS が増加するのは望ましい事なので、increaseIsBetter 引数に True を渡しています。

コマンドラインから実行した場合、最後の 2 つの引数はパフォーマンステスト結果の .xml ファイル内に収集・保存され、後にベンチマークを確立するために Unity Performance Benchmark Reporter 内で使用できます。

new SampleGroupDefinition(FpsName, SampleUnit.None, AggregationType.Median, threshold: 0.15, increaseIsBetter: true)

テストが完了すると、先に有効にしたすべてのメトリックサンプルが Performance Testing Extension によって集計されます。

各種測定メソッド

各種コード例の中では以下の 2 つの Unity Performance Testing Extension API を使用しています。

  • Measure.ProfilerMarkers
  • Measure.Custom

Unity Performance Testing Extension は、Unity でパフォーマンスを測定したい対象と方法に応じた特定のニーズに対応すべく、この他の測定メソッド(以下を含む)も提供しています。

  • Measure.Method
  • Measure.Frames
  • Measure.Scope
  • Measure.FrameTimes

各種測定メソッドについての詳細は Unity Performance Testing Extension に関するドキュメンテーション(英語)の「Taking measurements」の項をご覧ください。

Unity Test Runner でパフォーマンステストを実行する

以上、Unity Test Runner と Unity Performance Testing Extension を使ったパフォーマンステストの記述方法の例をいくつかご紹介しました。次に、この実行方法をご説明します。

パフォーマンステストの主な実行方法は以下の 2 つです。

  1. コマンドラインから -runTests オプションで Unity を起動する方法。Unity Performance Test Extension が結果の .xml ファイルを生成し、それを Unity Performance Benchmark Reporter 内で使用して結果の表示と比較を行えるので、パフォーマンステスト用にはこの方法が推奨されます。
  2. エディター内から直接実行する方法。これは以下の場合に有用です。
    a. 単純にテストを実行して Unity Test Runner ウィンドウで結果を確認したい場合(後の使用のために結果をキャプチャーする必要がない場合)
    b. テストが正常に実行されるか、あるいはテストコードのデバッグが必要かを検証したい場合

-runTests コマンドラインオプションを使用してパフォーマンステストを実行する

コマンドラインから Unity Test Runner でパフォーマンステストを実行する方法として、2 つの例をご紹介します。これらは上記の、UnityPerformanceBenchmark プロジェクトをコマンドラインから開く方法の説明の中でご紹介した例と同じものを基に作成しているので、見覚えがあると思います。

例:Windows から Android プレイヤーを対象に UnityPerformanceBenchmark パフォーマンステストを実行する

ここでは、Windows で Unity を起動して「OpenGLES3 グラフィックス API、マルチスレッドレンダリング、Mono スクリプティングバックエンド」の設定で Android 向けにビルドしています。

Unity.exe -runTests [-batchmode] -projectPath
C:\XRAutomatedTests-2018.2\PerformanceTests\UnityPerformanceBenchmark -testPlatform Android -buildTarget Android -playergraphicsapi=OpenGLES3 -mtRendering -scriptingbackend=mono -testResults
C:\PerfTests\results\PerfBenchmark_Android_OpenGLES3_MtRendering_Mono.xml -logfile
C:\PerfTests\logs\PerfBenchmark_Android_OpenGLES3_MtRendering_Mono_UnityLog.txt

例:OSX から iOS プレイヤーを対象に UnityPerformanceBenchmark パフォーマンステストを行う

ここでは、OSX で Unity を起動して「OpenGLES3 graphics API、マルチスレッドレンダリング、Mono スクリプティングバックエンド」の設定で iOS 向けにビルドしています。また、iOS デバイスにデプロイするために必要な Apple Developer Team ID および Provisioning Profile の情報も提供しています。

./Unity -runTests [-batchmode] -projectPath /XRAutomatedTests-2018.2/PerformanceTests/UnityPerformanceBenchmark
-testPlatform iOS -buildTarget iOS -playergraphicsapi=OpenGLES3
-mtRendering -scriptingbackend=mono
-appleDeveloperTeamID=
-iOSProvisioningProfileID= -testResults /PerfTests/results/PerfBenchmark_Android_OpenGLES3_MtRendering_Mono.xml
-logfile /PerfTests/logs/PerfBenchmark_Android_OpenGLES3_MtRendering_Mono_UnityLog.txt

これらの例は両方とも新しいコマンドラインオプションを 3、4 つ使用しており、このおかげで、IPrebuildSetup.Setup メソッドで利用可能なコマンドライン引数で単に Unity エディターを開くだけではなく、テストを実行することが可能になっています。

-runTests
このオプションが、Unity Test Runner にテストを実行するように命じます。

-testResults
このオプションは、Unity Test Runner がパフォーマンステストの結果を保存するべき .xml ファイルの名前とパスを指定します。

-logfile
このオプションは、Unity エディターがログを記述するべきファイルの名前とパスを指定します。この使用は任意ですが、Unity エディターのログファイルに簡単にアクセスできるのであれば、不具合や問題の調査に非常に有用です。

-batchmode
このオプションは、Unity エディターを強制的に Headless モードで開きます。単純にプレイヤーパフォーマンステストを実行したいだけで Unity エディターウィンドウを開く必要がない場合に使用します。自動化されたテストの実行時間が短縮できる場合があります。このオプションを使用していない場合は、テストの実行前に Unity エディターが画面上に開かれます。

Unity では継続的インテグレーションシステム内で、多くの場合バッチモードで、コマンドラインからパフォーマンステストを実行します。

例:コマンドラインから UnityPerformanceBenchmark テストを実行する

Unity エディター内でパフォーマンステストを実行する

再生モードが選択されており、上部近くに Unity Test Runner ウィンドウが開いた状態で、以下が表示されます。(再生モードのテストはビルドプレイヤーまたはエディターの PlayMode ウィンドウで実行されます。)

  1. Run All ― このボタンをクリックすると PlayMode タブ内のすべてのテストが実行されます。
  2. Run Selected ― このボタンをクリックすると、選択されたテストまたはノードと、その下のすべてのテストが実行されます。
  3. Run all in player ― このボタンをクリックすると、Unity エディターが、ビルド設定に設定されたタイプのプレイヤーをビルドし、そこでテストを実行します。
重要な条件
Unity エディターで Test Runner ウィンドウからパフォーマンステストを実行した場合、Unity Performance Benchmark Reporter が必要とする、結果の .xml ファイルが生成されません。

パフォーマンステストの完了時に結果の .xml ファイルを作成したい場合は、-runTests コマンドラインオプションを使ってコマンドラインから Unity を起動してテストを実行する必要があります。ただし、-runTests コマンドラインオプションを使って Unity を実行している場合、エディターが開いてテストの実行を開始しますのでご注意ください。

結果の .xml ファイルにはテストの実行結果とメタデータが含まれます。Unity Performance Benchmark Reporter がそれを使用してベンチマーキング結果を作成し、後続のテストとの比較を行います。

例:Unity エディターでパフォーマンステストを実行する

パフォーマンステストの結果を表示する

これらのテストをエディター内で実行した場合、各テストを選択すると、Unity Test Runner ウィンドウの最下部近くに集計値が表示されます。

例:Unity Test Runner からパフォーマンステストのサンプリング集計を表示する

コマンドラインから実行した Unity Performance テストの結果を確認したい場合は、Unity Performance Benchmark Reporter を使用する必要があります。(単純に結果の .xml ファイルを開いても確認は可能ですが、読み易くはありません)。

それでは、Unity Performance Benchmark Reporter を使って結果を閲覧・比較する方法を見て行きましょう。

Unity Performance Benchmark Reporter を使用する

Unity Performance Benchmark Reporter を使用すると、(Unity Test RunnerUnity Performance Testing Extension の併用によって生成される)パフォーマンスメトリックのベースラインと以降のパフォーマンスメトリックを、ビジュアライゼーションを用いた HTML レポートで比較することができます。

このレポーターは、.NET 対応の各種プラットフォーム(Windows、OSX など)で実行できるように .NET Core 2.x アセンブリとして作成されています。したがって、実行するには .NET Core SDK のインストールが必要となります。

Unity Performance Benchmark Reporter を実行するには、以下のように .NET コマンドラインでアセンブリを呼び出す必要があります。

dotnet UnityPerformanceBenchmarkReporter.dll
--baseline=D:\UnityPerf\baseline.xml
--results=D:\UnityPerf\results --reportdirpath=d:\UnityPerf

レポーターの実行後、HTMLレポートとその補助ファイル(.css、.js、画像ファイル)を含んだ UnityPerformanceBenchmark という名前のディレクトリが作成されます。HTML レポートを開いて、結果の .xml ファイル内で、キャプチャーされたパフォーマンスメトリックのビジュアライゼーションを閲覧できます。

コマンドラインオプション

--results
HTML レポートに含まれることになる(1 つまたは複数の、ベースライン以外の)結果の .xml ファイルがあるディレクトリへのパスです。

最低 1 つの --results の値が UnityPerformanceBenchmarkReporter.dll アセンブリに渡される必要があります。必須のフィールドはこれだけです。

このコマンドラインオプションは、特定の 1 つのベースライン以外の .xml 結果ファイルへのパスを指定するのにも使用できます。また、このオプションを以下のように反復的に使用すれば、複数のディレクトリやファイルを指定することもできます。

--results=D:\UnityPerf\results --results=D:\UnityPerf\results.xml

--baseline
他のファイルを比較する時に使用される .xml 結果ファイルへのパスです。

--reportdirpath
レポーターがパフォーマンスベンチマーキングレポートを作成するディレクトリへのパスです。これは UnityPerformanceBenchmark サブディレクトリ内に作成されます。

レポートの場所が指定されていない場合は、UnityPerformanceBenchmarkReporter.dll が呼び出された作業ディレクトリ内に UnityPerformanceBenchmark サブディレクトリが作成されます。

パフォーマンステストの結果を比較する

パフォーマンステストの結果を Performance Benchmark Reporter で比較してみましょう。

例:VR 向けの Gear VR シーンの設定を変更してフレームレートを向上させる

ここに、ひとつの Unity シーンがあります。このシーンの複雑度は以下のようになっています。

  • オブジェクト 732 個
  • トライアングル 95,898 個
  • 頂点 69,740 個
Gear VR シーン

マルチパスステレオレンダリングで 60 FPS 近くを維持できそうかどうか検証するため、このシーンサンプリングメトリックに対して Unity Performance Test を実行します。次に、そのテスト結果をもって Performance Benchmark Reporter を実行します。

この結果、FPS が 30 FPS 近く(つまり目標の半分)になることが分かりました。

次に、60 FPS にどれだけ近付けられるか検証するために、シングルパスマルチビューステレオレンダリングを使用してみます。設定を変更したパフォーマンステストを戻し、Unity Performance Benchmark Report をもうひとつ作成して、最初の結果と新しい結果を比較します。

マルチパスからシングルパスマルチビューステレオレンダリングに切り替えた結果

シングルパスマルチビューレンダリングへの切り替えによって FPS が 37 に向上しました。Gear VR で目立ったフレーム落ちなしでシーンを実行したいのであれば、まだ更に 60 FPS に近付ける必要があります。

最後に、シーン内の回転キューブの数を削減して FPS を高くできるかどうか検証してみます。

何度か試みた結果、最高 55 FPS までパフォーマンスを向上させることができました。しかし、シーン内のオブジェクト数を 732 から 31 に減らす必要がありました。これはかなりの数です。

今後、他にもパフォーマンスを最適化し得る改善策を講じることにしますが、差し当たっては、これを FPS のベースライン(基準値)として使用します。今後はこれをベンチマークとして扱い、ここから改善を目指します。

VR シーンの FPS をより理想に近づける

ベンチマークの確立とパフォーマンスの変化のトラッキング

ベンチマークを確立する意味は、プロジェクトによって様々です。ここでは、Unity でパフォーマンステストを実行する目的は、各種結果のベースライン(それまでに最も良い結果が検証されたパフォーマンスメトリックの組み合わせ)を確立し、その後に変更を加えながら行うテストの実行結果をそれに照らし合わせて比較できるようにすることです。これがベンチマークとなります。

一つ前の項では結果的に「Gear VR 用のシングルパスマルチビューステレオレンダリングを使用してシーンのオブジェクト数を削減する」という設定で「許容できる範囲の」FPS の実現に至りました。その時点で、私はそのテスト結果をベンチマークとして使用することに決定しました。ここでひとつ例を挙げ、プレイヤーの設定に更に変更を加えるに当たり、このベンチマークをどのように使用して行けるかをご説明しましょう。

例:パフォーマンスベンチマークを使って、設定の変更によるパフォーマンス低下を確認する

シーンのアンチエイリアシングを有効にして見た目を滑らかにすしたいと思います。Unity の Android 用のクオリティー設定はデフォルトではアンチエイリアシングが無効になっていますが、これを有効にしても、この Gear VR シーンにとって許容できるレベルの FPS が保てるかどうか、検証してみましょう。

まず、IPrebuildSetup.Setup メソッド内のアンチエイリアシングの値を 4 に設定します。

QualitySettings.antiAliasing = 4;

次に、Gear VR 対応の Android 端末で、先に行ったパフォーマンステストを再度実行します。そして、Unity Performance Benchmark Reporter を使用して、この実行結果を先に確立したベンチマーキング結果と比較します。

アンチエイリアシングの値を 4 に設定した後のFPS の低下を検知する

ところが、ご覧ください。Unity プレイヤーの設定をアンチエイリアシング値 4 に変更したら、FPS が 32 に低下してしまいました。これでは、元々 732 個のオブジェクトでこのシーンを作成した当初とほぼ変わりません。

しかし諦めてしまう前に、アンチエイリアシングの値を低くして、許容できるレベルの FPS に戻せるかどうか何度か試してみたいと思います。アンチエイリアシングを 2 に設定した場合と、最後に 1 に設定した場合とで試しました。結果は以下の画像のようになりました。

アンチエイリアシングの値を減少させて、このシーンにおいて許容できるレベルの FPS への回復を試みる

Unity プレイヤーの設定を、最終的に変更にコミットすることなく「試しに変更」し、先に確立したパフォーマンスベンチマークを使って、パフォーマンスへの影響を検証することができました。

アンチエイリアシングの値を 1 に設定した場合、FPS の変動はデフォルトのしきい値である 15% 内に収まっていますが、FPS が 49 になっており、VR 向けのシーンでの目標である 60 FPS からの差が少々大きすぎます。今日のこの変更はコミットしないほうがいいでしょう。

まとめ

Unity は苦労せずにハイパフォーマンスを実現できることに重点を置いて取り組んでいます。しかし、最終的に「すべてのプラットフォームでスムーズでパフォーマンスの高いプレイ体験が提供され、ユーザーがゲームを気に入って楽しんでくれる」という結果は Unity エンジンだけによって実現されるものではありません。常に高パフォーマンスなプレイ体験を実現するには、例えば、パフォーマンスを低下させない高い機能を持った SDK やドライバー、Unity パッケージなどが必要不可欠です。

本記事では、パフォーマンスメトリックの収集とそれを使ったベンチマークの作成を簡単に行える Unity ツール(Unity Performance Testing Extension と Unity Performance Benchmark Reporter)についてご紹介しました。これらのツールでどんなことが可能か、ご自分のプロジェクトでパフォーマンスの向上にどのように役立てられるか、ぜひ試しにお使いになってみてください。

本記事では以下の事柄をご説明しました。

  • Unity Test Runner を使って、プロファイラーその他のメトリックをサンプリングするパフォーマンステストを記述する方法
  • Unity Test Runner でパフォーマンステストを実行する各種方法
  • パフォーマンステストを繰り返し実行しながら、Unity Performance Benchmark Reporter でパフォーマンスメトリックの分析・比較を行いつつ改善を目指す方法

各種メトリックの基準値を確立し、それを用いてシーンやゲーム、SDK、ドライバー、パッケージ、その他の Unity インテグレーション向けにベンチマークを作成することで、特定の修正がもたらす影響をより明確に把握できるようになるはずです。

今回、様々なアイデアやテスト、開発、イテレーションのサポートで貢献してくれた、以下の Unity の仲間達に感謝を述べたいと思います。ありがとうございました。

  • Qi Jiang
  • Sakari Pitkänen
  • Gintautas Skersys
  • Benjamin Smith
2018年9月25日 カテゴリ: Engine & platform | 22 分 で読めます

Is this article helpful for you?

Thank you for your feedback!

取り上げているトピック
関連する投稿