我的订单|我的收藏|我的商城|帮助中心|返回首页
搜维尔[SouVR.com]>服务>案例分享 应用研究>案例分享>软件开发

Unity Burst:Neon intrinsics更新

文章来源: 作者:frank 发布时间:2021年08月11日 点击数: 字号:

Unity最近发布了Burst 1.5。新版本重点添加了多条Neon intrinsics指令。Neon intrinsics指令支持精确设定矢量指令,为Arm CPU的处理进程生成最为高效代码。Neon指令集传统上只适用于C/C++语言,而Unity目前已成功将其移植到了C#中。

不过,要找到最合适的指令并没那么简单,Arm为此特地制定了一份“Neon intrinsics在Unity中的运用”指南,外加一个带有开源代码的Unity项目,供广大开发者参考。这篇指南将帮助你以正确的结构构建Burst代码,让代码自动应用Neon指令集,享受其带来的性能提升,为你省去自行编写指令集的麻烦。我们下面就来看看怎样才能充分利用起Neon intrinsics。

自动矢量化(Auto-vectorization)

Burst编译器将自动采用Neon intrinsics来提高性能收益,而我们仍可以使用其它方法来进一步提高Burst性能。举例来说,我们可根据一定的结构来调整数据和函数循环结构,利用自动矢量化来获取大量的性能提升。

要想在Burst编译器中将四条指令合并为一条Neon SIMD指令,我们可编写简短、连贯并保留内联的函数。此外,经我们在物理碰撞模拟中测试发现,传入Burst函数的指针在添加[NoAlias]属性后,其速度可提高4倍。  

开发者现身说法

本文中的案例重点在于展示物理碰撞,因此上方演示场景仅使用了简单的胶囊型和立方体图形。例中对两种类型的碰撞进行了优化:用于角色-墙体间碰撞的轴向边框盒(Axis-Aligned Bounding Boxes,AABB),及用于角色之间碰撞的截面半径碰撞。

手动编写的指令要快于编译器并不简单,但这里将介绍几种方法。可以让性能改进不仅是个难以实现的目标。在进入分析优化阶段后,我们可以先分析线程的运行耗时,再进行调整,如此循环往复。我们能使用Profile Analyzer,或自己的计时方法来完成这一阶段的优化。

这时我们需要将注意力放到代码调整上。在本例中,我们将原先的Burst jobs代码转写成了静态函数,方便进行计时。异步执行功能在最终的游戏代码中发挥了巨大作用,尽管性能计时使得代码执行更为复杂了一点。在一个真正的游戏里,你需要使用ProfilerMarker、ProfilerRecorder和ProfileAnalyzer来计算job的耗时。而在此例中,改写后的Burst静态函数实际上强制在脚本中应用了自动矢量化结构。如果job使用的是由Burst静态函数组成的NativeArray,则基本类型的指针使用起来也会更加简单,静态函数会把数据拆分成更易矢量化的片段。而应用在指针上的[NoAlias]属性会告诉编译器指针调用的数据是否有重复。在此案例中,Burst的性能非常强大,以至于只有极其出色的Neon代码才能比它更快。为了充分发挥Neon的作用,这两种类型的碰撞都需要采用特定的数据和逻辑结构。

矢量化的效果在同时比对四个或八个对象时超好,因为这时运算可一次性完成(在Neon指令正确的情况下)。

新指令的效果可谓立竿见影,其中一项优化甚至能让Burst代码比结构精巧的非Burst代码快6倍,让手动编写的Neon代码快10倍。

电话:010-50951355 传真:010-50951352  邮箱:sales@souvr.com ;点击查看区域负责人电话
手机:13811546370 / 13720091697 / 13720096040 / 13811548270 / 13811981522 / 18600440988 /13810279720 /13581546145

  • 暂无资料
  • 暂无资料
  • 暂无资料
  • 暂无资料
  • 暂无资料