こんにちは、Unityエンジニアのオオバです。

前回はIJobインターフェースでJobSystemを使ってみました。

Unity C#JobSystemをとりあえずやってみる序
IJobインターフェースで作ったジョブは1つのWorkerThreadに処理を分散することしかできませんでしたが、今回はもっと多くのWorkerThreadに処理を分散させてみようと思います。

👉DOTweenの教科書を読んでUnityアニメーションをプログラミングしてみよう!

IJobParallelForインターフェースを使ってジョブを作る

Unity - Scripting API: IJobParallelFor

IJobParallelForインターフェースを使うと、複数のスレッドに分散させて配列要素を並列で実行することができます。また、この配列はNativeContainerである必要があります。

struct VelocityJob : IJobParallelFor  
{
    // 処理するバッファはNativeContainerである必要がある  
    [ReadOnly]  
    public NativeArray velocity;  
    public NativeArray position;  
    public float deltaTime;  
    ///  
    /// ジョブの処理内容  
    ///  
    public void Execute(int index)  
    {
        position[index] = position[index] + velocity[index] * deltaTime;  
    }
}

上記のようにジョブを作ります。
Execute内で処理できる要素番号が引数で渡ってきますが、それ以外の要素数を操作することはできません。
position[index + 1]とかにアクセスするとエラーが出ます。

IJobParallelForで並列処理させるジョブを作ってみる_0

【Unite Tokyo 2018 Training Day】C#JobSystem & ECSでCPUを極限まで使い倒そう ~C# Jo…
分散処理は上のようなイメージらしいです。

ジョブの実行

var job = new VelocityJob() {  
    deltaTime = Time.deltaTime,  
    position = position,  
    velocity = velocity  
};  
// ジョブを実行  
// 第2引数に0を入れるといい感じにスレッドに振り分けてくれるらしい  
JobHandle jobHandle = job.Schedule(_count, 0);  
// ジョブ完了の待機  
jobHandle.Complete();  

Scheduleメソッドの第2引数にはバッチ数を指定します。0を指定するといい感じに分散してくれるらしいです。

パフォーマンスについて

ジョブ未使用状態

IJobParallelForで並列処理させるジョブを作ってみる_1

ジョブ使用状態(No Burst)

IJobParallelForで並列処理させるジョブを作ってみる_2

ジョブ使用状態(Burst)

IJobParallelForで並列処理させるジョブを作ってみる_3

そしてBurstCompilerを使うと、

前回記事のIJobインターフェースで作った処理をIJobParallelForに置き換えただけですが、複数のWorkerThreadを使用している分IJobよりパフォーマンスが出ているようです。

という使い分けをするのだろうと思いました。

今回のソースコードはこちら

パフォーマンス検証のためジョブ使用/未使用をuseJobフラグで分けてます。

IJobParallelForサンプル · GitHub

オススメ記事
検証環境