StarryOS 性能剖析
cargo xtask starry perf 构建 StarryOS 并通过 qperf 进行性能剖析,输出火焰图(SVG/HTML/Folded)、Pprof 或 callchain 数据。这是 StarryOS 独有的命令,ArceOS 和 Axvisor 没有。qperf 是运行在宿主 QEMU 中的 TCG translation-block profiler,不是 guest 的 Linux perf_event_open(2) 或 PMUv3;AArch64 guest perf 的 ABI、计数器、采样 ring 和 upstream perf 验证由 Starry system tests 与 apps/starry/linux-perf 承担。
目前支持 riscv64、loongarch64 和 x86_64,要求 QEMU 11.1.1(Plugin API v7)。
x86_64 和 LoongArch 按用例的 UEFI 配置启动,并通过 Ostool 的固定版本和 SHA-256
校验流程复用公共 OVMF 缓存。需要隔离缓存时,
统一设置 TGOS_OVMF_DIR;该目录必须使用 Ostool 的 <arch>/code.fd、vars.fd 布局。
建议在 x86_64 上同时使用 --kernel-filter,排除 UEFI 固件和用户态地址。
cargo xtask starry perf 的 build_qperf_tools() 与 apps/qperf/prebuild.sh
统一使用本仓库 tools/qperf 中的插件和分析器源码,不再回退到外部插件源码。
报告后处理和 apps/OScope-harness 仍通过 apps/common/prebuild-harness-kit.sh
获取固定版本的 harness kit。需要使用预先准备的只读 checkout 时,设置
TGOSKIT_HARNESS_KIT_DIR;该目录必须满足 provider 的固定提交和文件完整性校验。
此变量不改变 qperf 插件和分析器的源码来源。
若目标是验证 AArch64 用户态程序能否直接执行 perf stat、perf record 或 perf report,不要使用本命令。QEMU TCG 只能作为 guest perf ABI 与控制流门禁,真实 cache、branch、stall 和 big.LITTLE 行为需要在 OrangePi 5 Plus 上运行 linux-perf/board app。
1. 剖析流程
剖析流程先构建 qperf 工具链和 StarryOS 内核,再运行 QEMU 采样并生成报告。
2. 参数
perf 参数覆盖采样配置、guest 工作负载、host 侧统计和符号化输出。
| 参数 | 说明 |
|---|---|
-c/--case <NAME> | 性能测试用例名(默认 boot) |
--arch <ARCH> | 目标架构:riscv64/loongarch64/x86_64(默认 riscv64) |
--freq <HZ> | 采样频率(默认 99) |
--format | 输出格式:Folded/Svg/Pprof/All(默认 All) |
--mode | 采样模式:Tb(translation block,默认)/ Insn(指令级) |
--max-depth <N> | 最大调用栈深度(默认 128) |
--timeout <SEC> | 采集超时(默认 20) |
--output-dir/--out <DIR> | 输出根目录,报告位于 <DIR>/perf/<arch>/latest |
--host-time/--no-host-time | 收集/禁用 QEMU 进程的 host CPU 时间 |
--host-perf | 在 host 侧用 perf stat 采集 QEMU 进程指标 |
--host-perf-events | host perf stat 事件(逗号分隔) |
--shell-init-cmd/--workload | Guest shell 出现 boot 提示后发送的命令 |
--shell-prefix | 发送 --shell-init-cmd 前匹配的提示子串 |
--start-marker/--stop-marker | Guest stdout 标记,控制采样窗口起止 |
--workload-timeout <SEC> | 采样窗口超时,超时则停止 QEMU |
--qperf-metrics | 启用 feature-gated 的 in-guest qperf 指标计数 |
--flamegraph | 即使 --format 非 SVG 也生成火焰图 |
--flamegraph-kind | 火焰图格式:Svg(默认)/Html/Folded |
--full-stack | 保留本构建可采集的最深栈 |
--perf-callchain(别名 --callchain) | qperf callchain 模式:Leaf/Fp/Logical |
--perf-debuginfo | 添加 DWARF 调试信息并保留符号 |
--perf-force-frame-pointers | 强制帧指针以支持 FP 解栈 |
--demangle | 在 qperf-analyzer 中强制 Rust demangle |
--no-truncate | 火焰图中保留极小帧(min width 设为 0) |
--include-kernel-symbols | 包含内核符号(StarryOS 默认开启) |
--include-user-symbols | 包含用户符号 |
--symbol-style | 折叠栈符号风格:Full(默认)/Short/Module |
--focus <REGEX> | 为匹配正则的帧生成额外的聚焦折叠栈/火焰图 |
--kernel-filter | 仅保留内核态帧 |
--smp <N> | CPU 核数 |
--debug | debug 构建 |
Guest 调度指标
--qperf-metrics 会启用 /sys/kernel/debug/scheduler_metrics。该文件输出从启动开始累计的无锁诊断计数;快照使用 relaxed 读取,不代表跨字段的事务一致性。测量一个工作负载时,应在窗口前后各读取一次并对相同字段作差。
context_switches 记 录已经进入架构 switch_context 的真实切换总数;以下字段按 outgoing task 的稳定 SwitchReason 对总数分类:
| 字段 | 含义 |
|---|---|
context_switches_preempted | 更高优先级或更符合当前调度策略的任务触发抢占 |
context_switches_yield | 当前任务主动让出 CPU |
context_switches_blocked | 当前任务提交 park 或其他阻塞操作 |
context_switches_exited | 当前任务退出且不再运行 |
context_switches_migrated | affinity 或负载均衡将当前任务移出本 CPU |
五个分类字段来自 ax-task 的唯一真实切换点;Starry debugfs 只展示同一份 snapshot,不单独维护计数状态。
3. 采样模式
采样模式决定 qperf 在翻译块(translation block)执行回调还是指令执行回调中采样。
| 模式 | 说明 |
|---|---|
Tb(translation block,默认) | 在 QEMU 翻译块执行回调中采样,开销较低 |
Insn(指令级) | 指令级采样,精度高但开销大 |
4. Callchain 解栈模式
Callchain 模式决定 analyzer 如何从采样点恢复调用栈。
| 模式 | 说明 |
|---|---|
Leaf | 最快,仅依赖采样点的 PC/LR |
Fp | 需要帧指针(配合 --perf-force-frame-pointers) |
Logical | 逻辑推导,最完整但最慢 |
5. 输出产物
报告位于 <output-dir>/perf/<arch>/latest/,包含:
- 火焰图(
.svg/.html) - 折叠栈(
.folded) - 原始采样(
qperf.bin) - 符号化统计(
resolve_stats、stack_depth_summary) - phase/focus 火焰图(按采样窗口分段)
report.md/report.json汇总报告与hotspots.csv
6. 用法示例
以下示例覆盖默认采样、带采样窗口的 x86_64 boot 剖析、指令级采样和自定义工作负载。
# 默认 riscv64 性能剖析(boot 用例)
cargo xtask starry perf
# x86_64 内核 boot 剖析:出现 shell 后写入结束标记并停止 QEMU
cargo xtask starry perf --arch x86_64 --kernel-filter --format folded \
--shell-init-cmd "echo QPERF_BOOT_DONE" \
--stop-marker "QPERF_BOOT_DONE" --timeout 60
# 指令级采样 + 帧指针解栈
cargo xtask starry perf --mode insn --perf-callchain fp --perf-force-frame-pointers
# 自定义工作负载采样窗口
cargo xtask starry perf --shell-init-cmd "/bin/run_benchmark.sh" \
--start-marker "BENCH_START" --stop-marker "BENCH_END" \
--workload-timeout 30