获取这些关于高级分析的有用提示

在六月,我们举办了一场网络研讨会,邀请了来自Arm、Unity Studio Productions团队和SYBO Games(Subway Surfers的创作者)的专家。结果圆桌会议集中讨论了移动游戏的分析技巧和策略、糟糕表现的商业影响,以及SYBO如何推出一款至今下载量达到30亿的热门移动游戏。
让我们深入探讨一些在网络研讨会期间没有时间讨论的后续问题。您还可以观看完整录音。
我们经常听到关于Unity Profiler与CPU分析相关的内容,但关于Profile Analyzer(作为Unity包提供)却不多。是否有计划改进它或将其集成到核心Profiler工具集中?
目前没有将Profile Analyzer集成到核心编辑器的计划,但随着我们的分析工具的发展,这种情况可能会改变。

Unity是否有计划添加一个选项,使GPU使用分析模块以百分比形式显示,就像它以毫秒形式显示一样?
这是个好主意,虽然在这篇博客发布时我们不能确定,但这是一个已经与我们的研发团队分享的请求,供未来考虑。
您是否有计划解决Google Play商店报告的“应用程序未响应”(ANR)错误,而这些错误没有任何堆栈跟踪?
虽然我们目前没有针对没有堆栈跟踪的ANR进行跟踪的具体计划,但我们会考虑将其纳入未来的路线图。
是否有一个好的规则来确定什么算是一个可行的低端设备目标?
我们从许多Unity游戏开发者那里听到的经验法则是,目标设备应为游戏发布时五年前的设备,因为这有助于确保最大的用户基础。但我们也看到团队将发布日期的范围缩小到仅三年前的设备,如果他们的目标是更高的图形质量。例如,一个视觉复杂的3D应用程序将比一个简单的2D应用程序有更高的设备要求。这种方法允许更高的“最低规格”,但减少了初始安装基础的规模。这本质上是一个商业决策:开发和支持旧设备的成本是否会超过你的游戏在这些设备上运行所能赚取的收入?
有时,你游戏的技术要求会决定你的最低目标规格。因此,如果你的游戏即使在优化后仍然消耗大量纹理内存,但你绝对无法降低质量或分辨率,那么这可能排除了在内存不足的手机上运行。如果你的渲染解决方案需要计算着色器,那么这可能排除了无法支持OpenGL ES 3.1、Metal或Vulkan的设备。
查看你的优先目标受众的市场数据是个好主意。例如,移动设备的规格在不同国家和地区之间可能差异很大。记得定义一些目标“预算”,以便在选择低端设备进行测试之前设定可接受的基准目标。
对于将运行多年的在线服务游戏,你需要持续监控它们的兼容性,并根据实际用户基础和市场上当前设备的变化进行调整。

