[Docs] (Disaggregated): five-arm transport perf comparison and bottleneck attribution

rd12/openra on-device matrix (monolith/inproc/spawn+shm/spawn+tcp),
tcp-localhost transport_wait decomposition (present credit=1 ~74% +
futex wakeup tax; SPIN_US=2000 alone 2.9x), cross-host control-plane
hang evidence chain blocking P12 acceptance B, Wi-Fi bandwidth ceiling,
and the prioritized knob/code optimization list.
This commit is contained in:
2026-09-28 20:55:45 -04:00
parent 141227e8ba
commit b9a89967b0
3 changed files with 99 additions and 1 deletions
+2
View File
@@ -27,6 +27,7 @@
那一帧 **221.5 s → 182.8 s(−17%)**;设备定频+关深度空闲则是 **166.5 s(−25%)**。服务端日志会打印 `spin 2000 us` 自证。
见 [`notes/p12/DEVICELOST-AND-UPLOAD-WAITS.md`](notes/p12/DEVICELOST-AND-UPLOAD-WAITS.md) §2.6–2.10。
- **画面正确**:Vulkan 后端真机画面检查 36/36 通过,CTS 五块相对基线没有超过 0.5 个百分点的退步、没有新崩溃(P7);server 自有窗口上屏两后端 SSIM 1.0(P12)。
- **五臂传输对比(2026-09-28,未定频交错 A/B)**:重负载(rd12)下 inproc ≈ spawn+shm 比 monolith **快约 1/3**(run-ahead 流水线并行 + applier 路径探针更少),轻负载(openra)下 split 只付固定开销;**tcp localhost 慢 ~8 倍,瓶颈是 present credit=1 的串行等待(~74%)+ futex 唤醒税**,`MOBILEGL_IPC_SPIN_US=2000` 单项实测 21.7→63.6 fps;**跨主机 TCP 在 `eglMakeCurrent` 处 100% hang**(字节级证据链,P12 验收 B 的阻塞项),且实测 Wi-Fi 吞吐 19–22 MiB/s 使重负载 Wi-Fi 臂上限 ~40–45 fps。全文 [`notes/perf-five-arm-20260928`](notes/perf-five-arm-20260928/README.md)。
## 按阶段
@@ -47,3 +48,4 @@
| 14 | P6.5 | 跨机 TCP 102/102;断线约 5 s 检测到 | [`notes/p65`](notes/p65/README.md) |
| 15 | P7 | 真机画面 36/36;server 内存无界增长收住(主机 825 → 546 MiB) | [`notes/p7`](notes/p7/README.md) |
| 16 | P12 | 审查后真机复测:Espryt SSIM 1.0;Magma 1.0 / 0.999999511;P12 定向 CTest 46/46;纹理上传回包等待 1→0(主机机制门,真机墙钟待测);FCL 与跨机 TCP 收官门仍待完成 | [`notes/p12`](notes/p12/README.md) |
| 17 | 五臂传输测量(2026-09-28,非阶段) | inproc/shm 重负载比 monolith 快 ~1/3;tcp localhost 瓶颈是 credit=1 + 唤醒税(SPIN_US=2000 → 2.9×);跨主机 TCP hang 证据链 | [`notes/perf-five-arm-20260928`](notes/perf-five-arm-20260928/README.md) |
+1 -1
View File
@@ -25,7 +25,7 @@
| **P12**(当前)server 自有屏幕窗口 | [`p12/`](p12/README.md) | `PLAN-P12.md`、`INTEGRATOR-DECISIONS-P12.md`、`device/` |
| P8 / P9 / P10 / P11 / P13(待排) | [`p8/`](p8/README.md)、[`p9/`](p9/README.md)、[`p10/`](p10/README.md)、[`p11/`](p11/README.md)、[`p13/`](p13/README.md) | 目前只有路线图上的完整范围与出口门 |
跨阶段:[`DEBTS.md`](DEBTS.md)(仍开放的债务与去向)、[`OPEN-QUESTIONS.md`](OPEN-QUESTIONS.md)(开放问题全文,编号稳定);[`handoff/`](handoff/)(P7 的集成者审查稿,路径被 P7 交接文档引用,保持原位);[`recovered/`](recovered/)(从失败的 workflow 运行里捞回的 P0–P2 期材料,`wf1` 设计定稿前的计划草案、`wf2` P0、`wf3` P0.5、`wf4` P1、`wf5` P2;与阶段目录逐字节重复的副本已于 2026-09-24 删除,只留独有的)。
跨阶段:[`DEBTS.md`](DEBTS.md)(仍开放的债务与去向)、[`OPEN-QUESTIONS.md`](OPEN-QUESTIONS.md)(开放问题全文,编号稳定);[`handoff/`](handoff/)(P7 的集成者审查稿,路径被 P7 交接文档引用,保持原位);[`recovered/`](recovered/)(从失败的 workflow 运行里捞回的 P0–P2 期材料,`wf1` 设计定稿前的计划草案、`wf2` P0、`wf3` P0.5、`wf4` P1、`wf5` P2;与阶段目录逐字节重复的副本已于 2026-09-24 删除,只留独有的);[`perf-five-arm-20260928/`](perf-five-arm-20260928/README.md)(非阶段的五臂传输性能对比与瓶颈归因,2026-09-28)。
## 旧引用怎么找
@@ -0,0 +1,96 @@
# 五臂传输性能对比(monolith / inproc / spawn+shm / spawn+tcp localhost / tcp over Wi-Fi)
> 2026-09-28,设备 Redmi `2f7cbe2e`(Adreno 830,Android 16,aarch64,**无 root 未定频**——
> 以 A-B-C-D 交错 3 轮替代定频,臂内散布 ≤2.7%)。
> 驱动与 profiling 工具已入库 [`tools/device_bench/disagg/`](../../../tools/device_bench/disagg/README.md);
> 原始数据在 `.trace-work/perf-compare/`(`summary.json` / `REPORT.md` / 逐轮目录 / `profile/` / `wifi/`)。
> 每臂均验证 logcat 臂标志(transport marker、`spawn ARMED`、`run-ahead ARMED`),全部 0 lockstep、0 Fatal;
> 每负载另跑一轮非 benchmark 的 ssim 门(openra 四臂 1.000000,rd12 四臂 0.999883,字节级一致)。
## 结果
### rd12(Minecraft 重负载,251 帧;~7,500 条 wire 记录/帧、816 KB/帧 stage 流量)
| 臂 | fps(best-of-3) | mean ms | median ms | 备注 |
|---|---|---|---|---|
| monolith | 131.3 | 7.61 | 7.34 | 基线 |
| inproc | 176.2 | 5.68 | 5.32 | **比 monolith 快 34%** |
| spawn+shm | 178.3 | 5.61 | 5.26 | **快 36%**;与 inproc 打平(历史门 8 同结论) |
| spawn+tcp localhost | 21.0–23.1 | 43.3–48.3 | 45–49 | **比 shm 慢 ~8 倍** |
| spawn+tcp localhost + `SPIN_US=2000` | 63.6 | 15.7 | — | 单 knob A/B,**2.9×** |
| tcp over Wi-Fi | — | — | — | 跨主机控制面 hang,0 有效帧(见下) |
### openra(轻负载,128 帧;28 draws/帧、199 记录/帧)
| 臂 | fps | mean ms | 备注 |
|---|---|---|---|
| monolith | 101.3 | 9.87 | mean 含首帧 setup 尖峰;median 0.76ms |
| inproc | 99.8 | 10.02 | 与 monolith 差 ~1.5%,噪声级 |
| spawn+shm | 88.8 | 11.27 | −12%,纯跨进程固定成本 |
| spawn+tcp localhost | 76.9 | 13.00 | −24% |
| spawn+tcp 同机 wlan0 IP(Wi-Fi 替代拓扑,不过空口) | 74.2–76.3 | 13.1–13.5 | ≈ tcp localhost,符合预期 |
## 结论
1. **inproc / shm 不慢,重负载下反而比 monolith 快 ~1/3。** 机制有二:
run-ahead 把 server apply(3.5ms/帧)挪到另一核与 client 编码(5.7ms/帧)并行,帧时取 max 而非求和
(实测 monolith 7.87 vs inproc 5.80 ms/帧);且 applier 逐记录路径的状态探针更少
(accessor/draw:monolith 6.08 vs split 4.05,每帧少 ~3,000 次探针)。
轻负载(openra)下没有可重叠的工作量,split 只付固定握手成本:inproc ≈ monolith,shm −12%,tcp −24%。
2. **真正差的是 tcp 臂,瓶颈是"credit=1 串行 ping-pong + futex 唤醒税",不是带宽、不是 syscall、不是 RTT。**
rd12 稳态 transport_wait ≈ 20.5ms/帧的分解:
| 分项 | 占比 | 证据 |
|---|---|---|
| present credit=1 等待(等上一帧 swap ack) | **~74%** | ftrace:GL 线程长 park 260 次 × 均值 27.5ms |
| sendmsg 内联发送(GL 线程持锁,11 次/帧) | ~18% | simpleperf `__sendmsg` 占 client 用户态 7.6% |
| reply RTT | 稳态 0% | wait_replies 全部集中在第 1 帧(create window) |
| progress 64 记录/1ms 合批节流 | ≤5% | SPIN 对照 A/B 反证 |
佐证:需求带宽 148MB/s vs 实测突发 recv 293MB/s、send 占空比 3.5%;
`MOBILEGL_IPC_SPIN_US=2000` 只消唤醒税就把 fps 21.7→63.6(GL park 合计 8.99→4.97s,futex 阻塞 4.37→1.74s)。
server 侧 io 线程每帧 41ms 阻塞在 recv 是"对端还没发"(credit 串行化)的症状,不是网络问题。
3. **shm/inproc 已贴近它们的实际上限:apply 线程 CPU。** 帧时 5.6ms 中 3.5ms 是真实 apply 工作;
剩下可削的是握手开销——apply 线程 6,963 次/帧 doorbell 等待、自旋占其 CPU ~35%(1.8ms/帧),
离跨核 cache-line ping-pong 上限(估 2–5M 记录/s,实际 1.24M waits/s)还有 2–4 倍余量;park 率仅 0.05%。
4. **Wi-Fi 臂被两个独立问题卡住。**
- **跨主机控制面 hang(源码 bug,P12 验收 B 的直接阻塞项)**:WSL client → 手机 server 在
`eglMakeCurrent`(控制面 seq 3)100% 复现挂死。字节级证据链:client 字节已被手机内核 ACK、
`/proc/net/tcp` 接收队列已空,但 session child 的控制 fd `ppoll` 永远无 POLLIN(strace 现场:
主线程 ppoll 100ms 超时循环、io 线程 recv 阻塞、apply 线程 futex parked)。
同机 TCP(连本机 wlan0 IP)完全正常 → 特异于跨主机到达时序,疑为控制面帧重组/双 reader 竞态
(本地 loopback 时窗口太小不出现)。已排除:丢包/PMTU/冷启动预算/LOG_FORWARD/run-ahead/token。
复现与取证脚本:`tools/device_bench/disagg/wifi_hang_repro.sh`、`phone_strace.sh`、`fdprobe.sh`。
- **带宽硬约束(即使修好 hang)**:实测 Wi-Fi TCP 吞吐 19–22 MiB/s(链路 5GHz 11ax、
Tx 648–1441Mbps、RTT avg 0.78ms),rd12 满速需 ~49MB/s → **Wi-Fi 臂上限 ~40–45 fps**;
轻负载则转为 RTT × 同步点主导。要满速必须减流量(压缩/去重)或提 credit 深度摊 RTT。
## 优化建议(按优先级)
knob 级(零代码):
1. `MOBILEGL_IPC_SPIN_US=2000`(tcp/spawn 臂)——本机已实测 **2.9×**(21.7→63.6 fps),与 P12 结论一致。
2. `MOBILEGL_IPC_PRESENT_CREDIT=2`——投影砍掉 twait 主项(74%)的一半以上;代价 +1 帧延迟(P5e 裁定允许)。**未实测,待 A/B。**
3. shm 臂 server 侧 `SPIN_US` 降到 20–35——park 率 0.05% 说明 50µs 自旋预算几乎全在白烧(35% server CPU)。**投影,待 A/B。**
4. `MOBILEGL_IPC_SERVER_AFFINITY`——ftrace 显示 tcp 臂 apply 线程落在 1.02GHz 小核(cpu6/7),apply 8.8 vs 4.0ms/帧。待 A/B。
代码级:
5. client 侧 doorbell 从 condvar 换 futex/eventfd 直唤醒(`StreamLink.cpp` 的 `StreamBell` 现包 `CondVarDoorbell`;
唤醒链 p50=128µs × 9,134 次/轮)。
6. applier 的 WaitForWork 改自适应 spin(连续空转才降预算),与 #3 同向但更精细。
7. sendmsg 跨 Flush 合批(收益上限 ~18% twait,排在后面)。
8. appliedSeq/progress 合批参数**不动**(A/B 反证 ≤5%)。
9. 修跨主机控制面 hang(方向:RunSession 控制泵 / ControlInbox 的读状态机与双 reader 交错;
证据见 `.trace-work/perf-compare/wifi/`)。
## 方法与读法陷阱(复测必读)
- 未定频设备的替代口径:A-B-C-D 交错 ≥3 轮,看 best-of-N 与散布,不看单轮。
- benchmark 模式不落 PNG、ssim 恒 −1;正确性门要单独跑一轮非 benchmark。
- spawn 臂 client 侧 PipeStats `frames=0` 是结构性零;费率用 server 侧 dump 的 frames 做分母(merge 逻辑见 `make_report.py`)。
- 无 root 设备的 profiling 组合:simpleperf(`perf_event_paranoid=-1` 时 shell 可用)+ ftrace sched
(shell 可写;本机 ring 丢弃 ~74% 事件,看分位数不看绝对计数)+ 自研 `/proc/<tid>/syscall` 采样器
(`tools/device_bench/disagg/sampler.c`,strace attach 被 SELinux 拒时的替代)。
- 已知缺口:rd12 monolith/inproc 的客户端符号级 simpleperf 报告缺失(采样收尾 bug);
loopback 裸吞吐未测成(以突发 293MB/s + 占空比论证代替);rd12 的 Wi-Fi 替代拓扑数据缺失(编排问题)。