2、性能指标基准:FPS(帧率)的概念、TouchGFX中的FPS监控方法

做嵌入式UI优化,第一件事是什么?

不是改代码,不是换芯片。而是先搞清楚——你现在到底跑多快。

没有基准,你连问题在哪都不知道。我见过太多人上来就怀疑渲染引擎、怀疑内存分配,结果折腾半天,发现只是某个循环里多打了个日志。嗯,这种事我也干过。

2.1 帧率(FPS)到底是什么?

FPS,全称 Frames Per Second,每秒传输帧数。说白了就是——你的屏幕每秒钟能刷新多少张画面。

在 TouchGFX 里,FPS 直接决定了用户滑动页面时的流畅感。60 FPS 意味着每帧只有 16.67ms 的处理时间。你想想看,如果一帧花了 30ms,那 FPS 就掉到 33 了,用户立刻就能感觉到卡顿。

核心公式:
每帧可用时间 (ms) = 1000 / 目标 FPS
目标 60 FPS → 16.67ms/帧
目标 30 FPS → 33.33ms/帧

我个人习惯把 FPS 分成三个档位来判断问题严重性:

FPS 范围 用户体验 我的判断
55 - 60 丝滑流畅 不用动,或者微调
30 - 55 偶尔掉帧 有优化空间,需要排查
< 30 明显卡顿 必须立刻优化

这里有个坑要注意:FPS 不是越高越好。如果你的屏幕硬件只支持 60Hz,跑到 120 FPS 也没意义,反而浪费 CPU 去渲染多余的帧。我曾经在一个项目里看到 FPS 显示 90,但屏幕实际刷新率只有 60,那多出来的 30 帧全是白费功夫。

2.2 TouchGFX 里的 FPS 监控方法

TouchGFX 自带了 FPS 监控工具,不需要你额外写什么复杂的性能采集代码。我个人觉得这个设计挺贴心的——毕竟嵌入式调试环境本来就有限,能少折腾一点是一点。

方法一:启用内置 FPS 计数器

在 TouchGFX Designer 里,有个开关可以直接打开 FPS 显示:

  1. 打开你的 .touchgfx 项目
  2. 进入 Project Settings → Debug
  3. 勾选 Enable FPS Monitor
  4. 重新生成代码并编译烧录

运行后,屏幕左上角会显示一个实时 FPS 数值。这个数值是 TouchGFX 引擎内部统计的,不是靠外部工具估算的,所以很准。

小技巧: 如果你用的是 STM32CubeIDE 或者 IAR,可以在调试模式下运行,同时打开串口输出。TouchGFX 会把 FPS 数据也通过串口打印出来,方便你记录长时间的性能变化。

方法二:代码中手动获取 FPS

有时候你需要在特定场景下记录 FPS,比如页面切换瞬间、动画执行期间。这时候可以手动调用 API:

#include <touchgfx/hal/HAL.hpp>

// 获取当前 FPS
uint16_t currentFPS = HAL::getInstance()->getFramesPerSecond();

// 获取最近一秒的最小 FPS(这个很有用)
uint16_t minFPS = HAL::getInstance()->getMinimumFramesPerSecond();

// 获取最近一秒的最大 FPS
uint16_t maxFPS = HAL::getInstance()->getMaximumFramesPerSecond();

我建议你重点关注 getMinimumFramesPerSecond()。为什么?因为平均 FPS 可能很好看,但最低 FPS 才是卡顿的真凶。举个例子:平均 55 FPS 看起来很漂亮,但如果最低掉到 15 FPS,那用户一定会在某个瞬间感觉到明显的卡顿。

方法三:使用 TouchGFX 的 Performance Monitor

TouchGFX 4.18 之后引入了一个更强大的工具——Performance Monitor。它不仅能看 FPS,还能看到每一帧里各个模块的耗时分布:

  • Frame Buffer Swap:帧缓冲交换时间
  • Rendering:渲染耗时
  • Signal & Tick:信号处理和时钟更新时间
  • Idle:空闲时间(这个越大越好)

启用方式也很简单:

// 在 main.cpp 中,初始化 HAL 之后调用
HAL::getInstance()->enablePerformanceMonitor(true);

然后通过串口或者 LCD 上的 Debug 页面查看数据。我个人习惯把 Performance Monitor 的数据通过串口每秒打印一次,这样可以在 PC 上用串口工具记录整个运行过程,回头慢慢分析。

注意: Performance Monitor 本身会消耗少量 CPU 资源。在正式发布版本中,记得关闭它。我曾经有一次忘了关,结果发布版本比调试版本慢了 3 FPS,排查了半天才发现是 Performance Monitor 没关。

2.3 FPS 监控的完整流程

说了这么多,咱们把整个流程串起来。下面这张图是我在实际项目中总结的 FPS 监控步骤:

FPS 监控与问题定位流程 启用 FPS 监控 运行目标场景 FPS ≥ 55? 是 无需优化 否 记录最低 FPS 分析 Performance Monitor 重点关注:Rendering 耗时 > 10ms 或 Frame Buffer Swap 异常波动

这个流程我用了很多项目,基本能覆盖 90% 的卡顿问题。核心思路就是:先确认有没有问题,再定位问题在哪。不要一上来就改代码,先看数据说话。

2.4 避坑指南:FPS 监控中的常见误区

做 FPS 监控看起来简单,但实际操作中容易踩坑。我把自己踩过的坑列出来,你遇到了可以直接跳过:

  • 只看平均 FPS,不看最低 FPS——平均 58 不代表不卡,最低 12 才是元凶
  • 在 Debug 模式下测性能——Debug 模式比 Release 模式慢 20%-40%,测出来的数据没有参考价值
  • 忽略帧缓冲格式的影响——RGB565 和 ARGB8888 的渲染耗时差很多,切换页面时尤其明显
  • 忘记关闭 Performance Monitor——发布版本里开着它,等于自己给自己加了个性能包袱
我的习惯: 每次做性能优化之前,先跑一遍完整的 FPS 记录,保存下来作为基准。优化完再跑一遍,对比最低 FPS 有没有提升。没有数据对比的优化,都是瞎优化。