Native Containerざっくりまとめ
注意点
2019/12/01 時点で調べた内容です。
なに?
- ネイティブメモリ用の比較的安全なC#ラッパーを提供するマネージドな値型。
- NativeContainer は Blittable 型なので C# Job System でも使える。
- Blittable 型についてはこちらの記事が参考になります
【Unity】UnsafeUtilityについて纏めてみる - Qiita
- 管理されていない割り当てへのポインタが含まれている。
- Unity C# Job Systemで NativeContainer を使用すると、ジョブはコピーではなくメインスレッドと共有されるデータにアクセスできる。
安全性
- 安全性チェックは Unity Editor およびPlayモードでのみ使用できる。
- 安全性チェック
- 範囲外チェック
- 割り当て解除チェック
- 競合状態チェック ...etc
- 安全性チェック
- メモリを解放し忘れた場合、かなり時間を経過してメモリリークのエラーが起きる。
種類
- NativeArray
- 配列
- NativeSlice
- NativeArrayから一部のデータを取り出すことができる
- NativeList
- 可変長なNativeArray
- NativeHashMap
- キーと値のペア
- NativeMultiHashMap
- キーごとに複数の値を設定できる
- NativeQueue
- FIFOキュー
Native Container Allocator
NativeContaine のメモリ割り当てタイプを指定できる。
よく使うのはTemp、 TempJob、 Persistentの3つ。
種類
- Invalid
- 無効な割り当て。
- None
- 割り当てなし。
- Temp
- 自分で解放するする必要がある。
- そのフレームのみ有効。
- TempJob
- C# Job Systemで使う前提の一時割当。NativeArrayにDeallocateOnJobCompletion属性を付けるとJob終了時にNativeArrayを自動で解放してくれる。
- そのJob中のみ有効。
- Persistent
- 永続的な割当。
- ComponentやComponentSystemのAwake等のタイミングで作って、OnDestroy等で消す。
- 解放するまで有効。
- AudioKernel
- DSPGraphオーディオカーネルに関連付けられた割り当て。
メモリ確保のコスト
高い
↑
Persistent
TempJob
Temp
↓
低い
使い方
var position = new NativeArray<Vector3>(500, Allocator.Persistent);
NativeArray
C# Job Systemでよく使うであろう NativeArray について説明します。
恩恵
高速に処理が行える。
使い方
NativeArray<Type>(size, Allocator);
- Type
- プリミティブな型かstruct型のみが指定可能。class型は指定不可。
- size
- 生成したい要素数。
- Allocator
- メモリの生存期間。Native Container Allocatorで指定。
void Update() { // 入力バッファを用意 var commands = new NativeArray<RaycastCommand>(target.Length, Allocator.TempJob) var results = new NativeArray<RaycastHit>(targets.Length, Allocator.Temp); // 入力バッファを埋める for(int i = 0; i < targets.Legnth; ++i) { var targetPosition = targets[i].position; var direction = Vector3.down; var command = new RaycastCommand(targetPosition, direction); commands[i] = command; } // Jobを発行して終了を待つ RaycastCommand.ScheduleBatch(commands, results, 20).Complete(); commands.Dispose(); // 結果をバッファから受け取って何かを反映させる for(int i = 0; i < targets.Length; ++i) { if(velocity[i] < 0 && results[i].distance < 0.5f) velocity[i] = 2; velocity[i] -= 0.098f; } results.Dispose(); for(int i = 0; i < targets.Length; ++i) { targets[i].localPosition += Vector3.up * velocity[i]; } }
Native Slice
これだけ特殊なので紹介します。
なに?
NativeArray の一部分のデータを取り出すことができる。
使い方
NativeSlice<Type>(NativeArray, Index, Length);
- Type
- 取り出す要素の型。
- NativeArray
- 取り出す対象のNativeArray。
- Index
- 取り出したい先頭要素の添え字。
- Length
- 取り出したい要素数。