12. Burst

1.Burst简介

2.Burst解决什么问题

3.特性

4.使用场景

5.BurstCompile的配置参数


1.Burst简介

csharp 复制代码
Unity Burst是Unity推出的"高性能原生代码编译器", 基于LLVM架构, 专为Unity引擎的C#代码(尤其是数学计算、循环密集

型逻辑)优化, 能将C#代码直接编译为高度优化的原生机器码(x86、ARM等), 核心目标是突破托管代码的性能瓶颈, 让C#接

近C/C++ 的运行效率

csharp 复制代码
1).LLVM架构

LLVM架构为编译器开发提供了模块化的组件, 使得开发新的编程语言或优化现有语言的编译器变得更加容易; Unity中, 

Burst Compiler利用LLVM来优化和生成高性能的diamond, 特别是在"数学计算和循环密集型任务"上, 对于游戏性能至观重

要
csharp 复制代码
LLVM架构包含以下主要部分:

a.前端(Frontend): 将源代码(如C, C++, C#, Rust等)翻译成LLVM IR, LLVM IR是一种低级, 与平台无关的中间语言, 它

既保持了高级语言的语义, 又能被高效地优化和编译到不同目标平台

b.中间表示(IR): LLVM LR是LLVM的核心, 它是一种中间语言, IR可以被优化, 转换, 并且是连接前端和后端的桥梁

c.优化器(Optimizer): 对IR进行各种优化, 例如消除死代码, 内联函数, 循环优化等; 优化器由一系列的优化通道, 每个

Pass负责一个特定的优化

d.后端(Backend): 将优化后的IR转换为目标平台的机器代码
csharp 复制代码
由于LLVM的模块化设计, Burst可以只使用LLVM的部分功能; 由Unity自己将c#/IL转换为LLVM IR, Burst使用了LLVM的后端

为特定的CPU架构(如x86, ARM)生成代码, 并进行了大量的优化, 特别是针对数学计算和循环的优化

csharp 复制代码
2).数学计算、循环密集型逻辑

a.Unity上下文, "数学计算"特指涉及大量向量, 矩阵, 四元数, 三角函数等运算的代码

- 向量运算: Vector3的位置计算, 点乘/叉乘, 归一化, 距离判断等
csharp 复制代码
- 矩阵变换: 物体的移动, 旋转, 缩放, 坐标空间转换
csharp 复制代码
- 四元数: 旋转的插值, 组合
csharp 复制代码
- 三角函数: Mathf.Sin, Mathf.Cos, Mathf.Atan2等, 常用于周期性运动, 角度计算

- 物理计算: 射线检测, 碰撞检测, 力和速度计算

csharp 复制代码
b.密集型计算: 单帧内执行大量迭代的循环, 特别是嵌套循环

- 网格顶点处理: 修改Mesh的顶点, 法线, UV
csharp 复制代码
- 处理大量游戏对象: 遍历场景中的所有敌人, 子弹, 粒子
csharp 复制代码
- 集合批量操作: 寻路算法, 排序, 数据旋转
csharp 复制代码
- 处理像素点数量比较多的纹理, 比如: 生成纹理, 修改纹理

2.Burst解决什么问题

csharp 复制代码
1).Unity中默认的C#代码运行在Mono/IL2CPP虚拟机上

a.Mono: 即时编译(JIT), 启动快但运行时优化有限

b.IL2CPP: 提前编译(AOT), 跨平台兼容性好, 但优化程度中等

2).对于以下场景, 默认编译的性能往往不足

a.大量数学运算(如物理模拟、粒子系统、路径查找)

b.密集循环(如数组遍历、数据处理)

3).Burst的核心价值

通过深度优化编译, 让这些"性能敏感型"C#代码达到原生级速度, 同时保留C#的开发便捷性(无需切换到C/C++)

3.特性

csharp 复制代码
1).机制的代码优化

Burst基于LLVM进行底层优化, 优化级别远超Mono/IL2CPP

a.自动向量化: 利用CPU的SIMD(单指令多数据)指令集(如 SSE、AVX、NEON), 一次指令处理多个数据(例如同时计算4个

float的加法)

b.死代码消除: 移除未使用的代码, 减少冗余

c.循环优化: 循环展开、循环融合、循环向量化, 减少循环开销

d.常量传播与折叠: 编译时计算常量表达式(如2*3直接替换为6)

e.内存访问优化:减少缓存未命中, 优化数组访问(避免边界检查, 需配合[NativeDisableBoundsChecks])
csharp 复制代码
循环展开、循环融合、循环向量化

a.循环展开: "减少循环迭代次数, 把多次迭代的代码展开成一次执行"
csharp 复制代码
b.循环融合: "将多个循环合并成一个, 减少循环次数"
csharp 复制代码
问题: 两次循环 = 两次遍历内存, 缓存不友好
csharp 复制代码
c.循环向量化: 使用SIMD(单指令多数据)指令, 一次处理多个数据

csharp 复制代码
减少缓存未命中, 优化数组访问(避免边界检查, 需配合[NativeDisableBoundsChecks])

a.缓存未命中

现代CPU有三级缓存(L1, L2, L3), 访问速度递减, 但容量递增; 当CPU需要读取数据时, 先看L1缓存, 如果没有(缓存未命

中), 则看L1, L2, L3, 如果都没有则从内存读取; 内存访问速度比缓存慢的多, 因此减少缓存未命中是优化的关键
csharp 复制代码
b.优化数组访问

