WWDC Quick Look 💓 By SwiftGGTeam
Find and fix performance issues in your Metal games

Find and fix performance issues in your Metal games

观看原视频

Highlight

Metal 性能追踪工具新增 metalperftrace 命令行工具和 StateReporting API,支持长达数小时的游戏会话性能数据收集和分析,帮助开发者快速定位帧率下降的根本原因。

核心内容

游戏优化是个循环过程:在不同设备上测试、收集数据、分析结果、定位问题、修复,然后重复。这个过程听起来很常规,但实际操作中有个痛点。

玩家玩游戏用几代替几分钟,小时。在这几小时内,情况会不断变化:设备发热、温控降频、玩家调整画质设置、切换关卡、进入不同场景。如果你只在短时间测试,很可能漏掉这些长时间游戏才会暴露的性能问题。

Metal Performance HUD(性能仪表盘)能快速查看 FPS、内存、帧间隔等指标,但数据无法保存。玩几个小时后,你很难记住帧率具体在哪个时刻掉了。

Apple 的解决方案是让系统持续记录 Metal 性能数据,包括 CPU、GPU、FPS、内存等指标,数据可以保存数天。游戏结束后,你可以”回溯”收集这几小时的完整性能数据。

在 macOS 上,用 metalperftrace 命令行工具即可收集;在 iOS 上,需要在开发者设置中开启 Performance Trace,然后通过控制中心的按钮一键收集。

但拿到数据只是第一步。你看到 FPS 在某个时刻掉到 26,却不知道当时游戏在做什么——是在哪个关卡?画质设置是什么?网络状况如何?

这就是 Context(上下文)的重要性。Apple 推出了全新的 StateReporting API,让你可以描述游戏在任意时刻的状态,然后把状态信息和性能数据关联起来。

详细内容

Metal Performance HUD 基础

(00:29)

Metal Performance HUD 在游戏内容上方叠加显示性能指标,包括 FPS、内存使用、帧间隔等。它有配置面板可以自定义显示的指标,可以单独开关每个指标或选择预设。

HUD 的价值在于开发过程中快速查看性能趋势,但它不提供长期保存功能。

回溯收集性能数据

(04:40)

系统会持续记录 Metal 性能和资源使用数据,包括聚合指标和可选的逐帧指标(CPU、GPU、FPS、Memory)。这些数据高效存储,可以保存数天。

macOS 上的收集方式

(05:00)

macOS 27 提供了新的 metalperftrace 命令行工具:

# 收集过去 5 小时的数据
metalperftrace collect /tmp --last 5h

# 输出
# Metal performance traces collected to: /tmp
# /tmp/MetalPerfTrace_20260401_094100_to_144100.atrc

# 或指定明确的时间范围
metalperftrace collect /tmp \
  --start 2026-04-01T09:41:00 \
  --end 2026-04-01T12:41:00

关键点:

  • collect 是子命令,指定输出目录
  • --last 支持小时到天的时间范围
  • 也可以用 --start--end 精确指定时间
  • 输出是 .atrc 格式的 trace 文件

iOS 上的收集方式

(05:39)

iOS 需要一次性设备设置:

  1. 开启开发者模式,进入开发者设置
  2. 启用 Performance Trace
  3. 选择 Lookback Collection,设置回溯时长
  4. 在控制中心添加 Performance Trace 按钮

设置完成后,正常玩游戏。游戏结束后,从控制中心点击 Performance Trace 按钮,设备会自动收集并处理指定时长的数据。处理完成后会收到通知,trace 文件会出现在可用文件列表中,可以传输到 Mac 进行分析。

分析 trace 数据

(06:49)

使用 metalperftrace overview

(07:02)

metalperftrace overview /Data/MyGameTrace.atrc

# [Modern Renderer pid:13833]
# Mem: 2146.1 MiB (2343.9 Peak, 1199.4 Metal)
# Total CPU Time: 2417.601s (33.17% Sys, 66.83% User)
# Instructions: 9944836683668 (5.75% P, 94.25% E)
# Cycles: 5176430469224 (4.45% P, 95.55% E)
# Disk Reads / Writes: 317.37 / 0.04 MiB (Logical Write 0.04)
# Layer 0x729293000 (3456x2104) Interval 300.065s Active 300.065s
#   59.7 FPS  17735 Frames  188 Skipped
#   Frame Time avg: 16.74ms min: 8.33 max: 125.00 stddev: 3.70
#   CPU Begin-to-Present avg: 3.99ms min: 1.40 max: 94.37 stddev: 1.80
#   On-GPU Time avg: 13.39ms min: 5.24 max: 37.57 stddev: 1.43
#   Next Drawable Wait avg: 0.26ms min: 0.00 max: 91.08 stddev: 1.75
#   Shader Compilation Time: 0.000s (Total: 0, Cached: 18)

关键点:

  • 报告分为两部分:资源使用统计(内存、CPU、磁盘)和 Metal 性能指标
  • 每个 layer 显示 FPS、帧数、跳过帧数
  • 帧时间显示平均值、最小值、最大值、标准差
  • GPU 时间、CPU 呈现时间等关键指标

如果 trace 包含多个进程,可以用 predicate 过滤特定进程,或用 --json 输出结构化数据供脚本处理。

JSON 输出

(07:58)

metalperftrace overview /Data/MyGameTrace.atrc --json --predicate 'process == "MyGame"'

关键点:

  • --json 生成机器可读的结构化输出
  • 可用于回归测试或 AI 自动分析性能问题
  • --predicate 可以过滤特定进程

使用 Instruments 可视化

(08:29)

Instruments 可以打开 trace 文件进行可视化分析。数据按时间绘制,系统自动评估并高亮异常值(偏离正常范围的指标用不同颜色标记)。

