From 45664725f8ade2621fa0d529cdababa99093019b Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Fri, 18 Sep 2026 15:59:53 -0400 Subject: [PATCH] [Docs] (Disaggregated): P5e - the render-distance 32 comparison, where inproc draws level with monolith Section 11's matrix ran at VD12, where BOTH monolith and run-ahead hit the 120 Hz panel ceiling - so that section answers "can it reach the ceiling", not "which is faster". At render distance 32 the load rises to ~3550 draws/frame (4.2x) and neither arm is near any cap (the game's own enableVsync:false / maxFps:260, and the measured max is only 37-71). That is the comparable round. - Five runs per arm, interleaved, CPU clocks pinned (checked before AND after, both PINNED), GPU held at pwrlevel 0, fan on; 75-150 s in-world settle before a 40 s window - VD32's chunk streaming runs far longer than VD12's and reusing the 20 s settle would have counted loading as steady state. - monolith p50 median 58.5 (range 56.3-67.9), inproc run-ahead p50 median 59.9 (range 56.8-61.1), client CPU 16.19 vs 15.72 ms/frame. Level, run-ahead marginally ahead, and with half monolith's spread. - Against the lockstep it replaces: p50 +69%, client CPU -40%, apply CPU -43%. The heavier the load the more it is worth, which is what the mechanism predicts: rendezvous count follows draw count, ~900 per frame at VD12 and ~3600 at VD32. - Both arms are client-thread saturated (~94%), so the client ms/frame column is each arm's real bottleneck and the two are directly comparable. New section 11.1 records an OPPORTUNITY rather than a defect: apply spends 11-12 ms against the client's 15.7 ms, so the two sides are unbalanced and moving work from client to apply lowers the bottleneck directly. Under lockstep that was meaningless (the two sides add serially); run-ahead is what turns it into a lever. Left to a later phase. options.txt restored from .p5e-backup to renderDistance:12; the device is unpinned, fan off, GPU back to governed. --- docs/Disaggregated/CURRENT_STAGE_PROGRESS.md | 4 ++- docs/Disaggregated/MEASUREMENTS.md | 32 ++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/docs/Disaggregated/CURRENT_STAGE_PROGRESS.md b/docs/Disaggregated/CURRENT_STAGE_PROGRESS.md index 093cef4d..92ce6736 100644 --- a/docs/Disaggregated/CURRENT_STAGE_PROGRESS.md +++ b/docs/Disaggregated/CURRENT_STAGE_PROGRESS.md @@ -154,7 +154,9 @@ flaky 是竞态**。根因(ra2 实测,推翻了我 ID-132 的机制猜测) (max 113.7-115.1)。也就是说在这台设备的真实负载里,**inproc 现在与 monolith 齐平**,而阶段开始时是 0.62-0.74 倍。 逐帧 client CPU 上 run-ahead 比 monolith 多约 8%(6.9 vs 6.3),两者都在上限之下留有余量。 -**尚未回答的**:面板上限之上谁更快。本机定不住更高的频率,而未定频的一次高频窗口里 monolith p50 201 / run-ahead +**面板上限之上谁更快,已由渲染距离 32 的一轮回答**(`MEASUREMENTS.md` §11.1,~3550 draws/帧,两臂都远离任何上限,每臂五次):monolith p50 中位 58.5、run-ahead **59.9**,client CPU 16.19 vs **15.72**——**齐平,且 run-ahead 略前、离散度只有 monolith 的一半**(±4% vs ±10%);相对 lockstep p50 **+69%**。下一个机会是两侧不平衡(apply 11-12 ms vs client 15.7 ms),run-ahead 之后才成立。 + +**尚未回答的**:VD12 下面板上限之上谁更快。本机定不住更高的频率,而未定频的一次高频窗口里 monolith p50 201 / run-ahead p50 181(约 1.10 倍)——那一次不可配对,只能作为方向性提示。要回答它需要关掉 vsync 或换一台上限更高的设备。 ## 3. P5c 落地内容 diff --git a/docs/Disaggregated/MEASUREMENTS.md b/docs/Disaggregated/MEASUREMENTS.md index fdfbeac9..4d29071d 100644 --- a/docs/Disaggregated/MEASUREMENTS.md +++ b/docs/Disaggregated/MEASUREMENTS.md @@ -561,3 +561,35 @@ symbolized `simpleperf cpu-cycles`,客户端 GL 线程:`SessionProducer::Wai **31.58% 自身时间**,其后第二名只有 3.72%。设备计数器同期显示客户端每帧进入 doorbell 等待约 **916 次** (对 ~849 次 draw),其中 99.8% 靠自旋解决——`MOBILEGL_IPC_SPIN_US=0` 让每次等待都 park,帧率塌到 20.9。 所以代价是**会合本身**,不是自旋参数,这也是为什么修法是"不再每次 draw 会合"而不是"把每次会合做便宜"。 + +### 11.1 渲染距离 32 的对照(同头 `25fba0d5`,~3550 draws/帧) + +§11 的矩阵在 VD12 下跑,而两条臂都撞到了 120 Hz 面板上限,所以那一节回答的是"能不能撞到上限", +不是"谁更快"。把渲染距离拉到 **32**(`options.txt` 的 `renderDistance`,备份为 `.p5e-backup`,测完已还原) +负载涨到 **~3550 draws/帧**(VD12 的 4.2 倍),**两条臂都远离任何上限**(游戏自身 `enableVsync:false`、 +`maxFps:260`,实测 max 只有 37-71),这才是可比的一轮。 + +条件:CPU 定频 little 1555200 / big 1958400(跑前跑后各 check 一次,均 PINNED),GPU 钉 pwrlevel 0, +风扇开,进世界后**静置 75-150 s**再取 40 s 窗口——VD32 的区块流式加载远比 VD12 长,沿用 20 s 静置会把 +加载期算进稳态。臂交错。 + +| 臂 | n | fps p50 中位数 | p50 范围 | client ms/帧 中位数 | apply ms/帧 | +|---|---|---|---|---|---| +| monolith | 5 | **58.5** | 56.3 – 67.9 | 16.19 | — | +| inproc **run-ahead** | 5 | **59.9** | 56.8 – 61.1 | **15.72** | 11.1 – 12.1 | +| inproc lockstep(`RUN_AHEAD=0`) | 2 | 35.5 | 34.5 – 36.5 | 26.17 | 19.7 – 20.5 | + +**结论:在 VD32 下 inproc 与 monolith 齐平**,中位数上 run-ahead 甚至略微领先(59.9 vs 58.5, +client CPU 15.72 vs 16.19),差值远在 monolith 自身的离散度之内——**monolith 五次的范围是 56.3-67.9 +(±10%),run-ahead 是 56.8-61.1(±4%)**,也就是说 split 臂不但追平,还更稳。`mono1` 的 67.9 是全场唯一 +的离群值(装包后第一次运行)。 + +**run-ahead 相对它取代的 lockstep:p50 +69%、client CPU −40%、apply CPU −43%。** +负载越重它越值钱,这是预期内的——会合次数随 draw 数走,VD12 是每帧约 900 次,VD32 约 3600 次。 + +两条臂**都是 client 线程打满**(run-ahead 15.72 ms CPU / 16.7 ms 帧 ≈ 94%;monolith 同理),所以这一列 +是各自真正的瓶颈,可以直接比。 + +**下一个机会,不是缺陷**:apply 线程只有 11.1-12.1 ms,client 有 15.7 ms——**两侧不平衡**。把工作从 client +挪到 apply 会直接降低瓶颈。这在 lockstep 下毫无意义(两侧串行相加),run-ahead 之后才成立,是本阶段 +解锁出来的新优化方向,留给后续阶段。