Unity ECS+Jobs System笔记 简单介绍(一)

从Unity2018开始,推出了DOTS——多线程式数据导向型技术堆栈,其中有三板斧,分别是ECS、Jobs System、Burst,其中Burst是编译器加速,对于普通开发者来说ECS+Jobs System才是关注的重点,在这里我就为大家简单介绍一下着两个系统。

参考来源 https://software.intel.com/pt-br/articles/get-started-with-the-unity-entity-component-system-ecs-c-sharp-job-system-and-burst-compiler

ECS

GameObject系统

在介绍ECS之前首先要介绍Unity目前使用的GameObject系统
Unity ECS+Jobs System笔记 简单介绍(一)_第1张图片
目前的GameObject系统就是由以下三部分组成

  1. GameObject对象(GameObject)
  2. Transform、RigidBody等组件(Component)
  3. 各种脚本(Script)

这三者之间都是通过内存引用来相互连接
而整个Unity的生命周期就是通过遍历场景中所有的对象,再去调用其中的函数,如下图所示
Unity ECS+Jobs System笔记 简单介绍(一)_第2张图片
这个结构虽然能够让大部分的开发者快速上手,但由于对象与组件之间存在着地址引用,且它们在内存上过于分散,那么在性能上有一定会有一些缺陷
Unity ECS+Jobs System笔记 简单介绍(一)_第3张图片
并且有时候在组件中会存在一些我们并不需要的数据:比如Transform组件,如果该对象我们只需要它旋转,并不需要移动,那么Position数据对于我们来说就是多余的,而这个时候,我们从硬件中访问这些数据的时候,就会在缓存中加载一些不必要的数据

ECS系统

事实上,ECS系统和GameObject系统类似
是由以下三部分组成

  1. Entity对象
  2. Component等组件(只有数据)
  3. 管理Components的System(只有行为)

Unity ECS+Jobs System笔记 简单介绍(一)_第4张图片
类似GameObject系统,在Entity中也有不同的Component,只不过这些Component中只有数据,而这些数据通过System(只有行为)进行管理,例如所有的Rotation组件都通过RotationSystem进行管理
这种方式有点类似我们在处理GameObject时,通过List、Dictionary等容器对实例进行管理,那么它的优势在哪?

就是ECS系统中Component在内存中的分布

  • 在GameObejct系统中,各个对象、组件在内存中都是碎片化分布的,通过指针来进行引用
  • 在ECS系统中,各个对象、组件在内存中都是顺序排布的
    Unity ECS+Jobs System笔记 简单介绍(一)_第5张图片

可以自行查询有关CacheLine内容

可以看到,因为各个组件在内存中是顺序排布的,这有利于提高缓存效率,缩短访问时间;
同时在目前CPU使用数据对齐的情况下,采用SIMD/auto-vectorization技术来提升游戏的默认性能。
对比来看,ECS系统有着更紧密的内存排布和更少的内存浪费


我们可以看出,ECS使得Component在内存上有着更加紧凑的结构,而Jobs System可以更加高效来处理这些紧凑的数据,使其更加适合并行处理

Jobs System

对于大部分人而言,写多线程程序会存在一些潜在的危险,如何去平衡线程负载并保证线程安全是一个问题,而Unity的Jobs System就为我们解决了这一问题——如果当某个逻辑比较耗时,那就可以利用Job System

例如:做一个子弹系统

  • 在原本的GameObject系统中,我们通常会建立一个容器来保存这些子弹,然后通过遍历容器来执行子弹中的脚本,然后进行移动,而这些都是在主线程中做的
  • 而在Jobs System中,如图,主线程在一个Schedule中会把每个子弹的移动行为作为一个Job,然后分配给一个工作线程去处理
    Unity ECS+Jobs System笔记 简单介绍(一)_第6张图片
  • 为了多线程的安全,需要新的容器——NativeList和NativeArray,并且要注意这个容器是临时使用还是长时间使用,合理使用Dispose
  • NativeList即可读也可写,而NativeArray只可读或写
  • 注意不要在Job System中使用托管内存,结构体在大于40Byte时就会变成内存赋值,因此要控制值的大小,也可以使用Ref Return来避免

总结

ECS是一种全新高性能多线程式数据导向型技术堆栈
这里的重点在于多线程数据导向,即Jobs SystemECS

  • Job System,用于高效运行多线程代码
  • ECS(Entity Component System),用于默认编写高性能代码

在这里 Job System是一种新的多线程编程方式,而ECS是一个新的编程思路
OOP注重对象,而ECS注重组件,在这个单核趋于平稳而多核兴起的时代,我觉得Jobs System+ECS是一种趋势,之后应该会有更多针对多核的开发,而Unity的这个系统会成为这方面的代表

你可能感兴趣的:(Unity笔记)