データをコピーする 安全システム による処理の欠点は、各コピー内のジョブの結果も単独化してしまうことです。この制限を解決するには、NativeContainer と呼ばれる共有メモリに結果を保存する必要があります。
NativeContainer
はマネージ型で、比較的安全な C# ラッパーをネイティブメモリに提供します。これには、アンマネージの割り当てへのポインターが含まれます。Unity C# Job System で使用する場合、NativeContainer
を使用すると、ジョブはコピーを使って作業するのではなく、メインスレッドと共有するデータにアクセスできるようになります。
Unity には、NativeArray と呼ばれる NativeContainer
が搭載されています。NativeArray
を NativeSlice で操作して、NativeArray
の特定の位置から特定の長さのサブセットを取得することもできます。
注意 Entity Component System (ECS) パッケージは、Unity.Collections
名前空間を拡張して、他の NativeContainer
属性のある型が含まれています。
NativeList
- サイズ変更可能な NativeArray
NativeHashMap
- キーと値のペアNativeMultiHashMap
- 各キーに複数の値NativeQueue
- 先入れ先出し (FIFO) キューセーフティシステムはすべての NativeContainer
タイプに組み込まれています。 NativeContainer
へのすべての読み取りと書き込みを追跡します。
注意 NativeContainer
タイプのすべての安全チェック (例えば、範囲外チェック、割り当て解除チェック、競合状態チェック) は、Unity の エディター と 再生モード でのみ使用可能です。
この安全システムには DisposeSentinel と AtomicSafetyHandle が含まれます。 DisposeSentinel
はメモリリークを検出し、正しくメモリが解放されていない場合はエラーを返します。メモリリークエラーは、リークが発生してからかなり後に送信されます。
AtomicSafetyHandle
を使用すると、コードの NativeContainer
の所有権を移動します。例えば、2 つのスケジュールされたジョブが同じ NativeArray
に書き込みを行なうと、安全システムは例外を発生させ、問題の原因と解決方法を説明する明確なエラーメッセージを示します。安全システムは、違反のジョブがスケジュールされたときにこの例外をスローします。
この場合、依存関係を持つジョブをスケジュールに組み込めます。最初のジョブは NativeContainer
に書き込むことができ、実行が終了すると、次のジョブは同じ NativeContainer
から安全に読み取り、または書き込みすることができます。読み取りと書き込みの制限は、メインスレッドからデータにアクセスするときにも適用されます。安全システムでは、複数のジョブが並列で同じデータから読み取ることができます。
デフォルトでは、NativeContainer
へアクセスできるジョブは、読み取りと書き込みの両方のアクセスが可能です。この設定はパフォーマンスを遅くする可能性があります。C# Job System では、NativeContainer
への書き込みアクセス権を持つジョブを、NativeContainer
への書き込みアクセス権を持つ他のジョブと同時にスケジュールすることはできません。
ジョブが NativeContainer
への書き込みを必要としない場合は、以下のように NativeContainer
に [ReadOnly]
属性を設定します。
[ReadOnly]
public NativeArray<int> input;
上の例では、読み取り専用アクセス権を持つジョブと、NativeContainer
への読み取り専用アクセス権を持つその他のジョブを同時に実行することができます。
注意 ジョブ内からの静的データへのアクセスに対する保護はありません。静的データにアクセスすると、すべての安全システムを回避し、Unity をクラッシュさせる可能性があります。詳細は、C# Job System のヒントとトラブルシューティング を参照してください。
NativeContainer
を作成するときに、必要なメモリ割り当てのタイプを指定する必要があります。割り当てタイプは、ジョブが実行される時間の長さによって異なります。これにより、各状況で最高のパフォーマンスが得られるように割り当てを調整できます。
NativeContainer
メモリ割り当てと解放には 3 つの Allocator タイプがあります。NativeContainer
をインスタンス化するときに適切なものを指定する必要があります。
Temp
を使って割り当てを行った NativeContainer
をジョブに渡すべきではありません。また、メソッドの呼び出し (MonoBehaviour.Update など) や、その他すべてのネイティブコードからマネージコードへのコールバックから戻る前に Dispose
メソッドを呼び出す必要があります。Temp
よりもスピードの遅い割り当てですが、Persistent
よりも高速です。これは、4 フレーム以内のスパンの割り当てであり、スレッドセーフです。4 フレーム以内で Dispose
を行わないと、コンソールはネイティブコードから生成された警告を出力します。ほとんどの小さなジョブはこの割り当てタイプを使用します。Persistent
を使用しないでください。例
NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);
ノート 上の例の数字 1 は、 NativeArray
のサイズを示しています。この場合、配列要素は 1 つだけです (result
に 1 つのデータしか格納していないため)。
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.