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代码才继续
相关推荐
天人合一peng5 小时前
unity 生成标记根据背景色标记变色
unity·游戏引擎
天人合一peng9 小时前
unity 生成标记根据背景色变色为明显的颜色
unity·游戏引擎
魔士于安9 小时前
Unity 超市总动员 超市收银台 超市货架 超市购物手推车 超市常见商品
游戏·unity·游戏引擎·贴图·模型
CandyU29 小时前
Unity —— 数据持久化
unity·游戏引擎
zh路西法9 小时前
【Unity实现Oneshot胶卷显形】游戏窗口化与Win32API的使用
游戏·unity·游戏引擎
凡情14 小时前
android隐私合规检测
android·unity
小贺儿开发14 小时前
Unity3D 本地 Stable Diffusion 文生图效果演示
人工智能·unity·stable diffusion·文生图·ai绘画·本地化
mxwin1 天前
Unity Shader 半透明物体为什么不能写入深度缓冲?
unity·游戏引擎·shader
晚枫歌F1 天前
三层时间轮的实现
网络·unity·游戏引擎
咸鱼永不翻身1 天前
Lua脚本事件检查工具
unity·lua·工具