性能测试框架介绍

概述

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.jsonpfb_matrix_results.jsonspi_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/ 目录:

文件

说明

perf_results.json

当前 CPU profile 的性能结果

pfb_matrix_results.json

PFB 尺寸矩阵测试结果

spi_matrix_results.json

SPI 配置矩阵测试结果

perf_report.md

文本格式的简要报告

生成图表文档

使用统一入口把 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 或自定义基线脚本处理。