仅在低端设备上测试性能是否足够,以确保游戏在高端设备上也能顺利运行?
如果你在所有设备上都有统一的工作负载,这可能是足够的。然而,你仍然需要考虑来自不同供应商和/或驱动程序版本的硬件差异。
图形丰富的游戏通常会有不同的图形保真度层级——视觉层级越高,能够的设备所需的资源就越多。这种层级选择可能是自动的,但越来越多的用户可以通过图形设置菜单控制选择。对于这种开发风格,您需要针对游戏支持的每个功能/工作负载层测试至少一个“最低规格”目标设备。
如果您的游戏检测到其运行的设备的能力并根据需要调整图形输出,则在高端设备上可能会表现不同。因此,请确保在您为其编程的不同质量级别的设备范围内进行测试。
注意:在本节中,我们已指定回答的专家来自Arm还是Unity。
您是否有关于检测设备功率范围以支持自动质量设置的建议,特别是针对移动设备?
Arm:我们通常看到开发者根据CPU和GPU型号以及GPU着色器核心数量进行粗略的能力分组。这从来不是完美的,但“差不多正确”。许多工作室从已部署的设备收集实时分析,因此他们可以通过设备特定的选择/退出来补充自动分组,以解决能力分组不够准确的问题。
与前一个问题相关,对于图形丰富的内容,我们看到移动设备上出现了一种趋势,即设置菜单,用户可以选择打开或关闭效果,从而允许他们做出适合自己偏好的性能选择。
Unity:设备内存和屏幕分辨率也是选择质量设置的重要因素。关于纹理,开发者应该意识到渲染纹理在高分辨率屏幕但内存不足的设备上可能会成为问题。
考虑到可用配置的广度(CPU、GPU、SOC、内存、移动、桌面、控制台等),您能否建议一种分类设备的方法,以减少需要优化的层数?
Arm:您的团队优化的层数实际上是一个游戏设计和商业决策,应该基于推动视觉质量对游戏价值主张的重要性。对于某些类型的游戏,这可能根本不重要,但对于其他类型,用户对视觉保真度的期望会很高。
在具有相同总系统内存的Android设备的型号和品牌之间,纹理内存限制是否不同?
Arm:在一阶近似中,我们预计不同供应商和硬件代之间的纹理内存总量是相似的。由于内存布局和对齐限制,会有一些小差异,因此不会完全相同。
是CPU还是GPU的使用对移动设备的过热影响最大?
Arm:这完全取决于内容。如果推得足够狠,CPU、GPU或DRAM都可能单独使高端设备过热,即使你完全忽略其他两个。确切的平衡将根据你正在运行的工作负载而有所不同。
你能给出哪些关于在有热限制的设备上进行性能分析的建议?你会选择什么边际来避免热限制(即,目标20毫秒而不是33毫秒)?
ARM:在安卓上优化帧时间可能会产生误导,因为设备会不断调整频率以优化能耗,使得帧时间本身成为一个不完整的度量。最好监控每帧的CPU和GPU周期,以及每帧的GPU内存带宽,以获得与频率无关的某些值。你需要的周期目标将取决于每个设备的芯片设计,因此你需要进行实验。
在管理功耗方面,任何优化都有帮助,即使它并不直接改善帧率。例如,减少CPU周期将减少热负载,即使CPU不是你游戏的关键路径。
除此之外,优化内存带宽是你可以做的最大节省之一。访问DRAM的成本比访问片上本地数据高几个数量级,因此要注意你的三角预算,并尽可能保持内存中的数据类型小。
Unity:为了限制CPU时钟频率对性能指标的影响,我们建议尝试在一致的温度下运行。有几种方法可以做到这一点:
- 保持温暖:让设备运行一段时间,以便在分析之前达到稳定的温暖状态。
- 保持冷却:在分析之前,请让设备冷却一段时间。这种策略可以通过捕获不太可能受到热限制的会话来消除分析会话中的混淆和不一致性。然而,这些捕获将始终代表用户所看到的最佳性能,而不是他们在长时间游戏会话后可能实际看到的性能。由于需要先等待冷却期,这种策略也可能会延迟分析运行之间的时间。
对于某些硬件,您可以固定时钟频率以获得更稳定的性能指标。然而,这并不能代表大多数用户将使用的设备,并且不会报告准确的实际性能。基本上,如果您使用持续集成设置来检查代码库随时间的性能变化,这是一种方便的技术。
关于Android上的Vulkan与OpenGL ES 3,您有什么想法?在性能方面,Vulkan通常较慢。同时,许多设备缺乏对ES3的各种功能的支持。
Arm:最近的驱动程序和引擎版本大大提高了可用Vulkan实现的质量;因此,对于相同的工作负载,OpenGL ES和Vulkan之间不应该存在性能差距(如果有,请告诉我们)。转向Vulkan的速度正在加快,我们预计在接下来的一两年中会有更多人默认选择Vulkan。如果您有Vulkan表现不佳的反例,请与我们联系。我们欢迎大家的声音。
我们可以使用什么工具来监控内存带宽(RAM <-> VRAM)?
Arm:Arm Mobile Studio中的Streamline Profiler可以测量Mali GPU与外部DRAM(或系统缓存)之间的带宽。

