一、一句话回答Burst解决的核心问题C#太慢C太难写Burst让你用C#的语法写出接近C的性能。二、为什么需要BurstC#在Unity中的性能瓶颈传统Unity C#代码的执行链路 C#源码 → IL中间码 → Mono JIT → 机器码 ↑ 这一步是瓶颈 Mono JIT的问题 1. 运行时才编译优化时间有限不敢做太激进的优化 2. 无法利用CPU的SIMD指令SSE/AVX/NEON 3. GC垃圾回收随时可能暂停你的代码 4. 对象在堆上分散分布缓存命中率低 结果 同样的数学运算C#比手写C慢 5~50倍 对于CPU密集型计算这个差距是致命的传统解决方案的痛点方案一用C写插件 ✓ 性能好 ✗ 开发效率低调试困难 ✗ 需要维护多平台编译 ✗ C#和C之间的互调有开销P/Invoke 方案二用IL2CPP ✓ 比Mono快不少 ✗ 仍然受限于C#的内存模型GC、引用类型 ✗ 编译时间长 ✗ 无法充分利用SIMD 方案三手动优化C# ✗ 能做的有限天花板低 ✗ unsafe代码写起来痛苦三、Burst怎么解决这些问题Burst的执行链路 C#子集(HPC#) → IL中间码 → Burst(基于LLVM) → 高度优化的机器码 ↑ 关键差异在这里 Burst做了什么 ┌──────────────────────────────────────────────────────┐ │ │ │ 1. 自动SIMD向量化 │ │ 一条指令同时处理4个/8个float │ │ 你写 a bBurst自动用SSE/NEON指令 │ │ │ │ 2. 激进的内联和循环优化 │ │ 基于LLVM和clang/rustc同级别的优化能力 │ │ │ │ 3. 零GC │ │ HPC#子集禁止使用引用类型class/string等 │ │ 只用值类型struct→ 没有堆分配 → 没有GC │ │ │ │ 4. 内存连续布局 │ │ 配合NativeArray等容器 │ │ 数据在内存中紧密排列 → CPU缓存命中率极高 │ │ │ │ 5. AOT编译 │ │ 提前编译好运行时直接执行 │ │ 不像JIT那样边跑边编译 │ │ │ └──────────────────────────────────────────────────────┘性能对比典型场景10000个物体的位置更新 普通C#Mono ~15ms IL2CPP ~5ms Burst Jobs ~0.3ms 手写C SIMD ~0.25ms Burst达到了手写C约85%~95%的性能 但开发效率远高于C四、Burst服务的核心场景场景一大规模物理/碰撞计算问题 万人同屏的战场每帧需要做大量碰撞检测 Unity内置物理引擎不够灵活或性能不够 Burst方案 自定义空间划分网格/四叉树 碰撞检测逻辑用Burst Job并行计算 [BurstCompile] struct CollisionJob : IJobParallelFor { [ReadOnly] public NativeArrayfloat3 positions; [ReadOnly] public NativeArrayfloat radii; public NativeArraybool collisionResults; public void Execute(int i) { for (int j i 1; j positions.Length; j) { float dist math.distance(positions[i], positions[j]); if (dist radii[i] radii[j]) { collisionResults[i] true; } } } } 典型游戏 大型RTS星际争霸级别的单位数量 弹幕游戏满屏子弹碰撞 物理沙盒场景二大规模AI/寻路问题 1000个NPC同时寻路A*算法每帧跑不完 Burst方案 寻路算法用Burst加速 多个NPC的寻路任务用Job System并行 典型游戏 城市建造模拟城市、城市天际线 RTS单位群体寻路 僵尸潮/人群模拟场景三程序化生成问题 运行时生成地形、网格、噪声图 Perlin Noise、Marching Cubes等算法计算量巨大 Burst方案 [BurstCompile] struct NoiseJob : IJobParallelFor { public int width; public NativeArrayfloat heightMap; public void Execute(int index) { int x index % width; int z index / width; heightMap[index] noise.cnoise(new float2(x * 0.1f, z * 0.1f)); } } 典型游戏 我的世界类体素游戏区块生成 无人深空类程序化星球 Roguelike地图生成场景四粒子/特效系统问题 十万级粒子的位置、速度、生命周期更新 Unity内置粒子系统不够灵活 Burst方案 自定义粒子系统每个粒子的更新逻辑用Burst并行处理 [BurstCompile] struct ParticleUpdateJob : IJobParallelFor { public float deltaTime; public float3 gravity; public NativeArrayfloat3 positions; public NativeArrayfloat3 velocities; public NativeArrayfloat lifetimes; public void Execute(int i) { lifetimes[i] - deltaTime; velocities[i] gravity * deltaTime; positions[i] velocities[i] * deltaTime; } } 典型场景 大规模粒子特效 流体模拟 布料模拟场景五动画/骨骼计算问题 大量角色的骨骼动画混合、IK计算 每个角色几十根骨骼每帧都要算矩阵变换 Burst方案 骨骼矩阵计算并行化 动画混合用SIMD加速 典型场景 MMO城镇中几百个玩家同屏 大规模军团战场景六音频处理问题 实时音频DSP混响、均衡器、空间化 每秒处理44100个采样点延迟要求极低 Burst方案 音频处理管线用Burst编译 Unity的DSPGraph就是基于Burst的 典型场景 音乐游戏 VR空间音频 实时语音处理五、Burst的限制HPC# 子集Burst不是万能的它要求你只使用C#的一个子集 ┌─────────────────────────────────────────────────┐ │ │ │ ✓ 可以用 ✗ 不能用 │ │ ───────── ────────── │ │ struct值类型 class引用类型 │ │ NativeArrayT ListT │ │ NativeHashMapK,V DictionaryK,V │ │ math.sin/cos/... Mathf.Sin可以但慢│ │ float/int/bool string │ │ float2/float3/float4 Vector3可以但慢│ │ for/while循环 try-catch │ │ 固定大小数组 动态数组 │ │ 函数调用 虚方法/接口调用 │ │ ref/in/out参数 delegate/event │ │ LINQ │ │ 反射 │ │ 协程 │ │ │ └─────────────────────────────────────────────────┘ 本质 禁止一切可能触发GC的操作 禁止一切运行时动态行为 只保留纯计算能力六、Burst Job System 的协作关系Job System 和 Burst 是两个独立但互补的系统 ┌──────────────────────────────────────────────────────┐ │ │ │ Job System 多线程调度框架 │ │ 解决的问题如何安全地把工作分配到多个CPU核心 │ │ 没有Burst也能用只是每个Job跑得慢 │ │ │ │ Burst 编译器优化 │ │ 解决的问题如何让单个线程上的代码跑得更快 │ │ 没有Job System也能用主线程上也能Burst编译 │ │ │ │ 两者结合 多核 × 单核极致优化 最大性能 │ │ │ │ 打个比方 │ │ Job System 雇了8个工人8核CPU │ │ Burst 给每个工人配了电动工具SIMD优化 │ │ 两者结合 8个拿电动工具的工人 │ │ │ └──────────────────────────────────────────────────────┘代码示例两者结合 // 1. 定义JobJob System负责调度 // 2. 加[BurstCompile]Burst负责优化 [BurstCompile] struct MoveJob : IJobParallelFor { public float deltaTime; public NativeArrayfloat3 positions; [ReadOnly] public NativeArrayfloat3 velocities; public void Execute(int i) { positions[i] velocities[i] * deltaTime; } } // 调度 void Update() { var job new MoveJob { deltaTime Time.deltaTime, positions positionArray, velocities velocityArray }; // 分配到多个核心并行执行每个核心上跑Burst优化后的代码 JobHandle handle job.Schedule(count, 64); handle.Complete(); }七、总结┌──────────────────────────────────────────────────────────┐ │ │ │ Burst解决的根本问题 │ │ 游戏中CPU密集型计算的性能瓶颈 │ │ 用C#的开发效率获得C级别的运行性能 │ │ │ │ 核心服务场景 │ │ 一切大量数据 × 重复计算的场景 │ │ 物理、AI、寻路、粒子、程序化生成、动画、音频 │ │ │ │ 不适合的场景 │ │ UI逻辑、网络通信、文件IO、业务逻辑 │ │ 这些不是计算密集型用普通C#就够了 │ │ │ │ 一句话 │ │ Burst是给数值计算苦力活准备的涡轮增压器 │ │ 不是所有代码都需要它但需要它的地方它是救命的 │ │ │ └──────────────────────────────────────────────────────────┘