版本:Unity 6 (6000.0)
语言:英语
作业依赖项
调试和诊断

并行作业

当您安排作业时,只能有一个作业执行一项任务。但是,有时您需要对许多对象执行相同的操作。为此,请使用继承自IJobParallelFor的 ParallelFor 作业类型。

ParallelFor 作业使用NativeArray数据作为其数据源。ParallelFor 作业在多个 CPU 内核上运行。每个内核有一个作业,每个作业处理工作负载的一部分。

IJobParallelFor 的行为类似于IJob,但它没有单个Execute方法,而是针对数据源中的每个项目调用一次 Execute 方法。在 Execute 方法中还有一个整数参数索引,您可以使用它来访问和操作作业实现中的数据源的单个元素。

以下是一个 ParallelFor 作业定义的示例

struct IncrementByDeltaTimeJob: IJobParallelFor
{
    public NativeArray<float> values;
    public float deltaTime;

    public void Execute (int index)
    {
        float temp = values[index];
        temp += deltaTime;
        values[index] = temp;
    }
}

安排 ParallelFor 作业

要安排 ParallelFor 作业,您必须指定要拆分的 NativeArray 数据源的长度。如果结构体中有多个 NativeArray,作业系统不知道要使用哪个 NativeArray 作为数据源。长度还告诉作业系统预期多少个 Execute 方法。

在 Unity 的本机代码中,ParallelFor 作业的安排更加复杂。当 Unity 安排 ParallelFor 作业时,作业系统将工作划分为批次,并在内核之间分配。每个批次包含一个 Execute 方法子集。然后,作业系统在 Unity 的本机作业系统中为每个 CPU 内核安排一个作业,并将该本机作业传递给批次以完成。

A ParallelFor job dividing batches across cores
ParallelFor 作业在内核之间划分批次

当一个本机作业在其批次完成之前其他本机作业完成时,它会窃取其他本机作业的剩余批次。它一次只窃取一个本机作业剩余批次的一半,以确保缓存局部性

要优化此过程,您需要指定一个批次计数。批次计数控制您获得的作业数量,以及线程之间工作的细粒度重新分配。具有较低的批次计数(例如 1)可以使您在线程之间获得均匀的工作分配。但是,它会带来一些开销,因此有时最好增加批次计数。从 1 开始,然后不断增加批次计数,直到性能增益可以忽略不计,这是一个不错的策略。

以下是安排 ParallelFor 作业的示例

作业代码

// Job adding two floating point values together
public struct MyParallelJob : IJobParallelFor
{
    [ReadOnly]
    public NativeArray<float> a;
    [ReadOnly]
    public NativeArray<float> b;
    public NativeArray<float> result;

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

主线程代码

NativeArray<float> a = new NativeArray<float>(2, Allocator.TempJob);

NativeArray<float> b = new NativeArray<float>(2, Allocator.TempJob);

NativeArray<float> result = new NativeArray<float>(2, Allocator.TempJob);

a[0] = 1.1;
b[0] = 2.2;
a[1] = 3.3;
b[1] = 4.4;

MyParallelJob jobData = new MyParallelJob();
jobData.a = a;
jobData.b = b;
jobData.result = result;

// Schedule the job with one Execute per index in the results array and only 1 item per processing batch
JobHandle handle = jobData.Schedule(result.Length, 1);

// Wait for the job to complete
handle.Complete();

// Free the memory allocated by the arrays
a.Dispose();
b.Dispose();
result.Dispose();

ParallelForTransform 作业

ParallelForTransform 作业是另一种 ParallelFor 作业类型,专为对Transform进行操作而设计。它对于从作业中高效地处理 Transform 操作很有用。

其他资源

作业依赖项
调试和诊断