mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 18:13:23 +09:00
185 lines
12 KiB
Markdown
185 lines
12 KiB
Markdown
# P6.5 主机逐线程 CPU 前后记录
|
||
|
||
**已经取得前后数字,但不能称为“逐字不变”。** 本次记录覆盖本机 inproc 与 unix+shm spawn,
|
||
用于观察整波改动对保留车道的影响;性能按路线图通用纪律只记录,不据此阻塞正确性验收。
|
||
它不代表 TCP 吞吐,也不代表 Android Release 性能。
|
||
|
||
## 定义与条件
|
||
|
||
- WSL Arch、DirectGLES + llvmpipe;两臂均使用现有 Release 制品,同一个 retrace 可执行文件。
|
||
- before:`/home/swung/lk-split/libMobileGL.so`;after:READY6 的
|
||
`/home/swung/p65-split/libMobileGL.so`。各自启动同目录下的 server。
|
||
before 是既存的 P6.5 前制品,以实际 SHA-256 定身份;旧 CMake 缓存中的 build stamp
|
||
不足以声称它恰好对应当前远端源码头。
|
||
- OpenRA 完整 trace 128 帧,选择最后 **100 帧**;rd12 in-world 完整 trace 251 帧,选择最后 **200 帧**。
|
||
均排除起始资源准备窗口,不把全部 replay 时间除以帧数充作稳态结果。
|
||
- 每个 case × transport × before/after 均为 **3 次完整 replay**,共 24 个样本。
|
||
每组记录按 repeat 交替 inproc/spawn;全部 before 完成后等待构建结束,再采 after。
|
||
不是版本间随机交错试验,也没有 CPU 定频,因此不据此宣称统计显著性或唯一因果。
|
||
- 采集窗口内没有并发重型构建或另一条 host retrace。此前带
|
||
`before-pilot-not-comparable` 标签的试跑仅用于校验采集器,不进入表格。
|
||
- `PRESENT_CREDIT=1`、run-ahead=1、verb-barrier=1、batch-waits=1、spin=50us;
|
||
PipeStats=0、strict=0、role-split-state=0、audit=0。完整有效环境随每条样本保存。
|
||
- `--benchmark-finish=0`:runner 不额外在每帧插入 glFinish;trace 自己的同步行为仍保留。
|
||
|
||
**client CPU** 来自已有 runner 的 `CLOCK_THREAD_CPUTIME_ID` 与 `frameCpuTimesMs`,
|
||
取选中尾窗口的平均值。它包括该 replay 线程上的解码与 MobileGL 调用,不是整个进程 CPU,
|
||
也不是只计 MobileGL 函数的采样 profile。
|
||
|
||
**apply CPU** 来自 `/proc/<pid>/task/<tid>/schedstat` 的 execution runtime 纳秒计数。
|
||
选择最早的、仍存活的 `mgl-srv-apply` TID;后建的 driver helpers 会继承该名字,不能相加冒充
|
||
一个 apply 线程的 CPU。每条原始采样保留 pid、tid、线程名、采样时刻和累计 CPU。
|
||
如果没有唯一线程完整覆盖选中窗口,采集器报无效,不填 0。
|
||
|
||
### apply 窗口的精度限制
|
||
|
||
runner 现有帧数组没有绝对 monotonic 起点,因此外部 apply 采样使用 benchmark JSON 的文件 mtime
|
||
近似定位 `benchmark::End()`,再减去已有 `totalSeconds - sum(frameTimesMs)` 的非帧尾段,
|
||
最后回退选中尾窗口的 wall 时间。两个边界在线程 CPU 采样点间线性插值。
|
||
|
||
这存在**未单独测量的 summary/JSON 序列化延迟**,不能写成严格帧边界同步或纳秒精度的结果。
|
||
请求采样周期为 5 ms;before 实际最大间隔 **7.159784 ms**,after 为 **15.230268 ms**。
|
||
实际间隔与原始点均保留,后续可重新归约。下面多保留的小数位用于复算,不提高测量精度。
|
||
|
||
## 结果
|
||
|
||
每项是三次 replay 的“尾窗口 CPU 均值”的中位数,单位 **ms/帧**。
|
||
百分比为 `(after / before - 1) × 100`;完整未舍入值在 comparison JSON 中。
|
||
|
||
| trace | transport | 线程 | before | after | 差值 ms/帧 | 差值 % |
|
||
|---|---|---|---:|---:|---:|---:|
|
||
| OpenRA | inproc | client | 0.681840 | 0.705350 | +0.023510 | +3.448023% |
|
||
| OpenRA | inproc | apply | 3.040668 | 3.108000 | +0.067333 | +2.214402% |
|
||
| OpenRA | spawn | client | 0.806240 | 0.786330 | -0.019910 | -2.469488% |
|
||
| OpenRA | spawn | apply | 3.242036 | 3.198453 | -0.043583 | -1.344321% |
|
||
| rd12 | inproc | client | 8.287390 | 8.362680 | +0.075290 | +0.908489% |
|
||
| rd12 | inproc | apply | 64.884249 | 64.917254 | +0.033006 | +0.050868% |
|
||
| rd12 | spawn | client | 10.276510 | 10.285330 | +0.008820 | +0.085827% |
|
||
| rd12 | spawn | apply | 67.614988 | 67.059490 | -0.555499 | -0.821561% |
|
||
|
||
逐轮均值的范围也必须保留,避免只给一个点:
|
||
|
||
| trace / transport / 线程 | before 三轮范围 | after 三轮范围 |
|
||
|---|---:|---:|
|
||
| OpenRA / inproc / client | 0.678730–0.688320 | 0.690650–0.715600 |
|
||
| OpenRA / inproc / apply | 3.038111–3.112060 | 3.064185–3.172090 |
|
||
| OpenRA / spawn / client | 0.799590–0.810700 | 0.780370–0.792480 |
|
||
| OpenRA / spawn / apply | 3.239807–3.299042 | 3.187598–3.211357 |
|
||
| rd12 / inproc / client | 8.195700–8.325585 | 8.311060–8.510350 |
|
||
| rd12 / inproc / apply | 64.826829–64.939705 | 64.915537–65.039914 |
|
||
| rd12 / spawn / client | 10.274680–10.279320 | 10.250475–10.306380 |
|
||
| rd12 / spawn / apply | 67.489521–67.649413 | 67.010901–67.281044 |
|
||
|
||
存在双向变化:inproc client 的两个样本组上升,spawn client 一降一基本持平;
|
||
apply 也不完全相同。没有删除正增量,没有扩大阈值把它改写成“零开销”。
|
||
整波还补齐了独立 client 的死亡记录等正确性行为,故不能把全部差值唯一归因于 lk2 的调用形式。
|
||
|
||
## 制品与复现
|
||
|
||
共同 runner:
|
||
`/home/swung/tr-split/tools/trace_replay/mobilegl_trace_replay`
|
||
|
||
| 制品 | SHA-256 |
|
||
|---|---|
|
||
| runner(前后相同) | `700907be83c2c1c1c83eec8de37300a6fdab4c7f06387116fa8aaee0169b7291` |
|
||
| before libMobileGL.so | `a84d0c09b78b312c600e172c03bd9a6e4ce804585661859d888b20992b4e516d` |
|
||
| after libMobileGL.so | `d783080c5e1cb7db209a362db4ad742634d7525ae0c9683c4f6e9c5c54803361` |
|
||
| server launcher(前后相同) | `7a95cb4d276b40e4843c9d9f8c4d0f3486bfa6b5fc3e3b9a0dd842e1e9403ed6` |
|
||
|
||
server 是薄 launcher,`NEEDED libMobileGL.so`、`RUNPATH=$ORIGIN`;它自身字节相同并不表示加载了同一库,
|
||
两臂分别从各自目录解析生产库。
|
||
|
||
```bash
|
||
python3 <tree>/tools/trace_replay/measure_transport_cpu.py \
|
||
--runner /home/swung/tr-split/tools/trace_replay/mobilegl_trace_replay \
|
||
--library /home/swung/lk-split/libMobileGL.so \
|
||
--server /home/swung/lk-split/libMobileGLServer.so \
|
||
--fixtures /home/swung/w7/pipe/tools/trace_replay/fixtures \
|
||
--inputs /home/swung/p65-host-cpu-input \
|
||
--out /home/swung/p65-host-cpu-before --label before-p65 --repeats 3
|
||
```
|
||
|
||
after 只将 library/server 换成 `p65-split` 目录,out/label 换成对应 after 名。
|
||
脚本拒绝覆盖已存在的 benchmark 证据;重新测量应换新的 out。
|
||
新工作树中的某些 fixture 是 LFS 指针,故本次使用已核实的 Linux fixture 实体,并保存每条 trace SHA-256。
|
||
|
||
证据位置:
|
||
|
||
- `/home/swung/p65-host-cpu-before/summary.json`
|
||
- `/home/swung/p65-host-cpu-after/summary.json`
|
||
- `/home/swung/p65-host-cpu-comparison.json`
|
||
- 各目录的 `<transport>/<case>/run-N/{benchmark.json,cpu-summary.json,apply-samples.json,runner.log}`
|
||
|
||
这些数关闭了“必须真的量到逐线程 CPU”这一记录缺口,不关闭其他尚缺的 P6.5 设备/trace/吞吐指标,
|
||
也不把性能变化当正确性失败。
|
||
|
||
## 当前 spawn 与 loopback TCP 的专门比较:首轮负控
|
||
|
||
另外启动了仅用于本机测量的 `tcp://127.0.0.1:40616` supervisor,使用当前库、同一 runner、
|
||
credit=1,client/server 均开启 `MOBILEGL_PIPE_STATS=1`、`MOBILEGL_PIPE_STATS_PERIOD=1`。
|
||
`measure_loopback_cpu.py` 用 `P65LinkMetrics` 与 `P65ServerMetrics` 的线程 CPU 时钟,
|
||
逐个核对 client/server 帧号:OpenRA 29–128(100 帧),rd12 52–251(200 帧)。
|
||
这组 apply 数据直接来自帧时钟,不使用上节的 `/proc` 外部窗口近似。
|
||
|
||
**首轮不能作为纯传输成本对照。** 虽然两臂都请求 run-ahead=1,实际日志证明 spawn 已 ARMED,
|
||
而 TCP 在真实第一份 CapsSnapshot 到达之前,错误地用 placeholder 的零能力锁存为 lockstep,
|
||
随后“只允许 demotion”的规则使它一直无法武装。该差异由真实测量揭露,不能当成 TCP 固有成本放过。
|
||
|
||
完整首轮样本保留在 `/home/swung/p65-loopback-cpu/summary.json` 与
|
||
`summary-with-arm-proof.json`;OpenRA 每臂三轮,rd12 每臂一轮。
|
||
其中 rd12 的实际 client/apply CPU 为 spawn **10.377163 / 66.994613 ms/帧**,
|
||
错误 lockstep 的 TCP **105.151038 / 160.624839 ms/帧**。
|
||
这是具名负控证据,不进入正式 transport 比较结论。
|
||
|
||
修复由启动路径等待真实首 caps 完成,不强制打开 run-ahead,也不放宽后续只允许 demotion 的规则。
|
||
采集器已增加实际 ARMED、无 lockstep fallback、无 DISARMED 的检查;下节记录修复制品的正式重跑。
|
||
|
||
### 首 caps 修复后的正式两角色 CPU 数
|
||
|
||
修后 TCP 已完整重跑,所有样本均通过实际 run-ahead ARMED 检查,没有 fallback 或 DISARMED。
|
||
OpenRA 各臂 3 次取逐轮均值的中位数;rd12 各臂 1 次,单次样本不用于统计显著性推断。
|
||
两角色使用相同精确帧号窗口,不把 setup 算入稳态,也没有使用外部 `/proc` 插值。
|
||
|
||
| trace / 窗口 | 线程 | spawn unix+shm ms/帧 | TCP+stream ms/帧 | TCP − spawn ms/帧 | 差值 |
|
||
|---|---|---:|---:|---:|---:|
|
||
| OpenRA / 29–128 | client | 0.913889030 | 0.725938440 | -0.187950590 | -20.566019% |
|
||
| OpenRA / 29–128 | apply | 3.414349090 | 3.123573070 | -0.290776020 | -8.516294% |
|
||
| rd12 / 52–251 | client | 10.377163490 | 6.507507265 | -3.869656225 | -37.290115% |
|
||
| rd12 / 52–251 | apply | 66.994613060 | 53.903945275 | -13.090667785 | -19.539881% |
|
||
|
||
这是**指定两个线程**的实测变化,不能据负差值宣称 TCP 的进程总 CPU 更低:
|
||
TCP 另外有专用 I/O reader,以上 client/apply 时钟不包含那些线程的 CPU,也不包含其它 driver workers。
|
||
本表开了 PipeStats,前节 P6.5 前后表关闭 PipeStats;两表不能交叉相减。
|
||
|
||
spawn 控制复用本轮首 caps 修复前已真实 ARMED 的样本,其运行中的数据路径未改变;
|
||
TCP 使用修后制品。这个复用边界明确保留,不称两个 library 文件哈希相同:
|
||
|
||
- spawn library:`d783080c5e1cb7db209a362db4ad742634d7525ae0c9683c4f6e9c5c54803361`
|
||
- TCP library:`29fcff6b23557be6b1cc3765db382b3422ed0780643c719937616259298d3116`
|
||
- runner 与输入 trace 保持相同,完整哈希在各样本 `role-cpu.json` 中。
|
||
|
||
并发检查:最后一项 syntax 编译结束于 WSL 07:56:32.732;TCP OpenRA 三轮尾窗口分别从
|
||
07:56:56、07:56:58、07:57:00 开始,rd12 尾窗口从 07:57:55 开始,均无编译重叠。
|
||
这组精确帧时钟证据为 `/home/swung/p65-loopback-cpu-fixed/summary.json`,
|
||
归约比较为 `/home/swung/p65-loopback-cpu-comparison.json`;旧 lockstep 数据仍原样保存为负控。
|
||
|
||
最小复现(在没有其它 host 重负载时运行;不占手机端口):
|
||
|
||
```bash
|
||
p65_tree=/mnt/c/Users/geekerwan/.codex/worktrees/p65-all-tcp/MobileGL
|
||
LIBGL_ALWAYS_SOFTWARE=1 EGL_PLATFORM=surfaceless \
|
||
MESA_GL_VERSION_OVERRIDE=3.3 MESA_GLSL_VERSION_OVERRIDE=330 \
|
||
python3 "$p65_tree/scripts/ci/tcp_server_fixture.py" start \
|
||
--server /home/swung/p65-split/libMobileGLServer.so \
|
||
--endpoint tcp://127.0.0.1:40616 --state /tmp/p65-cpu-server.json
|
||
trap 'python3 "$p65_tree/scripts/ci/tcp_server_fixture.py" stop --state /tmp/p65-cpu-server.json' EXIT
|
||
python3 "$p65_tree/tools/trace_replay/measure_loopback_cpu.py" \
|
||
--runner /home/swung/tr-split/tools/trace_replay/mobilegl_trace_replay \
|
||
--library /home/swung/p65-split/libMobileGL.so \
|
||
--server /home/swung/p65-split/libMobileGLServer.so \
|
||
--inputs /home/swung/p65-host-cpu-input --out /tmp/p65-role-cpu
|
||
```
|
||
|
||
该命令用同一当前制品重测两臂;本次修复后仅 TCP 重测使用了 `--transport tcp`。
|
||
脚本按帧号核对两份日志、拒绝缺帧/重复帧/非正 CPU,并复用 `p65_link_metrics.py` 的归约逻辑。
|