您应该按设备级别或设备分辨率拆分图形资产吗?
Arm:通过重新调整资产,您可以获得最佳结果,但这样做的成本很高。首先降低分辨率和帧率,或禁用一些可选的后处理效果。
如何记录我们开发版本的性能指标统计数据是最好的方法?
Arm:您可以使用Arm Mobile Studio中的性能顾问工具自动捕获和导出Mali GPU的性能指标,但这有一个警告:生成JSON报告需要专业版许可证。
Unity:Unity Profiler可用于查看常见的渲染指标,例如Rendering module中的顶点和三角形计数。此外,您可以在项目中包含自定义包,例如System Metrics Mali,以将低级Mali GPU指标添加到Unity Profiler中。
您对分析着色器代码有什么建议?
您需要一个GPU Profiler来做到这一点。您选择的工具取决于您的目标平台。例如,在iOS设备上,Xcode的GPU Profiler包括Shader Profiler,它逐行分析着色器性能。
Arm Mobile Studio支持Mali Offline Compiler,这是一个用于着色器代码和计算内核的静态分析工具。该工具提供了一些整体性能估计和对Arm Mali GPU系列的建议。
在分析时,一般规则是测试您的游戏或应用程序在目标设备上。随着行业向更多类型的芯片组(Apple M1、Arm、Intel、AMD的x86等)发展,开发人员如何在合理的时间内分析和定位许多不同硬件配置上的问题?
芯片组的普及主要是在桌面平台上的一个问题。用于控制台游戏的硬件架构数量有限。在移动设备上,iOS设备有Apple的A系列,Android有一系列Arm和高通架构,但选择一个可管理的代表性移动设备列表相对简单。
在桌面上则更棘手,因为可用的芯片组和架构范围广泛,购买Mac和PC进行测试可能会很昂贵。我们最好的建议是尽您所能。没有工作室有无限的时间和金钱进行测试。我们通常不会期待在比较英特尔x86 CPU和类似规格的AMD处理器之间的性能时有任何巨大的惊喜。只要游戏在你的最低规格机器上运行得舒适,你应该对其他机器有合理的信心。考虑使用分析工具,例如Unity Analytics,来记录帧率、系统规格和玩家选项设置,以识别热点或问题配置,这也是值得的。
我们看到越来越多的工作室开始使用至少某种程度的自动化测试进行定期的设备性能分析,并发布摘要统计数据,以便整个团队可以关注目标设备范围内的性能。通过精心设计的测试场景,这通常可以转化为适合自动化的机械过程,因此你不需要经验丰富的技术艺术家或QA测试人员手动运行构建过程。
你是否在高端设备上看到性能问题,而在低端设备上没有出现?
这并不常见,但我们确实见过。问题通常出在项目的配置上,例如在高端设备上使用华丽的着色器和高分辨率纹理,这可能会给GPU或内存带来额外压力。有时,高端移动设备或游戏机会将高分辨率手机屏幕或4K电视输出作为卖点,但不一定有足够的GPU性能或内存来兑现这一承诺,而无需进一步优化。
如果你使用当前版本的C#作业系统,请验证是否存在与工作线程数量成比例的作业调度开销,而工作线程数量又与CPU核心数量成比例。这可能导致在64+核心的Threadripper™上运行的代码比在适度的4核或8核CPU上运行得更慢。这个问题将在未来版本的Unity中解决,但在此期间,请尝试通过设置JobsUtility.JobWorkerCount来限制作业工作线程的数量。

设置良好的帧预算有什么建议?
大多数时候,当我们谈论帧预算时,我们是在谈论帧的整体时间预算。你可以通过计算1000/目标帧每秒(fps)来获得你的帧预算:30 fps为33.33毫秒,60 fps为16.66毫秒,120 Hz为8.33毫秒,等等。如果你在移动设备上,将这个数字减少约35%,以给芯片在每帧之间冷却的机会。将预算划分为不同特性和/或系统的具体子预算可能是多余的,除非是具有非常特定、可预测系统的项目,或那些大量使用时间切片的项目。
一般来说,性能分析是找到最大瓶颈的过程,因此也是最大潜在性能提升的过程。所以与其说,“物理学需要1.2毫秒,而预算只允许1毫秒”,不如看一下帧并说,“渲染需要6毫秒,使其成为帧中最大的主线程CPU成本。”我们如何减少这个?
在使用Unity Profiler的深度分析时,有没有办法排除某些方法的仪器化或仅包含特定方法?在使用大量async/await任务时,我们会创建大的堆栈跟踪,但我们如何避免在深度分析时减慢客户端和分析器的速度?
您可以启用分配调用堆栈以查看导致托管分配的完整调用堆栈(在Unity CPU Profiler时间线视图中显示为品红色)。此外,您可以并且应该!通过在代码中撒上ProfilerMarkers手动仪器化长时间运行的方法和过程。目前没有办法在应用程序的特定部分自动启用深度分析或完全禁用分析。但是,在需要时手动添加ProfilerMarkers并启用分配调用堆栈可以帮助您深入问题区域,而无需诉诸于深度分析。
从Unity 2022.2开始,您还可以使用我们的IgnoredByDeepProfilerAttribute来防止Unity Profiler捕获方法调用。只需将IgnoredByDeepProfiler属性添加到类、结构和方法中。

