65.9K
CodeProject 正在变化。 阅读更多。
Home

坦克世界:现代图形需求的自动化性能测试

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2021 年 3 月 11 日

CPOL

15分钟阅读

viewsIcon

5735

Arm Mobile Studio Pro 允许我们在执行 CI 服务器上的自动测试时记录 Mali 系列 GPU 的硬件计数器,从而帮助我们解决任务。

《坦克世界》(WoT) 闪电战是一款基于回合制的坦克射击游戏,自 7 年前发布以来,一直由 MS-1(Wargaming 最古老、规模最大的移动工作室)不断更新。2014 年,该游戏在 iOS 和 Android 上发布;几年后,它被发布到桌面平台(Windows 和 macOS),并在 2020 年,WoT 闪电战首次登陆 Nintendo Switch。Android 和 iOS 仍然是我们关注的关键平台,这里需要注意的是,我们努力使闪电战在性能方面具有可扩展性;从低端移动设备到最新的旗舰设备。

性能对每个游戏都至关重要。我们近 200 人的开发团队在独立的、跨职能的团队中工作,每年发布约 10 次重大更新。为了跟上这种节奏和规模,我们必须自动化许多流程,性能测试也不例外。本博客探讨了持续集成 (CI) 测试的使用如何帮助我们为 WoT 闪电战打造最佳玩家体验。我们还将深入探讨以下主题:

  1. 自动化性能测试方法概述
  2. CPU 分析
  3. Arm Mobile Studio 和 Performance Advisor 在我们工作流程中的作用 

WoT 闪电战性能测试概述

如果我们暂时忽略游戏大厅,只考虑实际游戏(战场),性能测试包括对以下指标的控制:

  1. 进程使用的内存
  2. 地图加载时间
  3. 帧时间

自动化测试每晚针对主线构建触发。QA 工程师在验证包含以下任一内容的更改集时也会触发这些测试:

  1. 内容更改
  2. 可能影响性能的代码更改

我们使用 CI 服务器运行测试,其中测试设备充当构建代理。我们的测试农场包含 30 多台设备,代表所有支持的平台和整个性能水平范围。

我们尽最大努力在问题进入主线之前就识别出来,但如果发生了,每晚的回归测试就会显示出来。由于我们拥有大量内容和众多设备型号,我们制作了一个特殊的仪表板来显示所有夜间测试结果。下面是地图加载时间测试仪表板的一部分状态(完整版本有 13 列和 30 行)。

凭借我们的开发节奏和规模,保持健康的主线至关重要:由于我们坚持早期集成原则,并且在组装构建进行测试时,功能分支始终与主线合并,因此主线中的问题可能会被解释为功能分支问题。因此,我们对修复主线中发现的问题有严格的规定:导致问题的特性必须在工作日内禁用或回滚。

考虑到我们拥有大量内容,以及我们支持的平台和性能水平,很难想象我们的开发没有自动化性能测试。

  1. 如果我们必须手动运行自动化流程每晚触发的所有测试,我们将不得不为此分配 2 到 3 名全职员工。但更可能的是,我们只会妥协设备或内容覆盖范围或回归测试的频率,这会对开发速度产生负面影响。
  2. 测试需要性能测试的新内容和功能将比今天花费多 10-20% 的时间。此外,由于手动性能测试的可靠性较低,更多问题将潜入主线。

报告中对详细数据的需求

如上所述,我们在一个工作日内解决主线问题对我们至关重要。但由于我们拥有许多独立且专业的团队,首先我们必须找出哪个团队负责这个问题。尽管测试每晚运行,但以我们的开发规模,每天有 10 到 15 个非平凡的 PR 合并到主线。而且,仅仅通过查看代码并不总是能弄清楚是哪个导致了问题。这就是为什么我们希望自动化测试报告尽可能提供关于究竟是什么导致某个指标发生变化的详细信息。

