Unity のジョブシステムを使うと、アプリケーションが利用可能なすべての CPU コアを使用してコードを実行できるように、マルチスレッドコードを作成することができます。これにより、パフォーマンスが向上します。アプリケーションは 1 つの CPU コアですべてのコードを実行するのではなく、アプリケーションを実行するすべての CPU コアの能力をより効率的に使用するからです。
ジョブシステムは単独で使用できますが、パフォーマンスを向上させるには、Burst コンパイラー も使用する必要があります。Burst コンパイラーは、Unity のジョブシステムのジョブをコンパイルするために特別に設計されたコンパイラーです。Burst コンパイラーではコード生成が改善されており、その結果、パフォーマンスが向上し、モバイルデバイスでのバッテリー消費が少なくなります。
ジョブシステムは、Unity のEntity Component System と合わせて使用して、高パフォーマンスのデータ指向コードを作成することもできます。
Unityは、独自のネイティブジョブシステムを使用して、複数の ワーカースレッド で独自のネイティブコードを処理します。ワーカースレッドは、アプリケーションが実行されるデバイスで使用可能な CPU コアの数に依存しています。通常 Unity は、プログラムの開始時にデフォルトで実行される 1 つのスレッド (メインスレッド と呼ばれます) でコードを実行します。しかし、ジョブシステムを使用すると、Unity は複数のワーカースレッドでコードを実行します。これは マルチスレッド と呼ばれます
マルチスレッドは、複数のコアで多くのスレッドを同時に処理できる CPU の能力を利用します。タスクや命令は、1 つずつ実行されるのではなく、いっぺんに実行されます。ワーカースレッドは互いに並行して実行され、完了するとその結果をメインスレッドと同期します。
ジョブシステムは、CPU コアの能力に相当する十分な数のスレッドのみを確保します。つまり、使用可能な CPU コアの数を具体的に知らなくても、必要な数だけタスクをスケジュールできます。これは、CPU コアよりも多くのスレッドを非効率的に作成しがちな スレッドプール などの技術に依存する、他のジョブシステムとは異なります。
ジョブシステムは、スケジュール戦略の一環としてワークスチールを使用して、ワーカースレッド間で共有されるタスクの量を均等にします。ワーカースレッドは、他のスレッドよりもタスクを高速に処理する場合があります。そのため、ワーカースレッドは、そのすべてのタスクの処理を終了すると、他のワーカースレッドのキューを参照し、他のワーカースレッドに割り当てられていたタスクを処理します。
マルチスレッドのコードを書くのを容易にするために、ジョブシステムには、競合状態の可能性があるすべての状況を検出し、それらが原因となるバグからユーザーを保護する、安全システムがあります。競合状態は、1 つの操作の出力が、制御外の別の処理のタイミングに依存する場合に発生します。
例えば、ジョブシステムがメインスレッドのコードからジョブへ、データへの参照を送信する場合、ジョブが書き込むのと同時に、メインスレッドがデータを読み取っているかどうかを確認することはできません。このシナリオでは、競合状態が発生します。
この問題を解決するために、ジョブシステムは、メインスレッドのデータへの参照ではなく、操作の必要なデータのコピーを各ジョブに送信します。このコピーはデータを分離し、競合状態を解消します。
ジョブシステムがデータをコピーする仕組みは、ジョブが blittable データ型 にのみアクセスできることを意味します。これらの型は、マネージコードとネイティブコード間で渡されるときに変換する必要はありません。
ジョブシステムは memcpy を使用して blittable 型をコピーし、Unity のマネージパーツとネイティブパーツ間でデータを転送します。ジョブのスケジュール時に memcpy を使用してネイティブメモリにデータを配置し、ジョブの実行時にマネージ側がそのコピーにアクセスできるようにします。詳細については、ジョブのスケジュール を参照してください。
Unity コアエンジンで提供されるジョブシステムに加えて、Collections パッケージは多くの ジョブタイプ と ネイティブコンテナ を拡張します。詳細については、Collections のドキュメント を参照してください。