スレッドセーフタイプ
Understand Unity's custom thread-safe type, NativeContainer.
読み終わるまでの所要時間 10 分最終更新 1ヶ月前
ジョブシステムは、Burst コンパイラー と併用するのが最も効果的です。Burst はマネージオブジェクトをサポートしていないので、ジョブのデータにアクセスするにはアンマネージタイプを使う必要があるためです。これには blittable 型 を使うか、Unity のビルトインの オブジェクトを使用できます。これらは、ネイティブメモリのためのスレッドセーフな C# ラッパーです。 オブジェクトはジョブがコピーで作業するのではなく、メインスレッド と共有されるデータにアクセスすることを可能にします。
NativeContainerNativeContainerNativeContainer の型
Unity.CollectionsNativeContainer- : マネージコードにネイティブメモリのバッファを公開するアンマネージ配列
NativeArray - :
NativeSliceの特定の位置から特定の長さのサブセットを取得します。NativeArray
注意Collections パッケージ には、追加の が含まれています。追加の型の完全なリストについては、Collections ドキュメントの Collection 型 を参照してください。
NativeContainer読み書きアクセス
デフォルトでは、 インスタンスへアクセスできるジョブは、読み取りと書き込みの両方のアクセスが可能です。この設定はパフォーマンスを遅くする可能性があります。これは、ジョブシステムでは、 インスタンスへの書き込みアクセス権を持つジョブを、そのインスタンスへの書き込みアクセス権を持つ他のジョブと同時にスケジュールすることができないためです。
NativeContainerNativeContainerしかし、ジョブが インスタンスに書き込む必要がない場合は、以下のように に 属性を設定することができます。
NativeContainerNativeContainer[ReadOnly][ReadOnly]public NativeArray<int> input;
上の例では、読み取り専用アクセス権を持つジョブと、同様に最初の への読み取り専用アクセス権を持つその他のジョブを同時に実行することができます。
NativeArrayメモリ割り当て
NativeContainer NativeContainerNativeContainer- : 最も高速な割り当てが可能です。生存期間が 1 フレーム以下の割り当てに使ってください。ただし、
Allocator.Tempを使って、ジョブのメンバーフィールドに保管されているTempインスタンスに割り当てを渡すことはできません。NativeContainer - :
Allocator.TempJobよりもスピードの遅い割り当てですが、Tempよりも高速です。これは、4 フレーム以内の生存期間のスレッドセーフな割り当てに使用します。重要:4 フレーム以内でこの割り当てタイプにPersistentを行わないと、コンソールはネイティブコードから生成された警告を出力します。ほとんどの小さなジョブはこの割り当てタイプを使用します。Dispose - : 最も遅い割り当てですが、好きなだけ長く、必要な場合は、アプリケーションの生存期間を通して使用できます。これは、
Allocator.Persistentへの直接呼び出しのためのラッパーです。長いジョブはこの NativeContainer 割り当てタイプを使用できます。パフォーマンスが重要な場合はmallocを使用しないでください。Persistent
例:
NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);
注意上の例の数字 1 は、NativeArray のサイズを示しています。この場合、配列要素は 1 つだけです。理由は、result (結果) に 1 つのデータしか格納しないためです。
NativeContainer と安全システム
安全システム はすべての インスタンスに組み込まれています。すべての インスタンスへの読み込みや書き込みを追跡し、その情報を使って の使用に一定のルールを適用し、複数のジョブやスレッドにまたがって決定論的な動作を行うようにします。
NativeContainerNativeContainerNativeContainer例えば、2 つの個々にスケジュールされたジョブが同じ に書き込む場合、どちらのジョブが先に実行されるか予測できないため、これは安全ではありません。つまり、どちらのジョブがもう一方のジョブのデータを上書きするかわからないということです。安全システムは、2 番目のジョブがスケジュールされる際に、理由と問題を解決する方法を説明する明確なエラーメッセージとともに例外をスローします。
NativeArray同じ インスタンスに書き込む 2 つのジョブをスケジュールする場合、依存関係を持つジョブ をスケジュールできます。最初のジョブが に書き込み、実行が終了すると、次のジョブが同じ を安全に読み書きします。依存関係を導入することで、ジョブが常に一貫した順序で実行され、 内の結果のデータが決定論的であることが保証されます。
NativeContainerNativeContainerNativeContainerNativeContainer安全システムは、複数のジョブが同じデータを並行して読み取ることを可能にします。
これらの読み取りと書き込みの制限は、メインスレッドからデータにアクセスするときにも適用されます。例えば、NativeContainer に書き込むジョブが完了する前に NativeContainer のコンテンツを読み取ろうとすると、安全システムはエラーをスローします。同様に、NativeContainer への読み取りまたは書き込みを保留しているジョブがまだあるときに NativeContainer に書き込もうとすると、安全システムはエラーをスローします。
また、NativeContainer は を実装していないため、 のコンテンツを直接変更することはできません。例えば、 は と書くのと同じで、 の値は更新されません。
ref returnNativeContainernativeArray[0]++;var temp = nativeArray[0]; temp++;nativeArray代わりに、インデックスのデータからローカルの一時的なコピーを作成し、そのコピーを変更して、それを元のデータに保存する必要があります。 例:
MyStruct temp = myNativeArray[i];temp.memberVariable = 0;myNativeArray[i] = temp;