最初に
この記事はUnity2018.x系の目玉機能であるC# JobSystemについて簡単に概要をまとめたものとなります。
C# Job Systemとは?
C# Job Systemとは並列処理を行うための機能です。アプリ等の実行端末が持つCPUのコアをフル活用するために使用されます。時間のかかる処理の負荷を複数コアに分散し、コアの性能を十分発揮させてメインスレッドへの負荷を減らしてフレームレートの大幅な向上ができます。また、端末自体のバッテリー消費を軽減する効果も期待できます。
元々Unity自体、内部処理を並列処理で行なっており、元からコアを使用してはいたが、C# Job Systemによって自作するC#スクリプトもコアをフル活用できるようになりました。
ここでいう並列処理とは
実行の順番や実行タイミングを気にしないで処理をスレッドに詰めるだけ詰めて行うことです。
デメリットとしては、デッドロックや、データの受け渡しがあるとそこがボトルネックとなるので気にする必要があります。
C# Job Systemの特徴
- 簡潔にコードを書くことができる。
- オーバーヘッドが低い。
- コンテキストスイッチの増加を防ぐ。
- Burstコンパイラ向けに最適化される(GC使用不可)。
- 値型しか扱えない。
- エディタではメモリリークやデッドロックが起きないよう監視を行なっているようでビルド前とビルド後でパフォーマンスに大きな差がある。
- ロックやタイミングの同期、データの受け渡しはできない。
- ECSと連携可能。
- .NETやUnityのAPIはJob内では基本使えない。
C# Job Systemは基本的に算術系を高速化するのに使用する。
例えばユニット同士の相互距離計算や、ソート、シューティング系統…。
Job Systemの流れ
Job SystemはJobを作成して、Job queueに入れ、実行します。Job System内のWorker threadはqueueからJobを取り出して実行します。Job Systemは依存関係を管理しているため、Jobが適切な順序で実行されるようにします。このため、Job自体は自己完結型でも他のJobに依存しても問題ありません。例えばJobBがJobAに依存している場合はJobAが完了するまでJobBは実行開始されないことが保証されます。
1.NativeContainer系で入力・出力のバッファを用意する
2.入力バッファの中身を埋める
3.メインスレッドからSceduleを実行して、JobSystemにジョブを発行
4.メインスレッドにてCompleteで終了まで待つ
5.結果を出力バッファから受け取る
Jobの定義方法
基本的にはIJobを継承するstructを定義してExecuteに処理を書くことで動作します。
ただし、マルチスレッドに分散する場合はIJobParallelForを使用します。この辺はまた別の記事で紹介できればと。