前言
当游戏开发使用传统的OPP(面向对象编程)面对大量的Game object时FPS会显著降低,而使用Dots(面向数据编程)性能依旧很好
计算机内存基础
CPU自身有三级高速缓存,L1,L2,L3,其中CPU访问(L1)缓存最快,容量最小,第三级(L3)缓存最慢,容量最大。
内存是指CPU拿取数据的起源点,CPU访问内存所需的时钟周期远大于访问高速缓存所需的时钟周期
CPU处理数据的速度非常快,因此需要高速缓存区避免CacheMiss高速缓存缺失,以确保CPU一直在运行(未休息)
CPU操作数据会先从一,二,三级缓存中取得数据,如果数据不在三级缓存,就需要寻址内存中的数据
Dots(Data Oriented Tech Stack) 面向数据的技术堆栈
是一系列的集合
Entity Component System(ECS) :实体组件系统
Burst Compiler :Burst编译器 ,也是LLVM编译器
Job System :任务系统
masmatic:数学库
ECS
为什么ECS架构会加快性能?
将传统游戏对象杂乱无序的组件归类,当读取数据时无法从L1中找到,先从这一堆杂乱无序的内中找到需要的内存,然后将它读取并且移动到L1缓存中,移除L1不需要的数据(因为内存容量小),这个过程就会造成CacheMiss
而当我们用ECS的架构组织数据,它会将相同组件Component 整齐排列在内存中,当我们开始遍历相同组件时并不需要一个个从内存中读取,可以指定一个长度一次性全读进来放入缓存中,因此避免了CacheMiss
因此ECS模式无疑更加适合现代CPU架构
Burst Complier
JobSystem
masmatic
DOTS配置
官方文档
注意unity版本
要使用 Entities 包,必须安装 Unity 版本 2022.3.0f1 及更高版本
必须使用可编程渲染管线:
内置渲染管线(Built-in Render Pipeline)不是可编程渲染管线
URP (Universal Render Pipeline)通用渲染管线,可编程
(High Definition Render Pipeline)(HDRP)高清渲染管线。可编程
安装包
- com.unity.entities工具包:包括ECS,Burst,Job System,masmatic
- com.unity.entities.graphics渲染entity
- com.unity.physics:ECS物理
- 通过window->packageManager->'+'加号->install package by name->install搜索
- 注意所有包的版本要一致,如果无法安装指定版本通过:
- 工程文件Packages/manifest.json中手动修正版本,重启引擎
IDE
版本要更新
unity设置
Edit > Project Settings > Editor菜单,然后启用 Enter Play Mode Options 设置,但禁用 Reload Domain 和 Reload Scene
c#Attribute特性
反射:
如果让你在不修改源代码的情况下,通过一个函数(参数为类类型),运行时获取所有参数为空的公有成员方法,这是不可能的
但是如果可以修改类呢?
- 可以让每一个类继承Object基类,每个类都手写一个FuncData的表(所有MetaData元数据(FuncData,PropData)数据表)
- 每个类都重写基类的public FuncData[] getFuncData();方法
这样就可以运行时获取
Attribute:
比如我们通过反射可以快速查找一个类是否仅包含数据
那如果我想要对特定类控制?
Attribute是反射的扩充,目的是在不破坏原有代码的 情况下,在代码的元数据上附加一些信息
[……]本质上:调用一个继承Attribute类的派生类的构造,通过注解可以快速查找包含指定属性的类,或者间接实现类的构造而非直接调用new等
其他性能优化
Object Pooling对象池
用于减少对象Instantiate()创建和destroy()销毁的性能开销,减少创建销毁api的调用
维护一个list<>
创建-》如果pool中没有obj,那么就instantiate,如果有就从池内取出对象
销毁—》使用完成放回池内
组合设计模式
- MVC(Model-View-Controller)
- MVP(Model-View-Presenter)
- MVVM(Model-View-ViewModel)
实现低耦合