平均 FPS
流畅稳定的帧速率对于在 Android 设备上提供高质量的游戏体验至关重要。在衡量游戏性能时,您应将平均 FPS 作为基准进行衡量,以便对体验有一个基本的了解。 您应优化游戏,使其达到 60 FPS 的平均帧速率,以确保提供出色的游戏体验。
P90 和 P99 FPS,用于衡量稳定性
即使游戏的平均帧速率达到流畅的 60 FPS,仍可能会出现间歇性卡顿、微卡顿和不可预测的输入延迟,从而导致玩家体验不佳。
因此,帧稳定性与跟踪平均帧速率同样重要。 在这种情况下,您应分别将 P90 和 P99 帧速率指标作为一致的基准和卡顿指标进行衡量。这些指标可捕获性能的“尾端”,以便您优化玩家体验的流畅度。
指标
- 平均 FPS(基准):此基本指标可提供游戏性能的一般 基准。虽然这是一个标准基准,但平均计算意味着无法检测到间歇性掉帧和微卡顿,因此仅靠此指标不足以代表玩家体验。
- P90 FPS(第 10 个百分位的稳定基准):这表示 90% 的帧超过了此稳定基准,只有最慢的 10% 的帧需要更长时间才能呈现。如果 P90 帧速率较高且接近平均值,则表示游戏在会话的大部分时间里运行良好。
- P99 FPS(第 1 个百分位的卡顿指标):这表示 99% 的 帧超过了此卡顿指标,专门隔离了 最慢的 1% 的帧。此指标对于捕获微卡顿、资源加载延迟以及导致明显卡顿的突发性资源密集型渲染峰值至关重要。
示例
通过将平均 FPS 与 P90 和 P99 指标进行比较,您可以准确诊断游戏的底层行为。
场景 1:最佳曲线(经过优化的游戏)
- 平均值:60 FPS(16.6 毫秒)
- P90:58 FPS(17.2 毫秒)
- P99:52 FPS(19.2 毫秒)
- 分析:这些指标紧密聚集在一起。游戏感觉非常流畅且稳定。没有微卡顿,即使是最差的 1% 的帧也几乎无法被人眼察觉。
场景 2:负载瓶颈(受 CPU/GPU 限制)
- 平均值:45 FPS(22.2 毫秒)
- P90:40 FPS(25.0 毫秒)
- P99:38 FPS(26.3 毫秒)
- 分析:平均帧速率较低,但始终如此。与平均值相比,P99 没有大幅下降。这表明系统基本上被图形设置或分辨率限制所淹没。 游戏不会感觉卡顿,而是感觉迟缓。降低图形设置通常会统一提升这些指标。
场景 3:不稳定的 60 FPS(着色器编译 / 资源流式传输 卡顿)
- 平均值:60 FPS(16.6 毫秒)
- P90:45 FPS(22.2 毫秒)
- P99:15 FPS(66.6 毫秒)
- 分析:这是最糟糕的情况。虽然平均帧速率看起来很出色,但 P99 揭示了一个严重问题。P99 为 66.6 毫秒意味着游戏一次会完全冻结多个帧。这表明存在严重的离群值,通常是由 CPU 瓶颈、资源流式传输延迟(例如 RAM 或存储空间速度缓慢)或着色器编译导致的卡顿引起的。
衡量
如需有效衡量平均 FPS、P90 和 P99 FPS,您可以使用以下两种方法。第一种方法是使用 Android
Performance Analyzer (APA)(一种性能分析工具)分析系统跟踪记录。第二种方法是使用现有的 adb dumpsys SurfaceFlinger --timestats 命令。
1. 使用 APA 进行衡量
使用 APA,您可以记录系统跟踪记录,并通过 SQL 查询精确分析帧数据。请按照以下步骤衡量您的指标:
使用 APA 捕获跟踪记录:运行游戏,并使用 APA 在您要分析的片段(例如,您怀疑会掉帧的游戏过程中的某个点)期间捕获 系统跟踪记录。设备连接完毕且跟踪记录完成后,跟踪记录数据将加载到 APA 界面中。
跟踪记录捕获屏幕或已加载的跟踪记录屏幕 点击 APA 中的“SQL”标签页:跟踪记录分析屏幕打开后,点击 界面顶部或侧边导航区域中的 SQL 标签页,打开 跟踪记录处理器环境,您可以在其中直接查询数据。
将 SQL 查询粘贴到 APA SQL 标签页中:复制以下 SQL 查询,并 将其粘贴到查询输入字段中。此查询会标识 SurfaceFlinger 进程,根据实际显示更新时间戳计算帧间隔,并得出平均 FPS、后 10% (P90) FPS 和后 1% (P99) FPS。
WITH target_process AS ( -- 1. Get SurfaceFlinger process ID where frames were identified in debugging step 3 SELECT upid FROM process WHERE name = '/system/bin/surfaceflinger' ), actual_present_times AS ( -- 2. Calculate the hardware display timestamps when SurfaceFlinger actually updated the screen SELECT (ts + dur) AS present_ts FROM actual_frame_timeline_slice WHERE upid IN (SELECT upid FROM target_process) AND dur > 0 ), present_intervals AS ( -- 3. Calculate intervals between physical screen refreshes SELECT (LEAD(present_ts) OVER (ORDER BY present_ts ASC) - present_ts) / 1000000.0 AS p2p_ms FROM actual_present_times ), valid_intervals AS ( -- 4. Filter for valid frame intervals SELECT p2p_ms FROM present_intervals WHERE p2p_ms IS NOT NULL AND p2p_ms > 0 ), ordered_frames AS ( -- 5. Sort in ascending order to calculate percentiles SELECT p2p_ms, ROW_NUMBER() OVER (ORDER BY p2p_ms ASC) AS row_num, COUNT(1) OVER () AS total_frames FROM valid_intervals ) -- 6. Output final metrics SELECT (SELECT COUNT(1) FROM valid_intervals) AS total_presented_frames, ROUND(1000.0 / NULLIF((SELECT AVG(p2p_ms) FROM valid_intervals), 0), 2) AS average_fps, ROUND(1000.0 / NULLIF((SELECT p2p_ms FROM ordered_frames WHERE row_num = CAST(total_frames * 0.90 AS INT)), 0), 2) AS low_10_fps, ROUND(1000.0 / NULLIF((SELECT p2p_ms FROM ordered_frames WHERE row_num = CAST(total_frames * 0.99 AS INT)), 0), 2) AS low_1_fps;点击“运行查询” :点击查询输入字段附近的运行查询 按钮(或执行图标)。查询执行完毕后,衡量出的总帧数 (
total_presented_frames)、平均帧速率 (average_fps)、后 10% FPS (low_10_fps) 和后 1% FPS (low_1_fps) 将显示在结果窗格的表格中。
显示执行的 SQL 查询的屏幕以及表格中显示的四个结果指标
2. 使用 adb (dumpsys SurfaceFlinger) 进行衡量
如需有效衡量平均 FPS、P90 和 P99,您可以使用 Android
dumpsys surfaceflinger timestats 命令。此工具可提供平均 FPS 和所有正在渲染的层的 presentToPresent 时间直方图。帧的 presentToPresent 时间是当前帧与上一帧绘制之间的时间间隔。
以下是收集和计算游戏的这些指标的分步说明:
开始捕获:使用 enable 和 clear 标志运行以下命令,以开始捕获信息:
adb shell dumpsys SurfaceFlinger --timestats -clear -enable转储信息:当游戏运行足够长时间后,使用 dump 标志再次运行 该命令以输出信息:
adb shell dumpsys SurfaceFlinger --timestats -dump按层过滤:转储的信息提供由 SurfaceFlinger 渲染的所有层的数据。您必须根据
layerName(例如 layerName = SurfaceView[com.example.yourgame...])进行过滤,找到与您的游戏对应的部分。layerName = SurfaceView[com.google.test/com.devrel.MainActivity]@0(BLAST)#132833确定平均 FPS:系统会自动计算每个层的平均 FPS,并直接显示在转储输出中(例如 averageFPS = 30.179)。
... averageFPS = 30.179 ...计算 P90 和 P99 FPS:如需查找 P90 和 P99 指标,您需要 分析转储中提供的 totalFrames 和
presentToPresent时间直方图。totalFrames = 1000 ... presentToPresent histogram is as below: 0ms=0 1ms=0 2ms=0 3ms=0 4ms=0 5ms=0 6ms=0 7ms=0 8ms=0 9ms=0 10ms=0 11ms=0 12ms=0 13ms=0 14ms=0 15ms=0 16ms=850 17ms=0 18ms=0 19ms=0 20ms=0 21ms=0 22ms=0 23ms=0 24ms=0 25ms=0 26ms=0 27ms=0 28ms=0 29ms=0 30ms=0 31ms=0 32ms=0 33ms=100 34ms=0 36ms=0 38ms=0 40ms=0 42ms=0 44ms=0 46ms=0 48ms=0 50ms=35 54ms=0 58ms=0 62ms=0 66ms=10 70ms=0 74ms=0 78ms=0 82ms=0 86ms=0 90ms=0 94ms=0 98ms=0 102ms=5 106ms=0 110ms=0 114ms=0 118ms=0 122ms=0 126ms=0 130ms=0 134ms=0 138ms=0 142ms=0 146ms=0 150ms=0 200ms=0 250ms=0 300ms=0 350ms=0 400ms=0 450ms=0 500ms=0 550ms=0 600ms=0 650ms=0 700ms=0 750ms=0 800ms=0 850ms=0 900ms=0 950ms=0 1000ms=0A. 概念示例(累积分布表) 假设您的游戏会话记录的总帧数 (totalFrames) 为 1,000。如需查找 P90 和 P99,您可以计算累积帧数分别达到 900 帧 (90%) 和 990 帧 (99%) 的毫秒阈值,从最低毫秒存储分区开始计数。
帧时间(毫秒) 帧数(直方图) 累积帧数 百分位状态 / 计算 16 毫秒 850 850 85.0% 33 毫秒 100 950 95.0%
(已达到 900 的 P90 目标!→ 1000/33 = 30.3 FPS)50 毫秒 35 985 98.5% 66 毫秒 10 995 99.5%
(已达到 990 的 P99 目标!→ 1000/66 = 15.1 FPS)102 毫秒 5 1000 100% B. 实现逻辑(伪代码) 如果您使用 Python 脚本或日志解析器自动执行此分析,则可以按如下方式实现从直方图中提取 P90 和 P99 值的逻辑:
# Define target thresholds based on total frame count p90_target = totalFrames * 0.90 p99_target = totalFrames * 0.99 cumulative_frames = 0 p90_fps = None p99_fps = None # Iterate through the parsed SurfaceFlinger histogram data (sorted by millisecond) for ms_bucket, frame_count in present_to_present_histogram: cumulative_frames += frame_count # Capture P90 when cumulative frames cross the 90% threshold if p90_fps is None and cumulative_frames >= p90_target: p90_fps = 1000 / ms_bucket # Capture P99 when cumulative frames cross the 99% threshold if p99_fps is None and cumulative_frames >= p99_target: p99_fps = 1000 / ms_bucket break # Optimization: stop iterating once both targets are found停止捕获:收集所有必要信息后,您应 使用 disable 标志停用 timestats:
adb shell dumpsys SurfaceFlinger --timestats -disable
慢会话
慢会话用于识别广泛存在的实际性能问题。如果超过 25% 的帧低于阈值(例如 20 FPS),则会话为“慢会话”。 虽然此指标有助于发现严重 build 问题,但仅靠此指标无法保证提供高质量、可持续的体验。游戏可能会避免达到慢会话阈值,但仍会受到微卡顿的影响,从而影响流畅的 60 FPS 体验。
虽然“慢会话”和“帧速率”都源自帧时间,但它们的作用不同。平均 FPS、P90 和 P99 FPS 指标用于衡量性能的质量和可持续性,检测慢会话指标可能会忽略的瞬时下降和不一致的步调。
总结
成功的性能优化需要全面的策略。 开发者应将慢会话作为主要雷达,以捕获严重的性能下降,然后检查平均 FPS、P90 和 P99,以诊断根本原因并验证游戏过程的实际流畅度。通过集成这些指标,您可以确保应用提供始终如一的可持续卓越用户体验。
其他资源
如需详细了解高级分析技术、实现帧同步 API 和特定于引擎的优化策略,请查看官方 Android 开发者文档:
- Android Vitals:慢会话:了解 Google Play 如何衡量和报告持续的呈现速度缓慢时段,这会直接影响用户体验。“慢会话”是指用户会话中速率较慢的帧(例如,耗时超过 50 毫秒,相当于 20 FPS)占比超过 25% 的会话。
- Android 开发者:优化游戏性能:探索 Android 游戏优化的中心 枢纽。这份全面的指南涵盖了最佳 实践、分析工具(如 APA 和 Perfetto),可帮助您 最大限度地提高游戏的整体性能。