【Unity】Profilerで処理落ちの原因がメインスレッドなのかレンダースレッドなのかGPUなのか切り分ける手順

UnityのProfilerで処理落ちの原因がメインスレッドなのかレンダースレッドなのかGPUなのか切り分ける手順についてまとめます。

Unity2020.2.7f1

パフォーマンスチューニングの一番最初にやるべきこと

ゲームにおける処理落ちの原因は、大きくCPUに起因するものとGPUに起因するものに分類できます。
さらにUnityでは、CPUでいくつかのスレッドを使って処理を行っています。
これらのスレッドのうち処理落ちの原因として挙がりやすいのが、メインスレッドとレンダースレッド(GPUに送る描画情報を設定するスレッド)です。

したがって、パフォーマンスチューニングを行う際には何よりもまず、
処理落ちの原因がメインスレッドなのかレンダースレッドなのかGPUなのかを切り分けるべきです。

この記事ではUnityのProfilerを使ってこれを分析する方法についてまとめます。

なおProfilerの基礎知識を前提としますので、必要に応じて以下の記事を参照してください。

light11.hatenadiary.com

メインスレッド vs レンダースレッド・GPU

まず、処理負荷がメインスレッドのものなのか、あるいはレンダリング処理によるものなのかを切り分けます。
ここでいうレンダリング処理とは、レンダースレッドの処理とGPUによる処理をまとめたものを指します。

ProjectSettingsからVSyncをOffにしたうえでProfilerを開き、CPUの処理負荷が高い部分の詳細を見ます。
以下の例ではメインスレッドがGfx.WaitForPresentOnGfxThreadという処理に時間を割いていることがわかります。

f:id:halya_11:20210522162226p:plain
Gfx.WaitForPresentOnGfxThread

これは「レンダースレッドにレンダリング情報を送りたいけどまだ前回のレンダリング処理をしているから待っている状態」です。

このようにメインスレッドのGfx.WaitForPresentOnGfxThreadの処理時間が長かったらレンダリング処理に時間が掛かっていると判断できます。

レンダースレッド vs GPU

前節で処理負荷がメインスレッドのものなのかレンダリング処理によるものなのかを切り分けました。
レンダリング処理が原因であるとなった場合、次にやるべきことはレンダースレッドとGPUのどちらに負荷がかかっているかを見極めることです。

これはまずレンダースレッドについて分析するのが手っ取り早いです。
レンダースレッドに処理負荷がかかっている状態というのはたいていセットパスコールが多すぎる場合です。
セットパスコールはGameビューのStatsから見れるのでここを見ます。
これはエディタ上の値とはなりますが、参考になります。

f:id:halya_11:20210523134146p:plain
セットパスコール

処理落ちするときだけこの値が大きくなるようであればレンダースレッドの負荷を疑います。
もう少し分析するにはFrameDebuggerを使うのが良いです。

docs.unity3d.com

FrameDebuggerで異様にドローコールが発行されているところがあればその部分が怪しいです。

もしセットパスコール数に異常がないとすれば、GPUバウンドということになります。

ScneViewをOverdrawモードにしてオーバードローがひどくないか確認してみたり、
主要なGameObjectの表示・非表示を切り替えてFPSの変化を見はったりします。
またXCodeなどの分析ツールを使うことも有効です。

関連

light11.hatenadiary.com

参考

docs.unity3d.com