版本:Unity 6 (6000.0)
语言英语
  • C#

IJobFor

Unity.Jobs 中的接口

建议更改

成功!

感谢您帮助我们提高 Unity 文档的质量。虽然我们无法接受所有提交,但我们确实会阅读来自我们用户的每个建议更改,并在适用时进行更新。

关闭

提交失败

出于某种原因,您的建议更改无法提交。请在几分钟内<a>重试</a>。感谢您抽出时间帮助我们提高 Unity 文档的质量。

关闭

取消

说明

表示一个作业的接口,该作业独立地对本机容器中的每个元素执行相同的操作,或执行固定次数的迭代操作。

此作业类型的任务计划选项如下

  • IJobForExtensions.Run 在主线程上运行作业,并立即完成。
  • IJobForExtensions.Schedule 计划在工作线程或主线程上运行作业,但表示该工作应在单个线程中进行。此选项允许在主线程外执行工作,但工作是按顺序执行的。
  • IJobForExtensions.ScheduleParallel 计划在多个工作线程上同时运行作业。这种计划选项可以提供最佳性能,但当同时从多个工作线程访问相同数据时,可能会发生冲突。
  • Execute(int index) 对从 0 到提供的长度的每个索引执行一次。

RunSchedule 保证按照顺序调用该作业的 Execute(int index) 方法。 ScheduleParallel 不按顺序调用作业的 Execute 方法,因为它从多个工作线程中被并行调用。

每个迭代必须独立于其他迭代,而且安全系统会强制执行此规则。这些索引没有保证的顺序,并且将在多个内核上并行地执行。

Unity 会自动将任务分割为不少于所提供的 batchSize 的块,并根据工作线程的数量、数组长度和批处理大小安排适当数量的任务。您应该根据任务中执行的工作量来选择批处理大小。例如,一个简单的任务,例如将几个 Vector3 相加,批处理大小应为 32 到 128。但是,如果执行的工作非常繁重,那么最佳做法是使用较小的批处理大小,例如批处理大小为 1。IJobFor 使用原子操作执行任务窃取。批处理大小可以很小,但它们不是免费的。

您可以使用返回的 JobHandle 来检查任务是否已完成,或将其作为依赖项传递到其他任务。当您将 JobHandle 作为依赖项传递时,它可确保任务在工作线程上一个接一个地执行。

其他资源: IJobForExtensions

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

class ApplyVelocityParallelForSample : MonoBehaviour { struct VelocityJob : IJobFor { // Jobs declare all data that will be accessed in the job // By declaring it as read only, multiple jobs are allowed to access the data in parallel [ReadOnly] public NativeArray<Vector3> velocity;

// By default containers are assumed to be read & write public NativeArray<Vector3> position;

// Delta time must be copied to the job since jobs generally don't have concept of a frame. // The main thread waits for the job same frame or next frame, but the job should do work deterministically // independent on when the job happens to run on the worker threads. public float deltaTime;

// The code actually running on the job public void Execute(int i) { // Move the positions based on delta time and velocity position[i] = position[i] + velocity[i] * deltaTime; } }

public void Update() { var position = new NativeArray<Vector3>(500, Allocator.Persistent);

var velocity = new NativeArray<Vector3>(500, Allocator.Persistent); for (var i = 0; i < velocity.Length; i++) velocity[i] = new Vector3(0, 10, 0);

// Initialize the job data var job = new VelocityJob() { deltaTime = Time.deltaTime, position = position, velocity = velocity };

// Schedule job to run immediately on main thread. First parameter is how many for-each iterations to perform. job.Run(position.Length);

// Schedule job to run at a later point on a single worker thread. // First parameter is how many for-each iterations to perform. // The second parameter is a JobHandle to use for this job's dependencies. // Dependencies are used to ensure that a job executes on worker threads after the dependency has completed execution. // In this case we don't need our job to depend on anything so we can use a default one. JobHandle scheduleJobDependency = new JobHandle(); JobHandle scheduleJobHandle = job.Schedule(position.Length, scheduleJobDependency);

// Schedule job to run on parallel worker threads. // First parameter is how many for-each iterations to perform. // The second parameter is the batch size, // essentially the no-overhead innerloop that just invokes Execute(i) in a loop. // When there is a lot of work in each iteration then a value of 1 can be sensible. // When there is very little work values of 32 or 64 can make sense. // The third parameter is a JobHandle to use for this job's dependencies. // Dependencies are used to ensure that a job executes on worker threads after the dependency has completed execution. JobHandle scheduleParallelJobHandle = job.ScheduleParallel(position.Length, 64, scheduleJobHandle);

// Ensure the job has completed. // It is not recommended to Complete a job immediately, // since that reduces the chance of having other jobs run in parallel with this one. // You optimally want to schedule a job early in a frame and then wait for it later in the frame. scheduleParallelJobHandle.Complete();

Debug.Log(job.position[0]);

// Native arrays must be disposed manually. position.Dispose(); velocity.Dispose(); } }

公开方法

Execute针对特定迭代索引执行任务。