テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】ECSの並列処理"IJobProcessComponentData"におけるスケジューリングの挙動

デカイ記事を書こうとして中々更新まで辿り着かないので、今回はサクっとECSの並列処理におけるスケジューリングの挙動について書いておきます。

 

ECSは参照するComponentDataでスケジュールが決まる

ECSのIJobProcessComponentDataを使用すると、特に面倒くさい事を考えなくとも良い感じにスケジューリングしてくれます。
どういった感じにスケジューリングされるのか見ていきます。


異なるComponentDataへアクセスするジョブは並列処理する

まず異なるComponentDataへアクセスするジョブは、並列で処理されます。
下の例ではSampleData1とSampleData2という異なるComponentDataへアクセスしている場合の挙動です。

gist.github.com

実行してみると、2つのジョブが並列で実行されるのが確認出来ます。

f:id:tsubaki_t1:20181023234353j:plain

これは複数のJobHandleを合成した場合も同様です。
例えば下のコードではSampleData1とSampleData2に対しての処理と、SampleData3とSampleData4に対する処理を呼び出します。
結果、全て並列で処理されました。

gist.github.com

f:id:tsubaki_t1:20181024000456j:plain

同じComponentDataへアクセスするジョブは並列処理されない

一方、同じComponentDataへアクセスしている場合。この場合は並列処理されず、片方の終了を必ず待ちます。
下のコードでは2つのシステムがComponentDataへアクセスしているので、並列で処理されることはありません。

gist.github.com

これは片方がReadOnlyだった場合も同様です。

f:id:tsubaki_t1:20181023234637j:plain

またJobHandleをまとめた場合、中にReadWriteが一つでもあれば分割されます。
下のコードではまとめたJobHandleの一つがReadWriteなので、処理が分割されています。

gist.github.com

f:id:tsubaki_t1:20181024000846j:plain

ReadOnlyのComponentData同士は並列でアクセスになる

同じComponentDataにアクセスしている場合でも、ReadOnlyの場合は同時にアクセスが可能です。

gist.github.com

f:id:tsubaki_t1:20181023235251j:plain

 

感想

ということで並列処理の動作を見てみました。
ECSで「単一の動作を突き詰める」ようなデモを作ろうとすると、頑張って並列化を推し進めようとします。ただ、そこまで頑張らなくともジョブを発行しまくってたら意外とWorker Threadがジョブで埋まるねという感想

とりあえずJobHandleで依存関係を勝手に作ってくれるのは楽で良いです。