3. 性能回归基线建立

性能回归的价值不在于“跑了一次仿真”,而在于“这次结果能和过去比、和未来比”。如果每次回归的测试集不同、工具版本不同、机器负载不同,那么即使拿到一组漂亮的仿真时间,也无法判断性能是真的提升了,还是环境波动带来的假象。基线(Baseline)就是解决这个问题的锚点:它把某一时刻的测试集、版本、环境配置和性能数据一起冻结下来,作为后续所有对比的参照系。

一、代表性测试集:不是越多越好,而是覆盖关键路径

选择回归测试集时,常见的误区是把全量回归直接当作性能回归集。全量回归可能包含数千个用例,跑一轮需要数小时甚至数天,但其中大量用例的仿真时间只有几秒,对性能变化的敏感度极低。真正需要进入性能基线的,是那些运行时间长、资源消耗高、覆盖关键场景的用例。

一个可操作的筛选方法是按“仿真时间占比”和“场景代表性”两个维度排序。例如某 SoC 验证项目共有 1200 个回归用例,总仿真时间约 18 小时。按单用例耗时排序后,前 40 个用例合计占用了约 11.5 小时,占比约 64%。这 40 个用例中,再按功能场景分类:CPU 子系统启动与中断、DDR 控制器压力、总线仲裁冲突、低功耗状态切换、外设 DMA 传输等。每个关键场景保留 2~3 个用例,最终形成约 25~30 个用例的性能回归集,单轮运行时间控制在 6~8 小时,既覆盖了主要性能敏感路径,又能在夜间完成一轮回归。

测试集确定后,需要为每个用例记录其基准仿真时间、峰值内存、编译耗时三个核心指标。编译耗时容易被忽略,但在增量编译和全量编译差异较大的项目中,编译时间往往占总回归时间的 20%~30%,必须单独记录。

二、基线版本:代码、工具、库三者同时冻结

基线版本不是简单地打一个 Git tag。性能回归的基线必须同时冻结三个层面:设计代码版本、仿真工具版本、依赖库版本。设计代码用 Git commit hash 标识;仿真工具如 Xcelium 需要记录完整版本号(例如 23.09.001)以及编译和仿真时使用的选项;依赖库包括 UVM 版本、VIP 版本、C 模型或 DPI 库版本。

如果只冻结设计代码而忽略工具版本,那么当 Xcelium 从 23.03 升级到 23.09 后,即使设计代码完全没变,仿真时间也可能因为编译器优化策略变化而波动 5%~15%。这种波动会被误判为设计性能退化。因此,基线记录中必须包含工具版本和关键编译选项,例如:

# 基线环境记录示例(示例参数,非实测)
Baseline ID: perf_base_2024Q3
Git Commit: a3f8c21d
Xcelium: 23.09.001
Compile Options: -mce -fast -access +rwc -timescale 1ns/1ps
Simulation Options: -sv_seed random -perf_stats
UVM: 1.2
VIP: axi_vip_2.1, ddr_vip_1.8
Host: compute-node-07 (Intel Xeon 6348, 256GB)
Load: 无其他重负载任务

三、环境配置固化:把“机器差异”变成可控变量

仿真性能对运行环境极其敏感。CPU 型号、主频、内存带宽、NUMA 配置、甚至同一台机器上其他进程的负载,都会影响仿真时间。如果基线在一台空闲的服务器上采集,而后续回归在负载较高的共享集群上运行,结果自然不可比。

固化环境配置的核心是锁定硬件与系统状态。具体做法包括:指定固定的计算节点或节点池;记录 CPU 型号、核心数、主频和内存容量;关闭或限制其他重负载任务;固定操作系统的 CPU 频率调节策略为 performance 模式;记录 Xcelium 的 license 队列等待时间,避免因 license 争用导致仿真启动延迟被计入仿真时间。

对于必须共享集群的场景,至少要做到“同节点对比”:基线和当前回归在同一节点上运行,或者使用容器化环境固定 CPU 和内存配额。如果无法保证同节点,则需要在性能数据中记录节点信息,并在对比时按节点分组,避免跨节点直接比较。

