Unity DOTS

义项:Unity 高性能多线程架构
Unity DOTS

Unity DOTS 是 Unity 引擎的数据导向技术栈(Data-Oriented Technology Stack),由实体组件系统(ECS)、C# 作业系统(C# Job System)与 Burst 编译器三部分配合构成,目标是让游戏代码在多核 CPU 上高效并行执行[1][2]。它把数据按类型连续存放以提升 CPU 缓存命中率,并通过编译优化利用单指令多数据指令集,从而支撑大量同质对象同屏的模拟[3][4]。其 1.0 版本随 Unity 2022 系列面向生产环境提供。

目录
  1. 定义
  2. 原理
  3. 发展历程
  4. 应用
  5. 局限
  6. 参见

定义

Unity DOTS 并不是单一组件,而是一组技术与软件包的合称,其共同特征是以数据导向设计(data-oriented design)组织游戏代码[4]。按官方文档的划分,它的核心部分包括 Entities 包(实体组件系统的实现)、作业系统、Burst 编译器,以及配套的非托管集合库与数学库[1]。在核心之上还堆叠了若干专用包,例如面向实体的物理、联网、渲染与角色控制器包[1]。

第二段

原理

实体组件系统(Entity Component System,ECS)把原本由对象同时承担的数据与逻辑拆开。实体只是一个标识,自身不含数据也不含行为;组件是只带字段的结构体,用来承载数据;系统则集中编写逻辑,批量处理具备特定组件组合的实体[5]。组件以值类型而非托管堆对象的形式存在,因此同类数据在内存中连续排列[5]。

内存布局由原型(Archetype)决定。组件集合完全相同的实体会被归入同一原型,并分块存放在连续内存中[5]。这样遍历时一次即可把整块数据读入 CPU 缓存,减少缓存未命中;普通面向对象程序的对象分散在堆上,访问时更容易出现缓存未命中而拖慢速度[3]。

作业系统负责把可并行的计算拆成作业,分摊到多个工作线程上执行,其底层暴露的是引擎自身的 C++ 作业系统,使脚本与引擎内部处理可以同时运行[2]。Burst 编译器则把 IL/.NET 字节码翻译为高度优化的本机代码,基于 LLVM 编译基础设施,并开放 CPU 内建指令以便微调关键代码[2]。

$Burst 输出 \approx f(IL/.NET 字节码)$,其优化包括自动向量化、循环展开与去除堆分配,从而利用 SSE、AVX、NEON 等 SIMD 指令集[5]。三项技术叠加后,ECS 提供可并行的无状态任务,作业系统提供多核调度,Burst 提供高效机器码[6]。

发展历程

2018 年,Unity 在公布 DOTS 时同步展示了名为 Megacity 的技术演示,其中有数百万个静态模型、上万个音源与数千辆飞行汽车,用以说明旧式引擎难以实时完成这种规模的仿真与渲染[3]。此后数年该技术栈经过多代内部演进,Megacity 演示也发布了后续版本[3]。

较长时间内 ECS 相关包处于预览状态,Hurricane 相关组件与 API 多次变动[7]。2022 年 10 月前后,Entities 1.0 的预览版本发布,要求 Unity 2022.2.0b8 及以上版本,并带来实体层次面板、原型内存占用查看、系统开关等调试工具,以及用于把创作端对象转换为实体的 Baker 烘焙流程[8]。

随 Unity 2022.2 技术预览版一并提供的 ECS for Unity 已标注可用于生产,包含 Entities、Unity Physics、Havok Physics、Netcode for Entities 与 Entities Graphics 等包[9]。Unity 2022 LTS 发布时,Burst 编译器、C# 作业系统与 ECS for Unity 被描述为构成完整的 DOTS 解决方案[10]。

应用

该技术栈的典型场景是对象数量巨大且彼此差异很小的模拟,例如实时战略、弹幕射击、群体寻路与大规模单位同屏[6]。以作业系统与 Burst 组合实现的群体移动、最近邻查找等算法,在调节线程数与批大小后可获得显著加速,其中 Burst 优化在各类场景中都起关键作用[11]。

实际项目中,Stunlock Studios 在《夜族崛起》里用 ECS 完成开放世界的内容流式加载[4];Ramen VR 用其为虚拟现实大型多人在线游戏扩展玩法规模,Electric Square 则利用其确定性复现测试场景[4]。Kasedo Games 在《IXION》中用它支撑大量非玩家角色的模拟,Blackbird Interactive 在《Hardspace: Shipbreaker》中用其改造原本耗时较长的处理流程[4]。此外,部分渲染管线、动画与粒子系统也借助作业系统与 Burst 做并行计算,而不一定启用完整的 ECS[7]。

对于需要权威服务器与客户端预测的多人游戏,直接从 ECS 与面向实体联网包起步较为有利;而只做原型验证或不涉及联网的项目,沿用基于游戏对象的传统写法往往更合适[12]。

局限

作业系统与 Burst 的使用门槛高于普通脚本编写。Burst 上下文只能访问非托管数据,需要开发者自行管理内存,编写高性能代码还要求了解 CPU 架构、并发同步与 SIMD 指令集,因此它更适合封装成独立模块由资深人员完成,而不宜用于日常业务逻辑[7]。实测也显示,在小规模负载下单线程作业有时可与多线程持平甚至更好,优势要到对象数量上升后才明显[11]。

收益还依赖对象之间的同质程度。有研究指出,DOTS 在对象数量增加时表现更好,但前提是对象差异较小;差异变大时,面向对象写法在维持性能上反而更稳[13]。把类的数据拆成多个结构体也会使代码可读性下降、迭代逻辑变复杂[13]。

工程层面同样存在摩擦。组件须为可直接映射的类型,引用类型无法直接嵌套,需要额外的序列化桥接;Burst 编译后的作业内调试体验与普通 C# 有别,错误堆栈的指向也不直观。从既有项目迁移往往不只是改数据,还涉及算法重写与工作流调整,编辑器内仍以游戏对象进行创作、运行后逻辑转入 ECS,两种流程并行带来割裂感,且部分内置功能与第三方插件的适配仍在完善中[14]。教程与最佳实践相对零散,也是采用时被提到的障碍[7]。

参见

词条评价
词条统计

浏览次数:0 次

阅读量:0 次 · 阅读完成量:0 次

最近更新:2026-10-28T18:47:03Z

历史版本

本条目引用的词条
实体组件系统 Unity Burst 编译器 数据导向设计 单指令多数据 多线程