こんにちは、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]
とかにアクセスするとエラーが出ます。
【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を指定するといい感じに分散してくれるらしいです。
パフォーマンスについて
ジョブ未使用状態
- MainThreadのUpdate処理時間 : 28.4ms
ジョブ使用状態(No Burst)
- MainThreadのUpdate処理時間 : 16.06ms
- ジョブ実行時間 : 6.5ms
ジョブ使用状態(Burst)
そしてBurstCompilerを使うと、
- MainThreadのUpdate処理時間 : 10.15ms
- ジョブ実行時間 : 0.75ms
前回記事のIJobインターフェースで作った処理をIJobParallelForに置き換えただけですが、複数のWorkerThreadを使用している分IJobよりパフォーマンスが出ているようです。
- IJob・・・1つの処理をWorkerThreadに分散したい場合
- IJobParallelFor・・・・多くの要素を並列処理したい場合
という使い分けをするのだろうと思いました。
今回のソースコードはこちら
パフォーマンス検証のためジョブ使用/未使用をuseJobフラグで分けてます。
この記事が気に入ったらフォローしよう
- Unity2018.2.5.f1