Unity3D :并行作业

推荐:将NSDT场景编辑器加入你的3D工具链
3D工具集:NSDT简石数字孪生

并行作业

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

ParallelFor 作业使用数据的 NativeArray 作为其数据源。ParallelFor 作业跨多个 CPU 内核运行。每个核心有一个作业,每个作业处理工作负载的一个子集。

IJobParallelFor行为类似于 IJob,但它不是单个 Execute 方法,而是在数据源中的每个项调用一次该方法。该方法中还有一个整数参数索引,可用于访问作业实现中数据源的单个元素并对其进行操作。ExecuteExecute

以下是 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;
    }
}

安排并行 For 作业

若要计划作业,必须指定要拆分的数据源的长度。如果结构中有多个数据源,则作业系统不知道要使用哪个数据源。长度还告诉作业系统需要多少种方法。ParallelForNativeArrayNativeArrayExecute

在 Unity 的原生代码中,作业的计划更为复杂。当 Unity 计划作业时,作业系统会将工作分成批,以便在内核之间分配。每个批次包含一个方法子集。然后,作业系统在 Unity 的本机作业系统中为每个 CPU 内核调度一个作业,并将该本机作业传递给批处理以完成。ParallelForParallelForExecute

跨内核划分批处理的并行 For 作业
跨内核划分批处理的并行 For 作业

当本机作业先于其他作业完成其批处理时,它会从其他本机作业中窃取剩余的批处理。它一次只窃取本机作业剩余批次的一半,以确保缓存局部性。

要优化流程,您需要指定批次计数。批处理计数控制您获得的作业数,以及线程之间工作的重新分配的细粒度程度。具有较低的批计数(例如 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 API 文档。ParallelForTransformParallelFor


3D建模学习工作室整理翻译,转载请注明出处!

上一篇:Unity3D :作业依赖关系 (mvrlink.com)

下一篇:Unity3D :创建作业 (mvrlink.com)

NSDT场景编辑器 | NSDT 数字孪生 | GLTF在线编辑器 | 3D模型在线转换 | UnrealSynth虚幻合成数据生成器 | 3D模型自动纹理化工具
2023 power by nsdt©鄂ICP备2023000829号