- はじめに
- Grapchics Jobsが機能するUnityのバージョンについて
- boot.config
- GraphicsJobMode
- RenderingThreadingMode
- 組み合わせ一覧
- まとめ
はじめに
皆さん、Graphics Jobs 使っていますか? この機能、簡単に説明すると 描画処理にJob Systemを使用してアプリケーションのパフォーマンスを向上させる機能 です。 この機能の歴史は古く、Unity5.6の頃には既にあったと思いますが、いまだにExperimentalが付いたままである事からの非常に難産である事が判ります。(スタンドアローンなど、一部のプラットフォームではExperimentalが外れているようではあります)Unity2018.4.23f1 Relese Note 解説にも記載しましたが、実は、Unity2018、2019、2020において何時の頃か判りませんが、ProjectSettingsで有効にしていた場合でも機能が無効となっていました。
そこで今回はGraphics Jobsについて改めて検証をおこないました。
だらだら書いているので、組み合わせ一覧とまとめを見るだけでもOKですが、順に読むことで理解が深まります。
Grapchics Jobsが機能するUnityのバージョンについて
リリースノートに記載されている下記が該当するissueです。
Graphics: Fixes an issue where graphics settings were written to boot.config incorrectly. (1236936)
このissueは下記のバージョンで修正されています。
- 2018.4.23f1
- 2019.3.14f1
- 2020.1.0b8
- 2020.2.0a9
Graphics Jobsの機能を試してみる場合は必ずこのバージョン以降をご使用下さい。
boot.config
issueの内容としては、「boot.configに記述されたGraphics Settingsの内容が間違っていた。」とありますが、boot.configとはどこにあり、どう間違っていたのかを確認します。
boot.configの在りか
boot.configがプロジェクトをビルドする際に作成されます。 いきなりバイナリを作成するのではなく、一度各プラットフォーム用のプロジェクト形式へエクスポートすると確認しやすいと思います。
- Androidの場合
{GradleProject}/unityLibrary/src/main/assets/bin/Data/boot.config
- iOSの場合
{XcodeProject}/Data/boot.config
boot.configの中身
PlayerSettingsからGraphics jobsにチェックを入れた状態でプロジェクトをビルドすると、2019.3.13と2019.3.14では下記の部分に差分があります。
2019.3.13f1
gfx-enable-gfx-jobs= gfx-enable-native-gfx-jobs=
2019.3.14f1
gfx-enable-gfx-jobs=1 gfx-enable-native-gfx-jobs=1
どうやら、1を書き忘れていた為、機能が有効になっていなかったようです。 正直、Unityをバージョンアップしなくてもboot.configの記述さえ修正すればGrapchics Jobsは機能しているように見えますが、それは誰も保証できませんので自己責任でお願いします。
なお、Multithread Renderingにチェックを入れなかった場合、 2019.3.13f1
gfx-disable-mt-rendering =
2019.3.14f1
gfx-disable-mt-rendering = 1
と同様の修正が行われているのですが、こちらに関しては2019.3.13f1でも機能の切り替えは正常に動作していることを確認しました。この辺りの動作の違いは謎です。
また、変数名にdisable
と命名するのも落ち着かないので止めて頂きたいです。
gfx-jobsがGraphics Jobsの略称であるのは何となく想像がつくのですが、gfx-enable-gfx-jobsと gfx-enable-native-gfx-jobsの2種類が存在します。nativeとは一体なんのことでしょうか・・・・。
GraphicsJobMode
調査して判明したのですが実はこれは、GraphicsJobModeを指しています。
PlayerSettingsにはgraphicsJobModeという変数が存在するのですが、こちらにGraphicsJobMode.Native
またはGraphicsJobMode.Legacy
を設定します。
docs.unity3d.com Unity - Scripting API: GraphicsJobMode
GraphicsJobMode.Native
を指定するとboot.configにはgfx-disable-mt-rendering = 1
が記述され、GraphicsJobMode.Legacy
を指定すると記述が消えます。
このことから、Grapchics Jobsは有効・無効の2種類ではなく、 - Native - Legacy - 無効 の3種類であるということが判りました。
なお、PlayerSettings.graphicsJobModeにはGUIは存在しませんのでScriptから設定する必要があります。
RenderingThreadingMode
PlayerSettings.graphicsJobModeに関しては、Google先生に聞いてもほぼ情報が無い状態ですが、UnityのScripting APIでSystemInfo.renderingThreadingModeという変数の説明で下記のように記述されていました。
pplication's actual rendering threading mode (Read Only).
Rendering threading mode is decided during the Unity application startup, according to the combination of Player Settings PlayerSettings.MTRendering, PlayerSettings.graphicsJobs and PlayerSettings.graphicsJobsMode, as well as according to the target platform capabilities.
ようは、 Mulithread Rendering、Graphics Jobs、Graphics Jobs Modeの3種類の変数の組み合わせで、Rendering Threading Modeの組み合わせが確定するようです。
Graphics Jobs登場時のUnity Blogでは下記のようにMultithreaded Rendering
と Graphics Jobs
を同時に有効にするなと記載されていますが、時代は変わったようです。
注意 ― Android をターゲットにするとき、“Multithreaded Rendering” と “Graphics Jobs (Experimental)” 設定を絶対に同時には有効にしないように気を付けてください。その 2 つは互いに排他的なので、最終リリース版では、Graphics Jobs を有効にすると、警告なしに Multithreaded Rendering は無視されるようになります。
RenderingThreadingModeには全6種類のモードが存在します。 以下各モードを解説します。
RenderingThreadingMode.Direct
MainThreadから直接Graphic Commandを実行します。 シングルスレッドで実行される為、安定しています。コア数が1のデバイスはどのモードを指定してもこのモードにフォールバックされるようです。
RenderingThreadingMode. MultiThreaded
MainThreadから中間コマンドを作成し、RenderThreadからも参照出来る共有バッファへ書き込みます。 RenderThreadは共有バッファの内容からGraphic Commandを実行します。
iPhone7以前のようなCore数が少ない(2コア程度)の端末に適している傾向にあります。
RenderingThreadingMode.LegacyJobified
複数のWorkerThreadが中間コマンドを作成し、共通バッファに書き込みます。 RenderThreadが共通バッファの内容を元にGraphic Commandを実行します。 MultiThreadedでMainThreadが行っていた内容をWorkerThreadで行うように改良したモードです。
ユーザースクリプトの処理が長い等、コア数が多く、MainThereadを少しでもあけたい場合はこのモードが有効です。 (2コアであれば、MultiThreaderの方がパフォーマンスが高い傾向にあります。) Androidではサポートしておらず、このモードを選択した場合はNativeGraphicsJobsへフォールバックします。
RenderingThreadingMode. NativeGraphicsJobs
MultiThreadedで行っていたRenderingThreadの処理をWorkerThereadへ分散したモードです。 RenderingThreadの処理が長い場合、WorkerThreadに処理を逃がすことが出来る為、コア数が多い端末ではパフォーマンスの改善を見込めます。
RenderingThreadingMode. NativeGraphicsJobsWithoutRenderThread
DirectでMainThreadが行っていたGraphicAPIの発行処理をWorkerThreadへ分散するモードです。 中間コマンドを作成せず、複数のスレッドで直接Graphics Commandを発行する為、処理の改善効果が期待出来ます。
組み合わせ一覧
各Rendering ThreadingMode に切り替える為のMultiThread Rendering、Graphics Jobs、Graphics Jobs Modeの組み合わせと対応するプラットフォームの表です。 〇の後ろに続く括弧の中身は必須のGrapchics APIです。 また、Development Buildを有効にしてビルドを行った場合、デバッカ等を使用して実行時に引数を指定することで強制的にモードを切り替えることが可能です。
Rendering ThreadingMode | MT Rendering | Graphics Jobs | Graphics Jobs Mode | 引数 | Android | iOS |
---|---|---|---|---|---|---|
Direct | OFF | OFF | - | -force-gfx-direct | 〇 | 〇 |
SingleThreaded | - | _ | - | -force-gfx-st | 〇 | 〇 |
MultiThreaded | ON | OFF | - | -force-gfx-mt | 〇 | 〇 |
LegacyJobified | ON | ON | Legacy | -force-gfx-jobs legacy | × | 〇(Metal) |
NativeGraphicsJobs | ON | ON | Native | -force-gfx-jobs native | 〇(Valkan) | 〇(Metal) |
NativeGraphicsJobsWithoutRenderThread | OFF | ON | - | -gfx-enable-gfx-jobs -gfx-disable-mt-rendering | 〇(Valkan) | 〇(Metal) |
※ SingleThreadedはMultiThreadedののデバックバージョンで、RenderThreadで行っていた処理をMainThreadで処理します。