Files
Deshab-OS/docs/RE/test-cases/performance-baseline.md
xyou a26866e339 feat: B7 APIC/IOAPIC接管 + NVMe写路径 + virtio_net virtqueue + PE兼容层修复 + QEMU测试套件全自动化
中断路由 (B7):
- apic.drv: LAPIC enable + IOAPIC重定向表编程(MADT ISO感知) + apic_route/apic_route_legacy/apic_diag开关
- UTSM: LAPIC EOI钩子(register_apic_eoi, ABI尾部追加) + IDT 0-255全覆盖 + spurious 0xFF特判
- FUCK: apic_route=0默认PIC(零回归) / =1 IOAPIC->LAPIC接管(失败完整降级) / legacy放开IRQ1/12/11

存储:
- nvme.drv: 写路径 + PRP list + 读回校验 + MSI/MSI-X中断驱动(nvme_msi开关, 回退纯轮询)
- build.ps1: apic.drv纳入构建(原为预置二进制)

网络:
- virtio_net: virtqueue RX/TX + netdev注册 + DHCP自测(slirp真实OFFER)

PE兼容层:
- pe_shim: guest->host指针转换(g_emu_mem_base + gp()) + shim fn32列补齐
- gen_pe.py: PE32+ RVA偏置修复(BUG-004) + cmd.exe生成
- desktop_app.h: da_mouse_poll先判AUX位 + da_mouse_init冲刷残留(BUG-003/008)
- shell: Ctrl修饰键跟踪(BUG-001) + g_run_image扩至1MB(BUG-002)

QEMU测试套件:
- 9用例全自动化(Run-All.ps1): boot-regression/driver-matrix/linux-compat/pe-compat/deaicup-e2e/userapps-matrix/network-e2e/performance-baseline/x86emu32-coverage
- QemuTest.ps1公共库: 串口断言/monitor sendkey/screendump/HTTP服务器/并发隔离