我在哪里可以找到有关Unity中深度分析的更多信息?
深度分析在我们的分析器文档中有介绍。然后有一个最深入的单一资源用于分析信息,即Unity游戏分析的终极指南电子书,其中链接到相关文档和其他资源。
深度分析是否仅对分配分析器有用,并且结果偏差如此之大,以至于无法用于查找游戏中的卡顿?
深度分析可以用来找到托管分配的具体原因,尽管分配调用栈可以以更少的开销做同样的事情。同时,深度分析可以帮助快速调查为什么一个特定的ProfilerMarker似乎花费了很长时间,因为启用它比在脚本中添加多个ProfilerMarkers并重建游戏更方便。但确实,它会严重扭曲性能,因此不应在一般分析中启用。
将VSync设置为每个VBlank值得吗?当禁用时,我的移动游戏以非常低的fps运行。
移动设备在驱动程序/硬件级别强制启用VSync,因此在Unity的质量设置中禁用它在这些平台上应该没有任何区别。我们没有听说过禁用VSync会对性能产生负面影响的案例。尝试在启用VSync的情况下进行一次分析捕获,以及在禁用VSync的情况下对同一场景进行另一次捕获。然后使用分析器比较捕获,以尝试理解为什么性能差异如此之大。
如何确定主线程是否在等待GPU,而不是反过来?
这在Unity游戏分析的终极指南中有介绍。您还可以在博客文章中获取更多信息,使用Unity帧定时管理器检测性能瓶颈。
一般来说,明显的迹象是主线程在等待渲染线程,而渲染线程在等待GPU。具体的标记名称会根据您的目标平台和图形API而有所不同,但您应该留意名称如“PresentFrame”或“WaitForPresent”的标记。

在移动设备(包括VR/AR)上优化和重写DOTS系统的部分代码是否有意义?您在项目中使用这个系统吗?
现在有许多游戏项目利用数据导向技术栈(DOTS)的部分。本地容器、C#作业系统、数学和Burst编译器都是您可以立即使用的完全支持的包,以编写最佳的、并行的、高性能的C#(HPC#)代码,以提高项目的CPU性能。
较少的项目也在使用实体及相关包,例如混合渲染器、Unity物理和网络代码。然而,目前列出的包是实验性的,使用它们涉及接受一定程度的技术风险。这种风险源于一个仍在发展的API,缺失或不完整的功能,以及理解数据导向设计(DOD)所需的工程学习曲线,以充分利用Unity的实体组件系统(ECS)。Unity工程师Steve McGreal撰写了一份关于DOTS最佳实践的指南,其中包括一些DOD基础知识和提高ECS性能的技巧。
您如何设置SetPass调用或着色器复杂度的限制?您甚至可以提前设置限制吗?
渲染是一个复杂的过程,没有实际的方法可以对SetPass调用的最大数量或着色器复杂度设置硬限制。即使在固定的硬件平台上,例如单个控制台,限制也将取决于您想要渲染的场景类型,以及在帧期间CPU和GPU上正在进行的其他工作。
这就是为什么关于何时进行分析的规则是“尽早且经常”。团队往往在生产早期创建一个“垂直切片”演示——通常是开发到最终游戏视觉保真度水平的短暂游戏体验。这是您第一次分析渲染并找出可能需要的优化和限制的机会。每当添加新的区域或其他主要视觉内容时,分析过程应重复进行。
以下是有关性能优化的额外资源:
博客
- 优化您的移动游戏性能:关于图形和素材的专家建议
- 优化您的移动游戏性能:关于物理、用户界面和音频设置的专家建议
- 优化您的移动游戏性能:来自Unity顶尖工程师的分析、内存和代码架构的专家建议
- Unity专家教你如何优化主机游戏画面
- Unity 2021 LTS中的分析性能:什么、何时以及如何
操作指南页面
电子书
学习教程
更高级的技术内容即将推出 – 但在此期间,请随时建议我们在论坛上讨论的主题,并查看完整的圆桌网络研讨会录音。