C#中, 数组访问会自动进行边界检查, 以确保索引在数组范围内; 这虽然安全, 但每次访问都会增加一次条件判断, 影响性

能; 循环中, 这种开销会被放大

Unity提供了[NativeDisableBoundsChecks]属性来禁用边界检查, 必须谨慎使用, 因为一旦越界, 将导致未定义行为(崩溃)

csharp 复制代码
2).与Unity生态深度集成

a.无缝兼容Job System(Unity多线程任务系统): Burst编译的Job是多线程高性能的核心组合

- "Job负责多线程调度"

- "Burst负责单线程计算加速"

b.兼容Native Collections(如NativeArray、NativeList), 直接操作非托管内存, 避免GC(垃圾回收), 同时Burst优化内

存访问

c.支持大部分平台

- PC(Windows/macOS/Linux)

- 主机(PS5/Xbox Series)

- 移动设备(iOS/Android)

- WebGL(需Unity 2021+)

csharp 复制代码
3).零GC开销

Burst编译的代码若使用非托管类型(struct、NativeArray、值类型), 可完全避免GC

a.不允许托管引用类型(如 string、List<T>、自定义类)

b.不允许装箱/拆箱

c.强制使用值类型和Native Collections, 从根源消除 GC

4.使用场景

csharp 复制代码
1).能用的场景("直接加[BurstCompile]生效")

a.Job结构体(最常用): 实现IJob/IJobParallelFor等接口的struct(必须是值类型)

b.普通计算型结构体: 纯值类型(无托管成员), 仅包含数学计算/数据处理方法的struct(可在Job/非Job中调用)

c.静态工具方法: static方法(无托管依赖、仅做计算, 比如数学工具、算法封装)

d.支持的载体:

结构体的实例方法/静态方法

独立的静态函数(非类成员方法)
csharp 复制代码
2).不能用的场景(加了也编译失败/无优化)

a.载体类型限制

❌ 类(class): 只能用于struct或静态方法, 不能给class加[BurstCompile]

❌ 接口、委托、枚举: 这些类型不支持Burst编译

b.代码内容限制(只要包含以下任一, 就不能用)

❌ 用托管类型: string、List<T>、Dictionary<T>、自定义 class、数组以外的集合

❌ 调Unity引擎API: GameObject、Transform、Debug.Log、Time.deltaTime 等

❌ 用复杂语法: 反射、LINQ、async/await、try/catch、yield 迭代器

❌ 重写object方法:ToString()、Equals() (依赖托管的 object 类型)

c.调用场景限制

❌ 不能直接修饰MonoBehaviour类/方法(比如给Update()加[BurstCompile]无效)

❌ 不能修饰UI逻辑、网络请求、文件读写等非计算型代码(优化无意义)
csharp 复制代码
3).如果Job中调用了普通结构体(未标记 [BurstCompile]、纯值类型、符合 Burst 限制)

"Burst会对这个结构体的成员和方法进行优化"

5.BurstCompile的配置参数

csharp 复制代码
配置参数核心作用是精细化控制Burst的编译规则, 分别对应: "浮点数精度, 浮点数计算模式, 编译同步性"

csharp 复制代码
a.FloatPrecision.Standard: 浮点数精度控制

通俗理解: "规定Burst编译时, 浮点数计算要达到的精确程度"
csharp 复制代码
b.FlotaMode: 浮点数计算模式

通俗理解: "规定Burst对浮点数运算是否允许用更快但略微宽松的指令"
csharp 复制代码
c.CompileSynchronously: 规定Burst编译代码时是"同步编译"还是"异步编译"

- false(默认): "异步编译 ------ Burst会在后台线程编译", 当前线程先执行其他逻辑, 编译完成后自动切换到优化代码
csharp 复制代码
- true: "同步编译 ------ Burst会在代码第一次被调用时, 阻塞当前线程, 直到编译完成再执行"

比如: 第一次调度Job时, 主线程会等Burst编译完Job代码才继续
相关推荐
平行云PVT3 小时前
实时云渲染解决UE5 像素流插件迁移及传输数据受限问题
unity·ue5·xr·实时云渲染·云桌面·像素流·云推流
熬夜敲代码的小N6 小时前
Unity WebRequest高级操作:构建高效稳定的网络通信模块
android·数据结构·unity·游戏引擎
萘柰奈6 小时前
Unity【小问题】----URP项目中加载AssetBundle中的预设体即使加载了依赖的材质依然是紫色的问题
unity·游戏引擎·材质
wonder135797 小时前
UGUI合批分析和优化方法整理
unity·ugui
wonder135799 小时前
UGUI鼠标点击到按钮响应流程的源码分析
unity·ugui
熊猫悟道1 天前
Unity shader 之,Shader内部时间离散处理
unity·游戏引擎·材质·着色器
PA_1 天前
unity Component-Based Architecture游戏框架
游戏·unity·游戏引擎
yi碗汤园1 天前
C#实现对UI元素的拖拽
开发语言·ui·unity·c#
jtymyxmz1 天前
《Unity Shader》11.3.2 广告牌技术
unity·游戏引擎