一、unity原来的MC的缺陷
MonoBehaviour、Component和GameObject是unity最基础的单元。
通过创建GameObject,添加Component,然后再添加MonoBehaviour脚本是Unity的基础使用方式。其中MonoBehaviour承载了游戏逻辑和数据两部分功能,Component继承自MonoBehaviour,大部分时候Component的作用就是提供数据。
问题点
- 1、通过Component组织的数组是对CPU cache不够友好的,原因是并没有把需要多次重复计算更新的数据组织到一起,使得CPU在做计算时可能cache miss,如果游戏逻辑需要大量对象需要更新数据,可能这部分消耗是非常大的。
- 2、如果游戏中存在大量的GameObject,上面绑定大量的Component,那么执行大量的Update是非常耗时的,而且这些Update只能运行在主线程,无法并行。
- 3、MB不能很好的解决执行顺序问题,对于动态创建的GameObject,MonoBehaviour的更新顺序是不确定。
二、ECS解决了什么问题
-
1、将数据更有效的组织,提高CPU cache利用率
按照ECS设计规范,会把数据在内存中连续排列,从而在cache预读中能够将后续的数据一次性读取进来,提高cpu操作的效率。 -
2、并行化。
众所周知,unity是单线程的,几乎所有逻辑代码都跑在主线程上,当然有时也会将一些和显示无关的逻辑放入多线程中去执行,比如读取文件之类的。CS开放了底层的job system系统,在上层提供了c# job system,它是一套多线程调度系统。
三、ECS的缺陷或问题
- 1、目前的状况之下,CPU计算可能并不是重点。
绝大部分的unity项目,首要的性能热点都不是游戏逻辑本身,而是unity引擎本身的各种坑带来的性能消耗。比如mmo类游戏普遍的ui性能问题(ugui主要背锅)、GC(遥遥无期的mono SGEN垃圾回收机制)、渲染、移动(transform update的性能问题)、寻路、物理这些计算密集的大户,不少项目用的又是Unity内部的方案。手游现在普遍为了热更新而重度使用lua等方案去写逻辑,本身就是对cache不友好的。 - 2、ECS能很好解决数据单一而密集的问题,而很多情况下,无法对数据精心设计和拆分来达到这个条件。
- 3、ECS实现多态,需要通过为entity装配不同的component来实现,在实现类似很多技能效果这种节点的时候,不同逻辑其实使用的数据往往不相同,这样做本身就会对Cache不友好。
网友评论