除了确定哪个团队负责修复主线中的问题外,报告中的额外数据对于功能测试非常有价值。看到报告中的详细数据(例如,哪个函数现在执行时间更长),程序员即使没有手动分析游戏,也能定位问题。同样,能够访问此类数据的 the content makers 也能立即了解在哪里进行优化。

例如,对于内存测试,我们使用带有 Memory Profiler 的特殊构建。这可以将使用的整个内存池划分为“类别”(有近 30 个),而不仅仅是看到单个值的变化(进程的总内存使用量),而是更详细的图景。

对于地图加载时间测试,报告中仅包含一个数字(加载时间)。

但如果出现问题,您可以定位测试工件中的 json 文件,其中包含分析器跟踪。

要理清地图加载时间增加的问题,只需下载两个测试运行的 json 文件并使用 chrome://tracing 进行比较即可。

对于 FPS 测试,我们花了相当多的时间思考一种方便的方式来呈现报告中的细节。但在展示结果之前,我们将稍微介绍一下我们对此类测试的总体方法。

FPS 测试概述

FPS 测试是基于重放的:添加新游戏地图后(目前有 30 张),我们会进行一次游戏测试,选择其中的一个重放,并将其放入存储库。之后,此重放将用于 FPS 测试。

重放基本上是所有服务器消息的日志加上客户端状态的一部分(例如,摄像机视角)。与手动脚本化的测试相比,这种方法有其优点和缺点:

优点

  • 测试非常接近玩家看到的内容:在重放过程中,会发生各种游戏事件,所有图形元素(UI、粒子)的显示数量与实际游戏内情况相同。
  • 新地图的测试很容易获得:没有脚本阶段,您只需要一次游戏测试。当然,您不能称这种测试为竞技场内容的完整测试:您只检查游戏测试期间一个特定玩家所走的路线。但为了检查内容,我们有单独的测试,摄像机依次放置在 8x8 网格的点上,在每个点上以 45 度为增量完全旋转。

缺点

  • 测试需要大量时间。一张地图的处理时间约为 4 分钟,如果我们将其乘以地图数量(30),则为 2 小时。
  • 在重放中,游戏状态变化非常动态,有时很难将短暂的 FPS 下降与重放的具体部分联系起来。

CPU 分析器如何增强 FPS 测试报告

长时间以来,我们在报告中观察到的唯一结果是平均 FPS 值。此外,在测试运行工件中,您可以找到重放期间 FPS 值的详细图表,其中点代表一秒间隔的平均 FPS 值。后者是一个错误,因为单帧的长帧被忽略了。当我们意识到这一点时,我们决定不仅测量每帧的持续时间,还要进一步深入,并在测试中启用我们的内部 CPU 分析器。我们必须限制每帧的计数器数量,以免分析器影响低端设备的帧时间。为此,我们添加了标签功能:代码中的每个计数器都被标记,我们可以打开或关闭标签组。默认情况下,在启动自动化测试时,每帧的计数器不超过 70 个。

在自动化测试中启用分析器开辟了新的机会:为单独函数的执行时间设置预算。这使您可以跟踪某些系统的性能峰值。此外,预算还使做出引入新系统的决策更加容易。例如,几年前我们决定在战斗中添加 UI 控件的自动布局时,我们只是确保它不会影响我们测试中的 FPS 值。引入分析器后,我们对在某些情况下花费在自动布局上的帧时间感到非常惊讶。正确的方法应该是先定义预算,然后再添加新系统(例如,“布局在 Samsung S8 上每帧的运行时间不得超过 1 毫秒”),并通过自动测试对其进行进一步控制,以免代码或内容更改导致超出预算。

在重放结束时,我们分析分析器跟踪,并将仅包含任何函数超出其预算的帧的 json 文件放入工件中。在下面的示例中,列出了几十帧;在每一帧中,Scene::Update 函数的执行时间都比应有的时间长。

