Version: Unity 6.0 (6000.0)
言語 : 日本語
ジョブの作成と実行
ParallelFor ジョブ

ジョブの依存関係

多くの場合、あるジョブは別のジョブの結果に依存します。例えば、ジョブ A が NativeArray に書き込みを行うと、それをジョブ B が入力として使用します。依存するジョブをスケジュールする場合、ジョブシステムにその依存関係を伝える必要があります。依存されているジョブが終了するまで、ジョブシステムは依存するジョブを実行しません。1 つのジョブが複数のジョブに依存する場合もあります。

各ジョブが前のジョブに依存するような、ジョブのチェーンを作ることもできますが、ジョブを実行する前に依存先のジョブが完了するのを待たなければならないため、依存関係によってジョブの実行が遅延します。別のジョブに依存しているジョブを完了させるには、まずその依存先のジョブと、その (またはそれらの) ジョブがさらに依存しているジョブを完了させなければなりません。

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

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

依存関係の統合

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

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

// Populate `handles` with `JobHandles` from multiple scheduled jobs...

JobHandle jh = JobHandle.CombineDependencies(handles);

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

以下の例では、複数のジョブに複数の依存関係があります。ジョブコード (MyJobAddOneJob) を UpdateLateUpdate コードとは別のファイルに置くのが効率的ですが、わかりやすくするために、この例では 1 つのファイルに置いています。

using UnityEngine;
using Unity.Collections;
using Unity.Jobs;

public class MyDependentJob : MonoBehaviour
{
    // Create a native array of a single float to store the result. This example waits for the job to complete.
    NativeArray<float> result;
    // Create a JobHandle to access the results
    JobHandle secondHandle;

    // Set up the first job
    public struct MyJob : IJob
    {
        public float a;
        public float b;
        public NativeArray<float> result;

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

    // Set up the second job, which adds one to a value
    public struct AddOneJob : IJob
    {
        public NativeArray<float> result;

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

    // Update is called once per frame
    void Update()
    {
        // Set up the job data for the first job
        result = new NativeArray<float>(1, Allocator.TempJob);

        MyJob jobData = new MyJob
        {
            a = 10,
            b = 10,
            result = result
        };

        // Schedule the first job
        JobHandle firstHandle = jobData.Schedule();

        // Setup the data for the second job
        AddOneJob incJobData = new AddOneJob
        {
            result = result
        };

        // Schedule the second job
        secondHandle = incJobData.Schedule(firstHandle);
    }

    private void LateUpdate()
    {
        // Sometime later in the frame, wait for the job to complete before accessing the results.
        secondHandle.Complete();

        // All copies of the NativeArray point to the same memory, you can access the result in "your" copy of the NativeArray
        // float aPlusBPlusOne = result[0];

        // Free the memory allocated by the result array
        result.Dispose();
    }

}

追加リソース

ジョブの作成と実行
ParallelFor ジョブ