四、可对比性能数据的生成与判读

性能数据要可对比,必须满足三个条件:指标定义一致、采集方式一致、数据格式一致。建议每个用例采集以下指标:编译时间(秒)、仿真时间(秒)、峰值内存(MB)、CPU 利用率(%)。采集方式统一使用 Xcelium 的 -perf_stats 选项或外部 /usr/bin/time -v 包装,避免人工记录。

数据生成后,不要只看绝对值,而要看相对变化率。例如基线中用例 ddr_stress_01 仿真时间为 1820 秒,当前回归为 1950 秒,变化率为 +7.1%。此时需要结合阈值判断:如果项目设定的性能退化告警阈值为 5%,则 +7.1% 触发告警,需要进一步分析是设计变更导致还是环境波动。如果同一用例在连续三次回归中分别变化 +6.8%、+7.2%、+7.0%,则基本可以排除随机波动,定位为真实退化。

性能回归基线建立:四要素冻结与对比判读 ① 代表性测试集 筛选依据: • 仿真时间占比高 • 覆盖关键场景 • 资源消耗敏感 示例规模: 1200 → 25~30 个用例 单轮 6~8 小时 ② 基线版本冻结 三层冻结: • Git commit hash • Xcelium 完整版本号 • UVM / VIP / DPI 库 关键选项: -mce -fast -access +rwc -sv_seed random -perf_stats ③ 环境配置固化 锁定项: • 固定计算节点/节点池 • CPU performance 模式 • 限制其他重负载任务 记录项: CPU 型号 / 内存 / NUMA License 等待时间 ④ 可对比数据 采集指标: • 编译时间 (s) • 仿真时间 (s) • 峰值内存 (MB) 判读方式: 相对变化率 + 阈值 连续多轮趋势确认 性能数据对比判读示意(示例数据,非实测) 用例 基线仿真时间 (s) 当前仿真时间 (s) 变化率 判读 ddr_stress_01 1820 1950 +7.1% 超阈值,需分析 cpu_boot_03 960 972 +1.3% 正常波动 bus_arb_07 1450 1380 -4.8% 性能提升 low_pwr_02 720 735 +2.1% 观察趋势 告警阈值示例:仿真时间变化率 > ±5% 触发告警;连续 3 轮同向变化确认真实退化

上图的判读逻辑可以总结为:先看变化率是否超过阈值,再看连续多轮是否同向,最后结合设计变更记录定位原因。如果某个用例在基线版本之后没有任何 RTL 变更,但仿真时间持续上升,则应优先排查环境因素,例如节点负载、license 等待或文件系统缓存状态。

五、基线维护与更新策略

基线不是一成不变的。当设计进入新的里程碑、工具版本升级、或者测试集本身发生较大调整时,需要重新建立基线。重新建立基线的时机通常包括:Xcelium 大版本升级、关键 VIP 版本更新、测试集增删超过 20%、或者硬件平台迁移。

更新基线时,建议保留旧基线数据至少一个季度,以便在新基线建立初期进行交叉验证。新基线采集时,应在同一环境下连续运行 3 轮,取中位数作为基线值,避免单轮异常值污染基线。如果 3 轮之间的波动超过 3%,说明环境稳定性不足,应先解决环境问题再固化基线。

实践建议:把基线信息写入版本控制仓库中的 perf_baseline.yaml 文件,与设计代码一起管理。每次回归运行前自动读取该文件,校验当前工具版本和环境配置是否与基线一致。不一致时在报告中标记“环境偏差”,避免误判。

最终,性能回归基线建立的目标是让每一次回归结果都能回答三个问题:和谁比、在什么条件下比、变化是否显著。测试集决定了比什么,版本和环境决定了在什么条件下比,数据采集与判读规则决定了变化是否显著。三者缺一不可,共同构成可对比、可追溯、可复现的性能回归基础。