使用 Burst 1.7 提高您的游戏水平

TIM JONES / UNITY TECHNOLOGIESSenior Software Engineer
Mar 14, 2022|9 Min
使用 Burst 1.7 提高您的游戏水平
为方便起见,此网页已进行机器翻译。我们无法保证翻译内容的准确性或可靠性。如果您对翻译内容的准确性有疑问,请参阅此网页的官方英文版本。

最新版本的 Burst 软件包对迭代时间和 Burst 检查器都做了很大改进。在这篇文章中,我们将探讨有哪些变化,以及我们的高性能 C# (HPC#) 编译器技术现在如何帮助您在所有平台上更轻松地提高性能。

虽然我们的 DOTS 技术栈利用Burst提供高度优化的代码,但 Burst 是一个独立的软件包,可在 Unity 2019.4 或更新版本的软件包管理器中使用。您在所有主要桌面、控制台和移动平台上的数以千计的项目已经在利用 Burst 的优势。

迭代时间

在以前的 Burst 版本中,我们在改善 Burst 日常工作体验方面取得了重大进展。在 Burst 1.7 中,我们延续了这一趋势,重点改进了迭代时间。迭代时间是什么意思?我们指的是开发的 "内循环"--你对 C# 脚本进行修改,切换回编辑器,等待脚本编译完成,等待 Burst 编译完成,然后进入播放模式测试你的修改。

在 Burst 1.7 中,我们大大缩短了您等待 Burst 的时间,您只需对游戏代码稍作修改,然后在 "播放 "模式下进行测试即可。现在,Burst 编译会在管道的较早阶段进行(紧接在脚本编译管道完成 .NET 程序集编译之后),因此在许多情况下,当需要运行生成的代码时,编译工作已经完成。Burst 不再像以前的 Burst 版本那样单独编译每个 Burst 入口点,而是将 Burst 入口点(如作业或函数指针)分批编译,以提高编译器的吞吐量并减少编辑器需要加载的库数量。

Burst 1.7 还对直接呼叫性能进行了重大改进。直接调用是我们在 Burst 1.5 中添加的一项功能,它允许托管 C# 代码直接调用 Burst 编译过的方法,而无需通过 BurstCompiler.CompileFunctionPointer。在域重载期间,需要进行一些初始化工作来连接直接调用方法,而在 Burst 1.7 中,我们将初始化速度提高了 33 倍。

关于迭代时间的最后一点,我们研究了SharedStatic初始化的成本。SharedStatic 是一种允许托管 C# 和 HPC# 共享数据的机制。在 Burst 1.7 中,我们将 SharedStatic 初始化速度提高了 13 倍。

下图显示了 Burst 1.7 与 Burst 1.6 相比的性能改进。测量是在一个大型客户项目中进行的。下面第一张图显示的是使用秒表(实际的秒表,而不是 System.Diagnostics.Stopwatch)观察编辑器的时间,因此它们应该能反映出日常使用中的改进情况。

Burst 1.7 性能改进

下面的第二张图表只关注 Burst,因此不包括编辑器中可能出现的其他内容。对于这个特定项目和修改后的文件,Burst 1.7 在所有三个时序上都比 Burst 1.6 快:

  • 冷缓存 - Burst 尚未缓存项目中代码的任何编译结果。
  • 暖缓存 - Burst 已经编译了项目中的代码,需要从磁盘加载缓存的编译结果。
  • 更改一个文件 - 更改一个文件后,Burst 会检查哪些入口点需要重新编译,并编译这些入口点。请注意,Burst 1.7 中的改进量一般取决于更改文件。例如,如果您更改了所有Burst 入口点使用的方法,那么 Burst 1.6 和 Burst 1.7 之间的差异就会变小。在这个例子中,入口点方法本身被更改了。
Burst 1.7 性能改进 2
爆破检查员

突发检查器(可通过 "任务 > 突发 > 打开检查器... "访问)是一款非常有用的优化工具。使用该工具,您可以查看将在目标 CPU 上执行的汇编代码。在 Burst 1.7 中,我们添加了几项备受期待的功能。一张截图胜过千言万语,就不多说了:

爆破检查员分支标记

如您所见,我们添加了分支标记,使代码执行路径更加直观。请注意,分支标记可以通过 "显示分支流 "复选框关闭,这样在不需要时就不会碍事。这项功能的一个特别之处在于,你可以点击分支流箭头,然后跳转到箭头的另一端,就像这样:

点击分支标记跳转到分支目的地的示例

不太重要的反汇编块(如指令或常量数据)现在会自动折叠,但仍可在需要查看时进行切换。

Burst 1.7 的新功能还包括仅选择分解的一部分并将其复制。

选择和复制反汇编特定部分的示例

杂项改进

以下是 Burst 1.7 中较小但同样重要的改进列表。

  • 现在已完全支持 Arm Neon vst1* API。我们在 Burst 1.6 中添加了这些 API,但将其隐藏在试验性 #define 之后。在 Burst 1.7 中,它们不再受 #define 的保护,而是完全受支持。
  • 现在,Bursted 代码中支持 System.Span<T> 和 System.ReadOnlySpan<T>。这些类型不允许作为入口参数。
  • Burst 现在默认使用 LLVM 12.0.0 版,带来了 LLVM 项目的最新优化改进。
  • 我们更改了 LLVM 优化流水线,在循环矢量器之后才运行循环展开器。这在很多情况下都能改善 codegen 的性能。
  • 我们让 fmod 和浮点数使用更快的算法,以提高性能。
  • 现在,Burst 会自动生成 link.xml,以避免因使用静态构造函数而导致运行时符号缺失的 IL 剥离。
  • 通过检测更多可将加载/存储安全转换为移动内存操作的情况,我们提高了编译器在进行大型结构复制时的性能。
  • 我们更改了在 Burst 菜单中启用 "显示时序 "选项时显示时序的方式。通过清理并以更清晰的方式呈现信息。
Burst 的下一步计划

请注意,Burst 1.7 是支持 Unity 2019.4 的最后一个版本。下一个 Burst 版本的最低要求是 Unity 2020.3。如果您有任何想法、问题,或者只是想让我们了解您使用 Burst 的情况,请随时在Burst 论坛上给我们留言。