性能测试框架介绍¶
概述¶
EmbeddedGUI 的性能测试框架基于 QEMU ARM 仿真环境,提供确定性、可重复的性能基准测试。框架自动构建测试固件、在 QEMU 中运行、解析结果并与基线对比,检测性能回归。
为什么用 QEMU 而不是 PC 模拟器¶
PC 模拟器(SDL 后端)的系统计时器精度只有 1ms,对于微秒级的绘图操作来说粒度太粗。同一段代码在 PC 上多次运行的计时结果波动很大,无法作为可靠的性能基准。
QEMU 配合 -icount shift=0 参数可以实现指令级确定性计时:
每条 ARM 指令消耗固定的虚拟时钟周期
不受宿主机负载影响,结果完全可重复
通过
qemu_get_tick_us获取微秒级时间戳同一代码、同一 commit 多次运行结果一致
这意味着即使 0.1ms 的性能变化也能被可靠检测到。
测试环境¶
QEMU 配置¶
测试使用 qemu-system-arm 仿真 ARM Cortex-M 系列 MCU:
qemu-system-arm \
-machine mps2-an385 \
-cpu cortex-m3 \
-nographic \
-semihosting-config enable=on,target=native \
-icount shift=0 \
-kernel output/main.elf
关键参数说明:
-icount shift=0:确定性指令计数模式,1 条指令 = 1 个虚拟纳秒-semihosting:允许固件通过 semihosting 输出结果到宿主机终端-nographic:无图形界面,纯串口输出
CPU Profile 配置¶
框架支持多种 Cortex-M 内核配置,定义在 scripts/perf_analysis/perf_cpu_profiles.json 中:
Profile |
QEMU Machine |
典型芯片 |
|---|---|---|
cortex-m3 |
mps2-an385 |
STM32F1, STM32F2 |
cortex-m4 |
mps2-an386 |
STM32F4, STM32L4 |
cortex-m7 |
mps2-an500 |
STM32F7, STM32H7 |
每个 profile 使用对应的 QEMU machine 和 CPU 模型,确保指令集和流水线行为与真实硬件一致。
测试用例¶
测试应用为 HelloPerformance,每个测试用例在 240x320 屏幕上重复绘制 100 次,测量总耗时。
基础图元¶
测试项 |
说明 |
|---|---|
LINE |
直线绘制 |
RECTANGLE / RECTANGLE_FILL |
矩形描边/填充 |
CIRCLE / CIRCLE_FILL |
圆形描边/填充 |
ARC / ARC_FILL |
圆弧描边/填充 |
ROUND_RECTANGLE / ROUND_RECTANGLE_FILL |
圆角矩形描边/填充 |
ROUND_RECTANGLE_CORNERS / ROUND_RECTANGLE_CORNERS_FILL |
独立圆角矩形 |
TRIANGLE / TRIANGLE_FILL |
三角形描边/填充 |
ELLIPSE / ELLIPSE_FILL |
椭圆描边/填充 |
POLYGON / POLYGON_FILL |
多边形描边/填充 |
曲线¶
测试项 |
说明 |
|---|---|
BEZIER_QUAD |
二次贝塞尔曲线 |
BEZIER_CUBIC |
三次贝塞尔曲线 |
高质量抗锯齿 (HQ)¶
测试项 |
说明 |
|---|---|
CIRCLE_HQ / CIRCLE_FILL_HQ |
抗锯齿圆形 |
ARC_HQ / ARC_FILL_HQ |
抗锯齿圆弧 |
LINE_HQ |
抗锯齿直线 |
图片与文本¶
测试项 |
说明 |
|---|---|
IMAGE_565 |
RGB565 图片绘制 |
IMAGE_565_1/2/4/8 |
不同压缩比的 RGB565 图片 |
IMAGE_RESIZE_565 |
缩放图片绘制 |
TEXT / TEXT_RECT |
文本渲染 / 带裁剪区域的文本渲染 |
高级特效¶
测试项 |
说明 |
|---|---|
GRADIENT_RECT / GRADIENT_ROUND_RECT |
渐变矩形/圆角矩形 |
GRADIENT_CIRCLE / GRADIENT_TRIANGLE |
渐变圆形/三角形 |
SHADOW / SHADOW_ROUND |
阴影效果 |
运行方法¶
完整测试¶
# 运行所有 CPU profile 的完整性能测试
python scripts/perf_analysis/main.py --full-check
# 指定单个 profile
python scripts/perf_analysis/main.py --profile cortex-m3
# 自定义超时时间(秒)
python scripts/perf_analysis/main.py --profile cortex-m3 --timeout 600
PFB 矩阵测试¶
测试不同 PFB(局部帧缓冲)尺寸对性能的影响:
python scripts/perf_analysis/main.py --pfb-matrix
可用的 PFB 配置:
名称 |
尺寸 |
分块数 |
内存占用 |
|---|---|---|---|
default |
30x40 |
64 |
2.4 KB |
medium |
60x40 |
32 |
4.8 KB |
large |
120x80 |
8 |
19.2 KB |
fullwidth |
240x20 |
16 |
9.6 KB |
fullscreen |
240x320 |
1 |
153.6 KB |
SPI 传输矩阵测试¶
测试不同 SPI 速率和缓冲区配置对帧传输的影响:
python scripts/perf_analysis/main.py --spi-matrix
基线管理¶
结果对比¶
当前性能入口会输出最新 perf_results.json、pfb_matrix_results.json、spi_matrix_results.json 和对应 Markdown 报告。
如需把当前结果与某份历史基线 JSON 做对比,可使用:
python scripts/perf_analysis/main.py perf-compare perf_output/perf_baseline_999bb88.json perf_output/perf_results.json
perf-compare 会输出 Markdown 对比表,便于在评审或 CI 后处理阶段做人工复核。
回归检测¶
框架文档默认使用 10% 作为回归判定阈值。运行性能脚本时可把当前采用的阈值写入报告:
# 使用自定义阈值
python scripts/perf_analysis/main.py --threshold 15
回归检测公式:
change_pct = (current_ms - baseline_ms) / baseline_ms * 100
regression = change_pct > threshold_percent
输出文件¶
测试完成后,结果保存在 perf_output/ 目录:
文件 |
说明 |
|---|---|
|
当前 CPU profile 的性能结果 |
|
PFB 尺寸矩阵测试结果 |
|
SPI 配置矩阵测试结果 |
|
文本格式的简要报告 |
生成图表文档¶
使用统一入口把 JSON 数据转换为带图表的 Markdown 文档:
python scripts/perf_analysis/main.py perf-to-doc
生成的文档位于 doc/source/performance/ 目录,包含柱状图、热力图等可视化图表。
CI 集成¶
在 CI 流水线中,性能测试作为回归检查的一部分运行:
# CI 中的典型用法
python scripts/perf_analysis/main.py --full-check --threshold 10
当前脚本会在构建、QEMU 运行或文档生成失败时返回非零退出码;如需把性能回归阈值纳入 CI 判定,建议在后续步骤中结合 perf-compare 或自定义基线脚本处理。