Version: 2021.3
言語: 日本語
ジョブのスケジュール
ParallelFor ジョブ

JobHandle と依存関係

ジョブの Schedule メソッドを呼び出すと、JobHandle を返します。コード内で JobHandle を他のジョブの依存関係として使用することができます。ジョブが別のジョブの結果に依存している場合は、以下のように、最初のジョブの JobHandle をパラメーターとして Schedule メソッドに渡すことができます。

JobHandle firstJobHandle = firstJob.Schedule();
secondJob.Schedule(firstJobHandle);

Note: All of a job’s dependencies must be scheduled on the same control thread as the job itself.

依存関係の合同

ジョブに多くの依存関係がある場合は、JobHandle.CombineDependencies メソッドを使用してそれらを合同できます。CombineDependencies を使うと、依存関係を Schedule メソッドに渡すことが可能です。

NativeArray<JobHandle> handles = new NativeArray<JobHandle>(numJobs, Allocator.TempJob);

// `handles` に複数のスケジュールされたジョブの `JobHandles` を割り当てます...

JobHandle jh = JobHandle.CombineDependencies(handles);

Waiting for jobs in the control thread

Use JobHandle to force your code to wait in the control thread for your job to finish executing. To do this, call the method Complete on the JobHandle. At this point, you know the control thread can safely access the NativeContainer that the job was using.

Note: Jobs do not start executing when you schedule them. If you are waiting for the job in the control thread, and you need access to the NativeContainer data that the job is using, you can call the method JobHandle.Complete. This method flushes the jobs from the memory cache and starts the process of execution. Calling Complete on a JobHandle returns ownership of that job’s NativeContainer types to the control thread. You need to call Complete on a JobHandle to safely access those NativeContainer types from the control thread again. It is also possible to return ownership to the control thread by calling Complete on a JobHandle that is from a job dependency. For example, you can call Complete on jobA, or you can call Complete on jobB which depends on jobA. Both result in the NativeContainer types that are used by jobA being safe to access on the control thread after the call to Complete.

あるいは、データへのアクセスが必要ない場合は、バッチを明示的にフラッシュする必要があります。これを行うには、静的メソッド JobHandle.ScheduleBatchedJobs を呼び出します。このメソッドを呼び出すとパフォーマンスに悪影響を与える可能性があることに注意してください。

複数のジョブと依存関係の例

ジョブコードサンプル

//  2 つの浮動小数点の値を加算するジョブ
public struct MyJob : IJob
{
    public float a;
    public float b;
    public NativeArray<float> result;

    public void Execute()
    {
        result[0] = a + b;
    }
}

// 1 を値に加算するジョブ
public struct AddOneJob : IJob
{
    public NativeArray<float> result;
    
    public void Execute()
    {
        result[0] = result[0] + 1;
    }
}

メインスレッドコードサンプル

//結果を保存するために、1 つの float 値を格納できるネイティブの配列を作成します。この例では、説明のためにジョブが完了するのを待ちます。
NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);

//ジョブ1 のデータを設定します
MyJob jobData = new MyJob();
jobData.a = 10;
jobData.b = 10;
jobData.result = result;

//ジョブ1 をスケジュールします
JobHandle handle = jobData.Schedule();

// ジョブ2 のデータを設定します
AddOneJob incJobData = new AddOneJob();
incJobData.result = result;

// ジョブ2 をスケジュールします
JobHandle secondHandle = incJobData.Schedule(firstHandle);

//ジョブ2 が完了するのを待ちます
secondHandle.Complete();

//NativeArray のすべてのコピーが同じメモリを指している場合は、自分の NativeArray のコピーの結果にアクセスできます
float aPlusB = result [0];

//結果の配列に割り当てられたメモリを解放します
result.Dispose();

  • 2018–06–15 公開ページ

  • C# Job System は 2018.1 で公開NewIn20181

ジョブのスケジュール
ParallelFor ジョブ