Version: 2021.2
ParallelForTransform ジョブ
マルチプレイヤーとネットワーク

C# ジョブシステムのヒントとトラブルシューティング

Unity C# Job System を使用する場合は、以下を確認してください。

ジョブから静的データにアクセスしない

ジョブから静的データにアクセスすると、すべての安全システムが回避されます。誤ったデータにアクセスすると Unity をクラッシュさせることがあり、多くの場合予期せぬことが起こります。例えば、MonoBehaviour にアクセスすると、ドメインのリロード時にクラッシュする可能性があります。

注意 このリスクのため、今後のバージョンの Unity では 静的コード分析 を使用して、ジョブからグローバル変数へのアクセスを禁止します。もし、ジョブ内の静的データにアクセスすると、今後のバージョンの Unity では、コードが壊れることが予想されます。 

スケジュールされたバッチをフラッシュする

When you want your jobs to start executing, then you can flush the scheduled batch with JobHandle.ScheduleBatchedJobs. Note that calling this method can negatively impact performance. Not flushing the batch delays the scheduling until the control thread waits for the result. In all other cases use JobHandle.Complete to start the execution process.

ノート: Entity Component System (ECS) では、バッチは暗黙のうちにフラッシュされるため、JobHandle.ScheduleBatchedJobs を呼び出す必要はありません。

NativeContainer のコンテンツを更新しない

参照戻り値 (ref return) がないため、直接 NativeContainer のコンテンツを変更することはできません。例えば、nativeArray[0]++;var temp = nativeArray[0]; temp++; と書くのと同じです。 これは nativeArray の値を更新しません。

代わりに、インデックスのデータからローカルの一時的なコピーを作成し、そのコピーを変更して、それを元のデータに保存する必要があります。以下のように行ないます。

MyStruct temp = myNativeArray[i];
temp.memberVariable = 0;
myNativeArray[i] = temp;

所有権を回復するには JobHandle.Complete を呼び出す

Tracing data ownership requires dependencies to complete before the control thread can use them again. It is not enough to check JobHandle.IsCompleted. You must call the method JobHandle.Complete to regain ownership of the NativeContainer types to the control thread. Calling Complete also cleans up the state in the safety system. Not doing so introduces a memory leak. This process also applies if you schedule new jobs every frame that has a dependency on the previous frame’s job.

Use Schedule and Complete in the control thread

You can only call Schedule and Complete from the same control thread. If one job depends on another, use JobHandle to manage dependencies rather than trying to schedule jobs within jobs.

Schedule と Complete を適切なタイミングで完了する

ジョブが必要とするデータを取得したらすぐに、ジョブの Schedule を呼び出し、結果が必要になるまでそのジョブで Complete を呼び出してはいけません。実行中の他のジョブと競合していないときに、待機する必要のないジョブをスケジュールすることは適正な方法です。例えば、1 つのフレームの終了から次のフレームの開始までの間でジョブが実行されておらず、1 フレームの待ち時間が許容できる場合は、フレームの最後にジョブをスケジュールし、その結果を次のフレームで使用します。また、ゲームの切り替え部分が他のジョブで飽和状態であるのに、フレーム内の他のどこかで過度にジョブの少ない部分がある場合は、ジョブを少ない部分にスケジュールする方が効率的です。

NativeContainer タイプを読み取り専用にする

ジョブはデフォルトで NativeContainer タイプへの読み書きのアクセスを持っていることに注意してください。適時 [ReadOnly] 属性を使用して、パフォーマンスを向上させます。

データの依存関係を確認する

In the Unity Profiler window, the marker “WaitForJobGroup” on the control thread indicates that Unity is waiting for a job on a worker thread to complete. This marker could mean that you have introduced a data dependency somewhere that you should resolve. Look for JobHandle.Complete to track down where you have data dependencies that are forcing the control thread to wait.

ジョブのデバッグ

Jobs have a Run function that you can use in place of Schedule to immediately execute the job on the control thread. You can use this for debugging purposes.

マネージメモリをジョブに割り当てない

マネージメモリをジョブに割り当てると非常に遅く、パフォーマンスを向上させるために Unity Burst コンパイラー を使用することはできません。Burst は作業をより簡単にする新しい LLVM ベースのバックエンドコンパイラー技術です。C# のジョブを処理し、高度に最適化されたマシンコードを生成し、プラットフォームの特定の機能を活用できます。

その他の情報


  • 2018–06–15 公開ページ

  • C# Job System は 2018.1 で公開NewIn20181

ParallelForTransform ジョブ
マルチプレイヤーとネットワーク