データをコピーする 安全システム による処理の欠点は、各コピー内のジョブの結果も単独化してしまうことです。この制限を解決するには、NativeContainer と呼ばれる共有メモリに結果を保存する必要があります。
A NativeContainer
is a managed value type that provides a safe C# wrapper for native memory. It contains a pointer to an unmanaged allocation. When used with the Unity C# Job System, a NativeContainer
allows a job to access data shared with the main thread rather than working with a copy.
Unity には、NativeArray と呼ばれる NativeContainer
が搭載されています。NativeArray
を NativeSlice で操作して、NativeArray
の特定の位置から特定の長さのサブセットを取得することもできます。
Note: The Entity Component System (ECS) package extends the Unity.Collections
namespace to include other types of NativeContainer
:
NativeList
- サイズ変更可能な NativeArray
NativeHashMap
- キーと値のペアNativeMultiHashMap
- 各キーに複数の値NativeQueue
- 先入れ先出し (FIFO) キューセーフティシステムはすべての NativeContainer
タイプに組み込まれています。 NativeContainer
へのすべての読み取りと書き込みを追跡します。
Note: All safety checks on NativeContainer
types (such as out of bounds checks, deallocation checks, and race condition checks) are only available in the Unity Editor and Play mode.
Part of this safety system is the DisposeSentinel and AtomicSafetyHandle. The DisposeSentinel
detects memory leaks and gives you an error if you haven’t freed your memory correctly. Triggering the memory leak error happens long after the leak occurred.
AtomicSafetyHandle
を使用すると、コードの NativeContainer
の所有権を移動します。例えば、2 つのスケジュールされたジョブが同じ NativeArray
に書き込みを行なうと、安全システムは例外を発生させ、問題の原因と解決方法を説明する明確なエラーメッセージを示します。安全システムは、違反のジョブがスケジュールされたときにこの例外をスローします。
この場合、依存関係を持つジョブをスケジュールに組み込めます。最初のジョブは NativeContainer
に書き込むことができ、実行が終了すると、次のジョブは同じ NativeContainer
から安全に読み取り、または書き込みすることができます。読み取りと書き込みの制限は、メインスレッドからデータにアクセスするときにも適用されます。安全システムでは、複数のジョブが並列で同じデータから読み取ることができます。
By default, when a job has access to a NativeContainer
, it has both read and write access. This configuration can slow performance. The C# Job System doesn’t allow you to schedule a job that has write access to a NativeContainer
at the same time as another job that’s writing to it.
If a job doesn’t need to write to a NativeContainer
, mark the NativeContainer
with the [ReadOnly]
attribute, like so:
[ReadOnly]
public NativeArray<int> input;
上の例では、読み取り専用アクセス権を持つジョブと、NativeContainer
への読み取り専用アクセス権を持つその他のジョブを同時に実行することができます。
注意 ジョブ内からの静的データへのアクセスに対する保護はありません。静的データにアクセスすると、すべての安全システムを回避し、Unity をクラッシュさせる可能性があります。詳細は、C# Job System のヒントとトラブルシューティング を参照してください。
When creating a NativeContainer
, you must specify the memory allocation type that you need. The allocation type depends on the length of time the job runs. This way you can tailor the allocation to get the best performance possible in each situation.
There are three Allocator types for NativeContainer
memory allocation and release. You must specify the appropriate one when instantiating a NativeContainer
.
Temp
to pass NativeContainer
allocations to jobs.Temp
but is faster than Persistent
. Use it for thread-safe allocations within a lifespan of four frames. Important: You must Dispose
of this type of allocation within four frames, or the console prints a warning, generated from the native code. Most small jobs use this NativeContainer
allocation type.NativeContainer
allocation type. Don’t use Persistent
where performance is essential.例
NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);
Note: The number 1 in the example above indicates the size of the NativeArray
. In this case, it has only one array element because it only stores one piece of data in result
.