启动性能指标:把玄学变成可测量的数字

做性能优化,最怕什么?

怕你改了一堆代码,自我感觉良好,结果一测——没变化。更怕的是,你说“快了”,老板问“快了多少”,你答不上来。

所以这一章,咱们先把“快”这个模糊概念,拆成可测量、可复现、可对比的指标。说白了,就是给启动过程装上仪表盘。

启动时间定义:从哪一秒开始算?

这个问题听起来简单,其实坑很多。我见过好几个团队,因为统计口径不一样,吵得不可开交。

一般来说,UEFI 启动时间可以分成这么几段:

阶段 起点 终点 典型占比
SEC/PEI CPU Reset DXE IPL 5% - 15%
DXE DXE 入口 BDS 入口 20% - 40%
BDS BDS 入口 Boot Manager 选择 10% - 25%
OS Loader Boot Manager 启动 OS 内核接管 30% - 50%

我个人习惯,把“冷启动时间”定义为:从按下电源键,到操作系统桌面可用。但注意,这只是用户视角。做优化时,你得把每个阶段再拆细。

我曾经踩过的坑: 有一次优化 BIOS 启动,我盯着 DXE 阶段猛改,结果总时间没降多少。后来一测,发现 OS Loader 阶段才是大头。白忙活了两周。所以,先测量,再动手。

性能测量工具:你的眼睛和尺子

工具选对了,事半功倍。我主要用下面这几把尺子。

1. Bootchart:Linux 下的老伙计

Bootchart 是 Linux 系统下分析启动过程的经典工具。它会把启动过程画成一张时间轴图,每个进程什么时候启动、占了多少 CPU、IO 在等什么,一目了然。

用法很简单:

# 安装
sudo apt-get install bootchart

# 启动后生成图表
bootchart

# 或者用 bootchart2,功能更强
sudo apt-get install pybootchartgui

它会生成一个 PNG 图片。你一眼就能看出,哪个进程在“磨洋工”。

小技巧: 我一般会在 Bootchart 图上重点关注“CPU idle”和“IO wait”这两条线。如果 IO wait 很长,说明磁盘是瓶颈。如果 CPU idle 很多但进程没跑起来,那可能是调度问题。

2. PerformancePkg:UEFI 领域的瑞士军刀

这是 Intel 在 EDK II 里提供的一个工具包。它能在 UEFI 固件里埋下性能探针,精确测量每个 DXE 驱动、每个 Protocol 的加载时间。

使用方法:

# 在 .dsc 文件中添加
PerformancePkg/PerformancePkg.dsc

# 在 .fdf 文件中包含
INF PerformancePkg/PerformancePkg.inf

# 启动后,在 Shell 下执行
Shell> perf -v

输出结果类似这样:

Module                          Start     End       Duration
UsbBusDxe                       0x1234    0x12A0    0x6C
UsbKbDxe                        0x12A0    0x12E0    0x40
GopDriver                       0x12E0    0x1380    0xA0

你看,哪个驱动花了 0xA0 微秒,哪个只花了 0x40,清清楚楚。优化的时候,就盯着那个耗时最长的打。

核心思路: 不要凭感觉猜瓶颈。用 PerformancePkg 把每个模块的耗时拉出来,排个序。优化排名第一的,效果最明显。

3. 其他辅助工具

  • Serial Debug Log: 最原始但最可靠。在关键路径上打时间戳,用串口输出。我至今还在用。
  • Oscilloscope / Logic Analyzer: 硬件级测量。接一根线到 GPIO,在代码里拉高拉低,用示波器看波形。精度到纳秒级。
  • UEFI Shell 下的 dmem / dmpstore: 查看内存和变量,有时候能发现隐藏的延迟。

关键性能指标(KPI)分析:看什么数字?

工具给你一堆数据,你得知道哪些是关键。我一般只看这几个 KPI。

1. 总启动时间(Total Boot Time)

这是最终用户能感知到的。但注意,它是个结果指标,不是过程指标。你不能直接优化它,只能通过优化子项来间接影响它。

2. 各阶段耗时占比(Phase Breakdown)

这个很重要。我习惯画一个饼图,看看 SEC/PEI、DXE、BDS、OS Loader 各占多少。如果 DXE 占了 60%,那你就别去折腾 PEI 了,方向错了。

3. DXE 驱动加载时间(Driver Dispatch Time)

这是 PerformancePkg 最擅长的。我会列一个 Top 10 耗时驱动列表。优化策略很简单:

  • 能不能延迟加载?(Deferred Dispatch)
  • 能不能并行加载?(Concurrent Dispatch)
  • 能不能裁剪掉?(Remove Unnecessary Driver)

4. BDS 策略执行时间(BDS Policy Time)

BDS 阶段主要是做设备枚举和启动策略选择。如果这里慢,通常是因为:

  • USB 设备枚举太慢(等待 USB 设备稳定)
  • NVMe 设备初始化慢
  • Boot Manager 遍历启动项太多

5. OS Loader 加载时间

这个阶段其实已经出了 UEFI 的管辖范围,但你可以通过优化 Boot Manager 传递给 OS 的参数、或者优化固件提供的 ACPI/SMBIOS 表,来间接加速。

我的经验: 很多时候,OS Loader 慢是因为 UEFI 固件给 OS 传了太多没用的数据。比如,你插了 10 个 USB 设备,OS Loader 会花时间去枚举它们。如果这些设备在启动阶段用不到,可以在 ExitBootServices 之前把它们断开。

知识体系框架图

下面这张图,把启动性能指标的核心逻辑串起来了。你可以把它当作本章的思维导图。

启动性能指标知识体系 启动性能指标知识体系 启动时间定义 SEC/PEI DXE BDS OS Loader 性能测量工具 Bootchart PerformancePkg Serial Debug 示波器 关键性能指标 (KPI) 总启动时间 阶段耗时占比 驱动加载时间 BDS策略时间 先测量,再优化 不要凭感觉改代码

这张图把本章的三个核心模块串起来了:定义(启动时间分哪几段)、工具(用什么量)、指标(看什么数)。你优化的时候,就按这个框架来:先定义范围,再用工具测量,最后盯着 KPI 改代码。

一句话总结: 没有测量,就没有优化。没有 KPI,优化就是瞎忙活。