这篇文章是笔者对网上DOTS相关资料的总结,主要来自UNITY官方直播和unity社区的资料,还有其他网上同好的分享。如有纰漏,望读者指正,谢谢。
DOTS是什么?
DOTS全名:Data-Oriented Tech Stack(DOTS),即多线程式数据导向型技术堆栈。
简单来说,就是UNITY提供了一个高性能编程的解决方案,其中包含三个组成。
1)C#任务系统(Job System):用来方便地写出高效的多线程代码。
2)实体组件系统(ECS):一个用来实现高性能的实体框架。(类似原来的游戏对象组件系统)
3)Busrt编译器:用来生成高度优化的C#代码。HPC#(high preformance C#)。
这三个方案实际上各自独立各有优缺点,可根据实际情况组合使用。
DOTS能干什么呢?
由于DOTS只是一个提高性能的解决方案,可以应用各种场景,比如:
1) 用在网络通信上——Unity的NetCode 。
2) 用在网页和微信小程序那种小游戏——unity的Tiny项目。
3) 用在传统的3A游戏上——《守望先锋》。
DOTS是怎么优化游戏性能呢?接下来就依次对DOTS的三大部分来分析。
C#任务系统(JobSystem)
现在的CPU基本都是多核处理器。即使是笔者手中的千元机的骁龙430也号称8核处理器。但是大部分游戏都是单线程的,而少用多线程或进行多核优化的。一方面是多线程编程有难点,另一方面现在游戏基本是一条主线走下来,每个主要的游戏物体之间互相关联互动,用多线程如何处理分割这些逻辑上的依赖关系也是一个多线程编程的难点。
那么unity的JobSystem是怎么解决的呢。
以我浅薄地理解就是开发者按照unity的jobSystem的语法写好Job,之后的分配和依赖问题交给jobSystem就好了,简单高效。
那么怎么创建一个Job呢?
以下是一个Job的示例代码:
[BurstCompile]//启用brust编译,之后会总结
public struct MyJob1:IJob//Job是结构体,实现一个IJob的接口
{
[ReadOnly] public int left;
[ReadOnly] public int right;//两个readonly的数据为输入数据
[WriteOnly] public NativeArray<int> @out;//writeOnly为输出数据
public void Execute()//要另开个线程来计算的逻辑代码放到这个方法里
{
@Out[0] = left * right;//这里简单地计算下输入数据的乘积
}
}
private void Start()
{
MyJob1 myJob = new MyJob1();//创建一个Job
myJob.left = 2;//输入
myJob.right = 3;//输入
myJob.@out = new NativeArray<int>(1