文档:
- CLAUDE.md: APIC/IOAPIC能力 + kernel_api暴露 + IRQ后端升级状态
- LESSONS_LEARNED.md: B7 LAPIC/IOAPIC经验教训(2条)
- Bug记录.txt: BUG-20260801-001~008 + BUG-20260803-009(9条)
- test-cases/*.md: 全部补充自动化脚本小节
- 桌面设计.md: .lnk快捷方式 + LINUXAPP.CNF Linux应用图标
- 系统开发策划.md: NVMe/virtio_net标完成 + B2/B7标已解决 + M2进度列
2026-08-04 18:08:08 +08:00

115 lines
4.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 性能基线测量
> 对应计划 Phase C5:基于 TSC 的关键性能指标测量
## 状态: ⬜ PENDING
## 测量方法
所有指标基于 TSC(Time Stamp Counter):
```c
static inline u64 rdtsc(void) {
u32 lo, hi;
__asm__ volatile("rdtsc" : "=a"(lo), "=d"(hi));
return ((u64)hi << 32) | lo;
}
```
TSC 频率需先校准(PIT 100ms busy-wait 测量):
```c
u64 tsc_freq; // Hz
u64 calibrate_tsc(void) {
u64 start = rdtsc();
pit_busy_wait(100); // 100ms
u64 end = rdtsc();
return (end - start) * 10; // ×10 得到 Hz
}
```
时间换算:`ms = (tsc_diff * 1000) / tsc_freq`
## 基线指标
| # | 指标 | 测量位置 | 基线目标 | 实测 | 状态 |
|---|---|---|---|---|---|
| P1 | UTSM 启动到 DSK SELFTEST | UTSM entry → DSK selftest pass | < 500ms (QEMU) | | ⬜ |
| P2 | DSK 加载 shell.elf 时间 | FAT32 read + PIE load 包围 | < 200ms | | ⬜ |
| P3 | DSK 加载 desktop.elf 时间 | 同上 | < 200ms | | ⬜ |
| P4 | shell `ping 10.0.2.2` RTT | echo request → reply | < 10ms (user-net) | | ⬜ |
| P5 | shell `linux ls` 完整 RTT | IPC exec round-trip | < 100ms (park-and-resume) | | ⬜ |
| P6 | shell `run PING.ELF` 加载时间 | FAT32 read + PIE load | < 150ms | | ⬜ |
| P7 | desktop 窗口拖动帧率 | 帧计数/TSC | 30+ FPS | | ⬜ |
| P8 | `pe HELLO64.EXE` 加载+执行 | pe_service_run 包围 | < 50ms | | ⬜ |
| P9 | `pe HELLO32.EXE` 加载+执行 | x86emu32 解释 | < 200ms | | ⬜ |
| P10 | UTSM VMM self-test | vmm_init → vmm_self_test | < 50ms | | ⬜ |
| P11 | Linux guest 启动到 park | vmlaunch → daemon HLT | < 3s (QEMU WHPX) | | ⬜ |
| P12 | e1000 DHCP 完整耗时 | netman DHCP start → final rc | < 5s | | ⬜ |
## 自动化测量
在 dev_mode run_dev_tests 中追加性能测量代码:
```c
/* 在 run_dev_tests 开头校准 TSC */
u64 tsc_freq = calibrate_tsc();
logl("[shell] TSC freq: <Hz>");
/* 各项测试包围 TSC */
u64 t0 = rdtsc();
/* ... 操作 ... */
u64 t1 = rdtsc();
u64 ms = (t1 - t0) * 1000 / tsc_freq;
logl("[shell] perf: <name> = <ms>ms");
```
输出到串口日志,由 [ISO/run_tests.bat](../../ISO/run_tests.bat) 收集汇总。
## 性能回归检测
```powershell
# 比较两次测试结果
$prev = Get-Content ISO/logs/perf-baseline-prev.json | ConvertFrom-Json
$curr = Get-Content ISO/logs/perf-baseline-curr.json | ConvertFrom-Json
foreach ($m in $curr.metrics) {
$p = $prev.metrics | Where-Object name -eq $m.name
if ($p -and $m.ms -gt $p.ms * 1.5) {
Write-Host "[REGRESSION] $($m.name): $($p.ms)ms -> $($m.ms)ms (>50%)"
}
}
```
## 自动化脚本
[tests/qemu/performance-baseline.ps1](../../../tests/qemu/performance-baseline.ps1) 以主机墙上时钟
轮询串口锚点,测量启动阶段耗时(正常启动 firstInit=`1\n0`,AUTOEXEC=ver/exit):
```powershell
.\tests\qemu\performance-baseline.ps1 # 默认 3 轮取中位数
.\tests\qemu\performance-baseline.ps1 -Runs 5 # 自定义轮数
```
测量锚点与阶段换算:
| 阶段 | 起 → 止 | 对应指标 |
|---|---|---|
| ovmf_bootloader_ms | QEMU 进程启动 → `[UTSM] boot` | OVMF + Limine |
| utsm_drivers_ms | `[UTSM] boot` → `[UTSM] SELFTEST PASS` | P1(UTSM+16 驱动装载) |
| selftest_to_dsk_ms | SELFTEST → `[DSK] boot` | DSK 加载(FAT32 read + PIE load) |
| dsk_to_desktop_ms | `[DSK] boot` → `desktop ready` | DSK → 桌面就绪 |
| total_boot_ms | QEMU 启动 → `desktop ready` | 端到端总启动 |
结果写入 `.build_tmp\perf_baseline.json`(锚点绝对时刻 + 各轮数据 + 中位数 + 环境信息)。
本脚本只测量展示、不做阈值断言;轮询精度 ±200ms,QEMU 数值仅作回归参考。
未自动化项(需内核 TSC 打点日志,当前串口无锚点,保持 PENDING):P2/P3/P6(单 ELF 加载计时)、
P4 ping RTT、P5 linux RTT、P7 桌面帧率、P8~P11(PE/VMM/Linux)、P12 DHCP 耗时。
## 已知限制
- QEMU 性能数据不等于真机,仅作回归参考
- WHPX vs TCG 性能差异巨大,必须固定加速方案
- 多次测量取中位数,避免单次抖动