你可以在时间轴上选择区间,Instruments 会自动聚合该区间的统计数据。

StateReporting API

(09:56)

定位性能问题需要知道游戏在那一刻的状态。StateReporting API 让你可以描述游戏的行为和状态变化。

核心概念

(10:15)

  1. Domain(域):代表特定功能领域的有限状态机,比如关卡域追踪玩家进度
  2. State(状态):每个域同一时间只能处于一个状态
  3. Label(标签):状态的名称,如 “Level 1”
  4. Stable Metadata(稳定元数据):不可变的字典,包含状态的结构化信息
  5. Volatile Metadata(易变元数据):状态内可变的值,如玩家生命值

代码示例

(12:10)

#import <StateReporting/StateReporting.h>

// 创建域并获取 reporter
NSString *domain = @"com.mygame.level";
SRStateReporter *reporter = [SRStateReporter reporterForDomain:domain];

// 报告状态转换
[reporter reportTransitionToStateLabel:@"Level 1"
                        stableMetadata:nil
                      volatileMetadata:nil];

// 带稳定元数据的转换
[reporter reportTransitionToStateLabel:@"Level 1"
                        stableMetadata:@{ @"id": @1001 }
                      volatileMetadata:nil];

// 更新易变元数据(不转换状态)
[reporter reportVolatileMetadataUpdate:@{ @"health": @100 }];

关键点:

  • 域名通常用反向 DNS 字符串
  • reporterForDomain: 获取域的状态报告器
  • reportTransitionToStateLabel 报告状态转换
  • stableMetadata 包含状态的不变信息
  • reportVolatileMetadataUpdate 在不转换状态的情况下更新易变数据

StateReporting 与工具集成

Metal Performance HUD 集成

(13:00)

在 Metal Performance HUD 的指标配置选项卡中,状态域会出现在列表中。启用后,覆盖层会显示标签、稳定和易变元数据。

metalperftrace 集成

(13:42)

当 trace 包含状态转换时,metalperftrace overview 会显示域列表、转换次数和最后已知状态。

# 显示完整状态转换
metalperftrace overview /Data/MyGameTrace.atrc --include-state-transitions

# [States]
# com.mygame.graphics
#   High (30.59%, 14.996s)  raytracing: 1  shadow: ultra
#   Medium (69.38%, 34.012s)  raytracing: 0  shadow: medium
# com.mygame.level
#   Level 1 (20.47%, 10.033s)  biome: forest   id: 1001
#   Level 2 (79.53%, 38.991s)  biome: volcano  id: 1002

关键点:

  • --include-state-transitions 打印完整状态列表和时间戳
  • 显示每个状态的持续时间和占比
  • 包含稳定元数据

按状态聚合指标

(14:15)

# 聚合所有域
metalperftrace overview /Data/MyGameTrace.atrc --aggregate

# 聚合特定域
metalperftrace overview /Data/MyGameTrace.atrc --aggregate \
  --domain com.mygame.graphics

# 聚合特定状态标签
metalperftrace overview /Data/MyGameTrace.atrc --aggregate \
  --domain com.mygame.graphics \
  --state-label "High"

关键点:

  • --aggregate 自动按状态聚合指标
  • 可以指定域或具体状态标签
  • 报告显示状态的活跃时长和重叠状态

Instruments 集成

(15:02)

Instruments 会为每个域创建一个轨道,作为 Points of Interest instrument 的一部分。每个轨道绘制状态转换和易变更新,便于理解上下文。

选择单个状态可以在侧边栏查看详细信息(稳定和易变元数据)。

最佳实践

(16:17)

  1. 仔细设计域和状态:每个域应该在概念上正交,不要在一个域中表示太多维度
  2. 限制状态转换频率:StateReporting 用于分析长时间性能,不是高频状态变化。转换频率应控制在用户动作频率或更慢
  3. 验证状态正确性:使用 Metal Performance HUD 和 Instruments 确认转换符合预期,检查边界情况

发布后监控:MetricKit

(17:54)

MetricKit 提供两种数据:指标和诊断。它在后台持续收集数据,每天向游戏进程交付报告。

macOS 和 iOS 27 中,MetricKit 新增 Metal 帧率信息,以及根据 StateReporting 状态聚合的帧率数据。

报告中包含整体平均帧率以及时间和帧数,还会按 level domain 中的状态分组显示帧率信息。

深入分析工具

(15:44)

有足够上下文后,可以用以下工具深入分析:

  • Metal System Trace 模板(Instruments):捕获详细 CPU 和 GPU 调度数据
  • Metal Debugger(Xcode):捕获和 profile 单帧

核心启发

  1. 关卡加载性能分析器:使用 StateReporting 报告关卡状态和加载阶段,用 metalperftrace 分析每个关卡的帧率模式。找出哪些关卡有性能问题,是否与特定场景元素相关。

  2. 画质设置推荐系统:追踪画质设置(阴影质量、光线追踪等)与帧率的关系。通过 --aggregate 按状态聚合指标,找出哪些设置组合导致帧率下降,然后为不同设备推荐最佳配置。

  3. 玩家行为热力图:用易变元数据追踪玩家位置、战斗状态等,分析哪些区域或活动导致性能下降。结合 MetricKit 的现场数据,找出所有玩家普遍遇到的性能问题区域。

  4. 自动性能回归测试:将 metalperftrace 的 JSON 输出集成到 CI/CD,自动检测新版本的帧率或内存是否异常。用 AI agent 分析 JSON 数据并标记潜在问题。

  5. 热节流预警:追踪设备和温控状态,关联帧率下降与热节流事件。了解游戏在不同热状态下的表现,优化发热时的性能表现。

关联 Session

评论

GitHub Issues · utterances