对于峰值,一切都相对简单,但什么表示法可以轻松注意到某些函数执行时间的微小增加?比较两个四分钟长的跟踪似乎不是一个可行的选择,因此我们决定从一些统计数据开始。对于一小组最有趣的函数,我们计算执行时间达到某个范围的帧数,得到频率分布。

接下来,我们将这些数据发送到 BigQuery,并使用 DataStudio 进行可视化。

在上图表中,您可以看到 9 月 27 日执行 `Engine::OnFrame` 需要 24-28 毫秒的帧数显着增加。要找到原因,我们可以使用一个简单的序列:

  1. 沿着调用堆栈向下移动一个级别
  2. 通过仪表板过滤器依次选择此调用堆栈级别的函数,直到找到导致问题的函数。
  3. 如果我们还没有到达最低级别,请转到步骤 1。

如果我们到达最低级别并找到了“罪魁祸首”函数,那就没问题了。但是,如果执行时间对每个函数或多或少都均匀增长呢?这可能有几个原因:

  1. 极有可能这是热节流,这是移动设备性能测试中最大的复杂问题之一。我们通过将测试设备农场放置在冷房间来解决这个问题。尽管我们为测试创造了一些不太现实的条件,但我们使得大多数设备上的结果都稳定。
  2. 出现了一个新线程,与我们的代码争夺 CPU 时间。这可以通过采样分析器来识别。

尽管将插桩 CPU 分析器引入测试并没有排除使用采样分析器的必要性,但它减少了后者必需的情况。上面描述了一种情况,另一种是微优化,当您需要查看汇编代码中单个指令的执行时间时。

让我们回到我们的“9 月 27 日”问题。通过应用上述一系列操作,我们发现 `rhi::DevicePresent` 函数是罪魁祸首。此函数只是调用缓冲区交换,因此瓶颈一定在 GPU 端!但是,我们如何从报告中了解是什么导致 GPU 处理帧的时间更长呢?

GPU 指标

细心的读者可能会注意到,DataStudio 屏幕截图中的筛选器值之一看起来不像函数名称:“DrawCallCount”。我们还有其他类似的指标:“PrimitiveCount”、“TriangleCount”、“VertexCount”。 alas,这是我们从 CPU 端收集到的唯一数据,以找出 GPU 端减速的原因。但要解决“9 月 27 日”问题,这已经足够了。

事实证明,在许多帧中,我们开始绘制多出 15 万个图元。通过将这些数据与两次测试运行之间的时间间隔内合并的 PR 列表进行匹配(我们从图表中看到它们相隔 3 天,但其中 2 天是周末,没有测试),我们很快就找到了“罪魁祸首”的变更集。

但是,如果根本原因是着色器变得更复杂怎么办?或者绘图顺序发生变化,导致过度绘制增加?或者深度缓冲区意外开始保存到主内存中,从而对带宽产生负面影响?

这些指标在游戏中很难(如果是过度绘制)或不可能(如果是着色器复杂性和带宽)跟踪。而这正是 Arm Mobile Studio Pro 变得无价并帮助我们的地方。

Arm Mobile Studio Pro 如何提供 GPU 负载的洞察

Arm Mobile Studio Pro 允许我们在执行 CI 服务器上的自动测试时记录 Mali 系列 GPU 的硬件计数器,从而帮助我们解决三种类型的任务:

  1. 在回归测试中找到“GPU 端究竟发生了什么变化?”的答案。
  2. 在新内容测试中定位瓶颈并了解需要优化什么。
  3. 在引入新的图形功能时,有意识地选择目标设备(正如我们开头提到的,我们支持非常广泛的设备,因此图形功能通常通过图形设置菜单激活)。

Arm Mobile Studio 包含一个名为 Performance Advisor 的工具,这让我们能够将测试期间记录的分析器跟踪作为易于阅读的 html 报告进行呈现,这对我们来说非常重要。

