ECS框架文档翻译九 Job Component System

以下文档均来源于ECS官网:

https://docs.unity3d.com/Packages/com.unity.entities@0.0/manual/ecs_entities.html

 

JobComponentSystem

自动作业(Job)依赖管理

管理依赖关系很难,因此在JobComponentSystem中我们为你自动完成它。 规则很简单:来自不同系统的作业可以并行读取相同类型的IComponentData。 如果其中一个作业正在写入数据,那么它们将无法并行运行,并将按作业之间的依赖关系进行调度。

public class RotationSpeedSystem : JobComponentSystem
{
    [BurstCompile]
    struct RotationSpeedRotation : IJobForEach<Rotation, RotationSpeed>
    {
        public float dt;

        public void Execute(ref Rotation rotation, [ReadOnly]ref RotationSpeed speed)
        {
            rotation.value = math.mul(math.normalize(rotation.value), quaternion.axisAngle(math.up(), speed.speed * dt));
        }
    }

    // 任意先前安排的作业,读/写Rotation或者写RotationSpeed,都将被自动安排到inputDeps依赖
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        var job = new RotationSpeedRotation() { dt = Time.deltaTime };
        return job.Schedule(this, inputDeps);
    } 
}

这是如何运作的?

所有作业和系统都会声明它们读取或写入的ComponentTypes。 因此,当JobComponentSystem返回JobHandle时,它会自动向EntityManager注册,包括所有的组件类型以及相关的读写的信息{译者注:在job.schedule()方法执行时,通过反射获取本Job的Execute方法的参数类型以及读写属性来注册}。

因此,如果一个系统写入组件A,而稍后另一个系统从组件A读取,则JobComponentSystem会查看它正在读取的组件类型列表,从而向您传递该作业对第一个系统的依赖关系。

JobComponentSystem只是根据需要,为各个作业串联出各方的依赖关系,因此不会产生主线程上的停顿。 但是,如果非作业系统访问相同的数据会发生什么? 由于声明了所有访问权限,因此在调用OnUpdate之前,ComponentSystem会自动完成针对系统使用的组件类型运行的所有作业{译者注:非作业系统运行在主线程,主线程会因此卡住}。

依赖管理是保守和确定的

依赖管理是保守的。 ComponentSystem 只跟简单地踪所有使用过的EntityQuery对象,并存储它们正在写入或读取的类型。

此外,在单个系统中安排多个作业时,必须将依赖关系传递给所有作业,即使有的作业可能需要很少的依​​赖关系。如果这样做发现性能存在问题,那么最好的解决方案就是将系统分成两部分。

依赖管理方法是保守的。它提保证了确定的和正确的行为,同时提供了一个非常简单的API。

Sync points(同步点)

所有结构级的变化都会产生硬性的同步点。CreateEntityInstantiateDestroyAddComponentRemoveComponentSetSharedComponentData 都有一个硬性的同步点。这意味着通过JobComponentSystem安排的所有作业都将在创建实体之前完成,而且这是自动发生的。例如:在帧的中间调用EntityManager.CreateEntity可能会导致一个大的停顿,来等待World中所有先前安排的作业完成。

有关在游戏过程中创建实体时,避免产生同步点的更多信息,请参阅EntityCommandBuffer

多个World

As a result, for streaming and procedural generation scenarios, it is useful to create entities in one World and then move them to another World in one transaction at the beginning of the frame.

每个World 都有自己的EntityManager ,因此有一组相对独立的JobHandle依赖关系管理。一个世界中的硬同步点不会影响另一个世界。  因此,对于流式和程序生成方案,在一个世界中创建实体,然后在帧的开始处,在ExclusiveEntityTransaction 将它们移动到另一个世界是有用的。

有关程序生成和流式方案避免生成同步点,以及System update order的更多信息,请参阅ExclusiveEntityTransaction

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值