simplestarの技術ブログ

目的を書いて、思想と試行、結果と考察、そして具体的な手段を記録します。

Unity:安全な並列処理をする C# Job System について学ぶ

Unity の GDC2018 の英語発表見てるけど、長いな
まずは椿さんことUnityエヴァンジェリストの山村さんのブログ読んでどういう話なのか、知識を増やします。
tsubakit1.hateblo.jp

確かに、過去に Task とスレッドセーフキューを使った実装で、大量のブロックの相互作用をメインスレッドを停止させずに動かしたことありましたね。
simplestar-tech.hatenablog.com

これは確かにメインスレッドは結構余裕をもっていて、バックグラウンド処理が休みなく働いているイメージでした。
C# Job System はメインスレッドも休みなく働くようにスケジューリングできそうです。

Burstコンパイラ
(出典は山村さんのツィート)
scrapbox.io

1Tweetで分かる?Burstコンパイラ
・Mono、IL2CPPに並ぶ第三のコンパイラ
・厳しい条件指定のあるC#下(No GC,Noクラス,Noボクシング,No 例外処理)で最適化したアセンブラを吐く
・吐いたアセンブラはプレビュー出来る
SIMD で最適化 ・数字の精度を落としてさらに高速化

確かに高速になる機械語に翻訳してくれそうなルールですね。

この Burst コンパイラですが
手元の Unity 2018.2.2f1 は、プレビュー版ですが、Package Manager から有効化することができます。
ってことは、使い始めることは出来るってことですね(高速化試したい)

f:id:simplestar_tech:20180821073030j:plain

きっとそうだろうと思ったけど C# Job System では Collider や gameObject が取得できない
え、じゃあ RayCast とかもだめ?

それが C# Job System 用に RaycastCommand が作られているそうです。
Unity - Scripting API: RaycastCommand

なるほど、書式イメージは

1.入力作成
2.並列処理
3.結果利用

の3ステップですね。

■ NativeArray

あ、もしかして GCHandle.Alloc, handle.AddrOfPinnedObject を使わなくてもポインタ利用できる配列ってやつですかね?
ちょっと前 OpenCVC++のまま Unity で使う例を示した時に、WebCamTexture を cvMat として扱う時に使ってたやつです。
simplestar-tech.hatenablog.com

fixed いらずで unsafe ポインタを取得できるって、やるぅ!(C++のようにメモリの順番を使ったコード書ける!やった)
Unity - Scripting API: Unity.Collections.LowLevel.Unsafe.NativeArrayUnsafeUtility.GetUnsafeReadOnlyPtr

OnEnable で永続確保、OnDisable で Dispose による開放を行うのが良さそう

■ IJobParallelFor

並列処理するジョブはこのインタフェースを継承して、処理を実装するだけでよい
後は以下に紹介されている例を参考に Schedule, Complete の呼び出しで並列処理が完了する
Unity - Scripting API: IJobParallelFor

ひとまず書式は学べたし、並列処理を行えることも確認できました。

後半の
メッシュの変形やCubeの移動、ポイントクラウドや当たり判定
のデモの紹介が気になった。
github.com

今度はこちらを読むことにします。