让我们看看 Arm Mobile Studio(特别是 Performance Advisor)如何加速解决 3 型任务。

最近,我们在引擎中添加了贴花,我们的技术艺术家面临着为竞技场几何图形和贴花的重叠定义预算的任务。这项任务的本质是:

  1. 确定我们希望在此功能可用性的目标设备。
  2. 通过在已有的、FPS 测试结果已有的地图中添加贴花来准备测试内容。
  3. 在目标设备上运行更改内容构建的自动测试。
  4. 评估结果:如果 FPS 水平显着下降,则审查内容预算并返回第 2 阶段,或审查目标设备列表。

PA(Performance Advisor)极大地简化了第 4 阶段。假设在第 1 阶段,我们选择三星 Galaxy A50(配备 Mali-G72 MP3)作为目标设备。这是此设备上测试运行的 PA 报告的第一部分(高图形质量设置,但目前没有贴花)。

主要观察结果:

  1. FPS 在某些时候下降到 30。嗯,没有 PA 我们也能知道这一点。
  2. 在问题区域,设备明显受到片段限制。这个很有趣!我们可以对带有贴花的内容进行预测。

我们启动带有贴花的构建的测试,在工件中找到 PA 生成的 html 报告,然后打开它。

嗯……在这台设备上,以及在我们的技术艺术家为第一轮添加的贴花数量下,片段限制帧的比例显着增加。继续下一轮!

PA 并不能直接告诉你每一个情况下的瓶颈。例如,对于强大的设备,我们经常看到未知的限制占主导地位。

在这种情况下,完整的捕获文件会有帮助;您可以从测试运行的工件中下载这些文件,并使用 Streamline 进行分析。幸运的是,性能计数器在文档中有详细描述,Arm 工程师随时准备提供咨询。 

应该注意的是,Arm Mobile Studio Professional Edition 轻松快捷地成为了我们 CI 工作流程的一部分。除了方便的 PA 报告和完整的分析器跟踪外,我们还收到了一个 json 文件,其中包含 PA 报告中图表上显示的所有指标的平均值和百分位数。在不久的将来,我们计划将这些数据发送到 BigQuery 并使用 DataStudio 进行可视化,就像我们已经为 CPU 分析器数据所做的那样。指标本身在此处 有描述。

虽然 Arm Mobile Studio 允许我们仅获取 Mali 系列 GPU 的额外数据,但它们是我们玩家群体中最广泛的 GPU。同样,我们可以从 Mali GPU 系列设备上运行的测试中得出许多观察结果,对于其他设备也同样有效(例如,如果 Mali 的带宽增加了,那么其他 GPU 的带宽也很可能增加了,甚至可能对其他平台也是如此)。

因此,向 Arm 致敬:你们的工具解决了我们在自动化测试报告中 GPU 性能数据缺失的问题。

结论

在 MS-1 (Wargaming),我们热衷于自动化常规工作。性能测试已经自动化了很长时间,但仍有改进的空间。 

我们最近在提高测试报告的详细程度方面付出的巨大努力为我们提供了一个自动化框架,该框架为测试和问题调查节省了时间。现在,我们可以识别出代码和内容中的许多问题,而无需手动设置分析的乏味阶段。在自动化测试环境中收集分析数据不仅使其更易于访问,而且这种方法还提高了数据的质量。

  1. 稳定的测试环境意味着更稳定的数据(对于移动设备尤其重要,因为房间温度 3-5°C 的差异会影响测试结果)。
  2. 访问历史数据为区分噪声与性能指标的显着变化提供了手段。而数据的质量极大地影响了分析速度。

我们认为,自动化性能测试是任何中型或大型游戏工作室的必备条件。这不仅仅是节省您员工的时间,还关乎测试质量和风险管理:通过夜间测试,您无需担心在最终的游戏测试期间出现性能问题并影响您的发布计划。

© . All rights reserved.