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 需要一次性设备设置:
- 开启开发者模式,进入开发者设置
- 启用 Performance Trace
- 选择 Lookback Collection,设置回溯时长
- 在控制中心添加 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)
- Domain(域):代表特定功能领域的有限状态机,比如关卡域追踪玩家进度
- State(状态):每个域同一时间只能处于一个状态
- Label(标签):状态的名称,如 “Level 1”
- Stable Metadata(稳定元数据):不可变的字典,包含状态的结构化信息
- 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)
- 仔细设计域和状态:每个域应该在概念上正交,不要在一个域中表示太多维度
- 限制状态转换频率:StateReporting 用于分析长时间性能,不是高频状态变化。转换频率应控制在用户动作频率或更慢
- 验证状态正确性:使用 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 单帧
核心启发
-
关卡加载性能分析器:使用 StateReporting 报告关卡状态和加载阶段,用 metalperftrace 分析每个关卡的帧率模式。找出哪些关卡有性能问题,是否与特定场景元素相关。
-
画质设置推荐系统:追踪画质设置(阴影质量、光线追踪等)与帧率的关系。通过
--aggregate按状态聚合指标,找出哪些设置组合导致帧率下降,然后为不同设备推荐最佳配置。 -
玩家行为热力图:用易变元数据追踪玩家位置、战斗状态等,分析哪些区域或活动导致性能下降。结合 MetricKit 的现场数据,找出所有玩家普遍遇到的性能问题区域。
-
自动性能回归测试:将 metalperftrace 的 JSON 输出集成到 CI/CD,自动检测新版本的帧率或内存是否异常。用 AI agent 分析 JSON 数据并标记潜在问题。
-
热节流预警:追踪设备和温控状态,关联帧率下降与热节流事件。了解游戏在不同热状态下的表现,优化发热时的性能表现。
关联 Session
- Enhance your game performance with Metal — Metal 渲染性能优化技巧
- Metal debugging and profiling update — Metal 开发工具最新进展
- Optimize your game with Instruments — Instruments 性能分析最佳实践
- Meet the new MetricKit — MetricKit 深度解析
- Diagnostics and crash analysis — 应用诊断和崩溃分析
评论
GitHub Issues · utterances