LiteralliJeff 发表于 2022-11-14 11:51

Unity ECS内存分配器原理详解

ECS 为什么会高效,性能好,Entity的内存布局与分配就是非常重要的部分,今天我们一起来分析一下Unity ECS 架构里面如何来做高效的内存分配器。这种思路也可以给我们做内存分配提供很好的一个思路。
对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习unity的零基础小白,也有一些正在从事unity开发的技术大佬,欢迎你来交流学习。
1: ECS 里面基本的一些概念


ComponentData:
组件数据,开发的时候,可以把每个功能相关的数据放到ComponentData里面。
Entity:
对象实体,纯数据对象,里面包含了一个个的ComponentData, 每个相关功能使用的数据我们放Entity的ComponentData里面, 如图:


(Entity内存对象布局示意图)
System:
具体算法逻辑的实现,System算法数据基于Entity里面对应处理的ComponentData。游戏引擎每次Update的时候,System都会根据每个Entity里面的它使用的ComponentData, 来更新数据完成计算。
EntityManager:
负责Entity相关类型信息,对象实体的创建与管理。
Archetype:


World:
世界包含多个Entity组成Entity群体,通过世界把这些Entity群体孤立起来。Unity里面可以同时拥有多个不同的世界, 每个世界独立包含EntityManager, 与Systems, 在世界里面创建出来的一个Entity,只属于这个世界。世界里每个System也只能迭代一个世界里面的Entity实体数据。你可以创建多个World。
总结一下Unity ECS的使用步骤与逻辑关系:




(Unity ECS 架构图)
2: ECS 高效的内存模型与布局
作为架构师,设计框架数据结构由为关键。特别对于游戏开发,要处理迭代成百上千个游戏物体。高效的内存模型与布局如何实现? 首先要明白怎么样布局内存才会高效。内存模型布局高效主要从两个方面来考虑:
1:内存对齐。
CPU访问不同地址的内存数据的时候,如果内存地址基于2^n 数据对齐(n根据CPU而定),访问最为高效。例如我们以16字节数据对齐,那么对象内存开始排布的时候, 从地址能整除16的内存位置开始排布。高效的内存布局,对象实例内存地址要对齐,对象实例里面的每个数据成员内存地址也要对齐。Entity的内存分配与内存布局, 在创建Entity的时候,ECS系统就会注意Entity的内存对齐,同时也会注ComponentData在Entity里面排布的内存对齐,如果没有对齐,就会空一些出来。比如16字节对齐,一个ComponentData只有14个字节,实际上排布下一个ComponentData的时候是从16字节开始排布的。
2: CPU通过地址来取到内存数据的时,数据排布一起取的速度会更快。
ECS天然就具有这种优势。所有的逻辑代码迭代都是基ComponentData的,也就是算法迭代访问处理的数据都在一起,在一个ComponentData里面。这样访问数据高效,避免了地址的来回跳转。
3: Entity内存分配器 Chunk的设计
大量的Entity的创建与销毁,大量不同类型的数据对象交叉创建,很容易造成内存碎片。何为内存碎片?给大家举个例子,对象A,对象B(100字节),对象C连续排布,对象B销毁,内存释放,同时又请求分配对象D(80字节),系统在原来对象B的地方把一块内存分配给对象D,还剩了一小块内存(20字节)。而这一小块内存,无法分配给当前系统的任何一个对象,这样,这小快内存就再也无法使用了,造成内存碎片,随着系统不断运行,随着更多大量的创建与释放,内存碎片越来越多,分配/释放效率也越来越低。最终让系统越来越慢。解决这种大量创建与销毁,我们一般采用Cache内存池来做。那Unity ECS架构里面内存池是如何设计的呢?接下来我们来分析ECS里面基于Chunk的内存分配器。不同的Archetype,所对应的Entity的内存不一样,系统可能有N中不同的Archetype,而且Archetype是用户根据组件数据组合创建而来。
综上Unity ECS 是这样设计内存分配缓存池:
(1) 基于固定大小的Chunk来做内存缓存池。每个Chunk大小为16KB(引用来自于UnityECS 文档)


对于OS而言,ECS框架基于chunk来分配和释放内存,避免了内存碎片(大小都一样)。对于ArcheType而言,又基于特定ArcheType的Entity来做内存缓存,分配和释放都非常高效。
看完Unity ECS的架构设计与内存布局,我们在其他地方做ECS架构设计(游戏服务器)就有了一个很好的参考,设计万变不离其中。
页: [1]
查看完整版本: Unity ECS内存分配器原理详解