28、性能基准测试:benchmark工具、CPU/GPU/IO瓶颈分析

性能基准测试,说白了就是给系统“体检”。

我刚开始做嵌入式Android开发时,总觉得系统跑得慢,但说不清慢在哪。后来带我的老工程师扔给我一句话:“别猜,测一下。”从那以后,我养成了做基准测试的习惯。今天咱们就聊聊怎么测、用什么测、测完怎么看。

28.1 为什么需要基准测试?

嵌入式设备资源有限。CPU主频低、内存小、存储慢。你写的应用能不能流畅跑,不是靠感觉,是靠数据说话。

我个人习惯在项目启动阶段就建立一套基准测试流程。这样做有几个好处:

  • 量化性能基线:知道当前系统能跑多少分
  • 定位瓶颈:到底是CPU不够快,还是IO卡住了
  • 验证优化效果:改完代码后,分数有没有提升

核心观点:没有基准测试的优化,都是瞎优化。

28.2 常用benchmark工具

嵌入式Android上可用的工具不少。我挑几个常用的说说。

28.2.1 CPU基准测试

Geekbench:跨平台,测单核和多核性能。跑分直观,适合对比不同设备。

CoreMark:轻量级,专门测嵌入式CPU。我在项目中常用它,因为体积小,跑起来快。

Dhrystone:老牌工具,测整数运算能力。虽然有点过时,但很多芯片厂商还在用。

# 在Android设备上运行CoreMark
adb push coremark /data/local/tmp/
adb shell chmod +x /data/local/tmp/coremark
adb shell /data/local/tmp/coremark
# 输出示例:
# CoreMark 1.0 : 12345.67 / GCC 4.9 / Linux

28.2.2 GPU基准测试

GFXBench:测OpenGL ES和Vulkan性能。有离屏模式,可以排除屏幕分辨率影响。

3DMark:场景丰富,适合测游戏性能。不过体积大,我一般只在开发板上跑。

glmark2:开源,轻量。我推荐这个,因为它可以自定义场景,方便定位具体瓶颈。

小技巧:跑GPU测试时,记得关掉屏幕自动亮度。我遇到过因为亮度变化导致帧率波动的情况,折腾了半天才发现。

28.2.3 IO基准测试

AndroBench:测存储读写速度。顺序读写、随机读写都能测。

fio:Linux下的IO测试神器。Android上也能用,需要交叉编译。我习惯用它做压力测试。

dd命令:简单粗暴。虽然不精确,但快速判断IO有没有大问题。

# 用dd测试写速度
adb shell dd if=/dev/zero of=/data/testfile bs=1M count=100
# 输出示例:
# 100+0 records in
# 100+0 records out
# 104857600 bytes transferred in 2.345 secs (44712345 bytes/sec)

28.3 CPU/GPU/IO瓶颈分析

跑完测试拿到分数,然后呢?你得会看数据。

28.3.1 CPU瓶颈

CPU瓶颈的典型表现:

  • CPU占用率长期接近100%
  • 多核负载不均衡(一个核跑满,其他核闲着)
  • 任务切换频繁(上下文切换次数高)

我在项目中遇到过一个问题:视频解码卡顿。跑基准测试发现CPU占用率只有60%,但帧率就是上不去。后来用perf工具一看,发现大量时间花在锁竞争上。嗯,这其实是并发设计的问题,不是CPU不够快。

注意:CPU占用率低不代表没问题。可能是IO或GPU在拖后腿。

28.3.2 GPU瓶颈

GPU瓶颈的典型表现:

  • 帧率低于屏幕刷新率
  • GPU占用率持续高位
  • 渲染时间超过16.6ms(60fps场景)

怎么查?用dumpsys gfxinfo或者systrace。我个人习惯先看渲染管线,看看是顶点处理慢还是片段着色慢。

# 抓取GPU渲染信息
adb shell dumpsys gfxinfo <package_name>
# 重点关注:
# Draw, Prepare, Process, Execute 四个阶段的时间

28.3.3 IO瓶颈

IO瓶颈的典型表现:

  • 应用启动慢
  • 文件读写时系统卡顿
  • 随机读写速度远低于顺序读写

我曾经调试过一个车载系统,地图加载特别慢。跑AndroBench发现随机读速度只有不到10MB/s。后来换了更高等级的eMMC芯片,速度翻了三倍。你看,有时候问题不在软件,在硬件选型。

28.4 知识体系图

下面这张图总结了性能基准测试的核心逻辑。你可以把它当作排查问题的路线图。

性能基准测试知识体系 性能基准测试 CPU基准测试 GPU基准测试 IO基准测试 Geekbench CoreMark Dhrystone GFXBench 3DMark glmark2 AndroBench fio dd命令 CPU瓶颈 占用率100% 负载不均衡 上下文切换频繁 GPU瓶颈 帧率低于刷新率 渲染时间>16.6ms GPU占用率持续高位 IO瓶颈 应用启动慢 文件读写卡顿 随机读速度低

28.5 实战:一次完整的性能分析

光说不练假把式。咱们走一遍完整的流程。

场景:某嵌入式设备上,视频播放应用卡顿。

第一步:跑基准测试

先跑CPU和GPU基准测试,拿到基线数据。

# CPU测试
adb shell /data/local/tmp/coremark
# 结果:12345

# GPU测试
adb shell glmark2 --off-screen
# 结果:帧率 25fps

第二步:分析数据

CPU分数正常,但GPU帧率只有25fps。目标帧率是30fps。问题大概率在GPU。

第三步:深入排查

systrace抓渲染管线数据。发现片段着色器执行时间过长。

# 抓取systrace
python systrace.py -t 5 -o trace.html gfx view

第四步:定位根因

检查着色器代码,发现一个循环里做了大量浮点运算。优化后帧率提升到32fps。

经验总结:基准测试帮你快速定位问题域,但具体根因还得靠profiling工具深挖。

28.6 避坑指南

做基准测试时,有几个坑我踩过,分享给你:

  • 不要跑一次就下结论:至少跑三次取平均值。系统状态会影响结果。
  • 注意温度:设备过热会降频。我习惯在测试前让设备冷却到室温。
  • 关闭后台进程:测试前清理后台,否则数据不准。
  • 统一测试条件:屏幕亮度、网络状态、充电状态都要固定。

我曾经因为没关后台推送服务,跑出来的IO数据忽高忽低。折腾了两天才发现是日志进程在疯狂写文件。嗯,从那以后我每次测试前都会用ps看一眼进程列表。

28.7 小结

性能基准测试不是一次性工作。它应该贯穿整个开发周期。每次提交代码前跑一遍,你就能及时发现性能回退。

工具只是手段,分析才是核心。拿到数据后,结合CPU、GPU、IO三个维度去看,大部分性能问题都能定位。

好了,今天就聊到这。下次遇到卡顿问题,别急着改代码,先跑个基准测试看看。


公众号:蓝海资料掘金营,微信deep3321