mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
- 2.9 established that a record's ~5 ms is mostly the DEVICE waking out of a deep idle state. That points at a knob that is already wired: how long the server's apply thread spins before parking. Raised from 50 us to 2000 us (via the Activity's existing `env` extra, which ServerEnvironment.apply parses as KEY=VALUE;KEY=VALUE and which does not scrub MOBILEGL_IPC_SPIN_US), the same 43,232-record frame goes 221.5 s -> 182.8 s (-17%), with rtt_mean 5,040 -> 4,145 us. Pinning the device and disabling its deep idle states is worth 166.5 s (-25%) but needs root; the spin needs neither root nor a rebuild. - The server log proves the knob landed (`mgl-srv-apply started ... spin 2000 us`) rather than leaving the reader to trust an env var, and the note carries the exact am start line. - So the load stall now has three ordered levers with numbers behind them: batch the waits (client-only, not built), keep the server hot (this commit, usable today, trades device CPU for wall clock on a frame that is 94% waiting), and pin the device for measurement discipline.
5.7 KiB
5.7 KiB
实测(索引)
这一页只有结论和去向;完整的表、命令、协议与读法在各阶段
notes/<阶段>/README.md的"实测"节。代码和旧笔记里的MEASUREMENTS.md §N按下表"§"列找到对应阶段(小节编号在那里原样保留)。
口径:性能只记录、不设门;看逐线程 CPU 时间,不看整机帧率。性能对比只用一台手机(Redmi 2f7cbe2e,Adreno 830),定频、同热窗口、两臂交替跑(guide/pin-verification-2026-09-07.md)。
关键结论
- 接口本身的代价:单进程里改成"前端推、后端收",CPU 多约 6–12%(P2),已接受;顶点数组切换密集的场景更高(P3a,+27–30%)。
- 拆成两线程:起初游戏里只有 7–13 fps;优化后 103–106 fps(P5d);client 发完就走以后,重负载(渲染距离 32)下与单线程持平(P5e)。
- 拆成两进程:真机上与两线程成本持平;两者的 GL 线程 CPU 都比单线程少约 30%(后端工作挪到了另一线程 / 进程)(P6)。
- 跨机:电脑经 TCP 连手机,102 个集成用例全过;server 被杀后 133 ms、Wi-Fi 断开后约 5 s 干净报"设备丢失"(P6.5)。
- 纹理上传的等待粒度(P12,handoff §4):wire 臂上纹理那半
resource_subdata不再逐条买回包,等待点从「每条记录」落到「SEG_STAGE 窗口用尽」。 单条纯上传占用的回包等待 1 → 0(wait_replies,正是 §3.2 里"一帧 55,428"的那个计数器)。 按形状实测(RemoteClientControls.ReplyWaitsByOpForAnAtlasShapedLoad,主机 inproc,按 op 计数):图集拼接(一张 level 上 64 次glTexSubImage2D)64 → 0 次回包等待; 每 sprite 一张纹理(64 张纹理 + 256 次glTexParameteri)384 → 320,剩下的全是 per-resource / per-call 的三条 row(create 76 / respecify 130 / params 130)—— 它们的拒绝是「服务端没有这个 handle」的唯一客户端可见信号,删掉等待就是删掉信号,裁定见CONTRACT-P5E.md§2.5。 真机(TrebleDroid GSI,MC 26.2 经 TCP 入世界)那一帧的构成为ResourceRespecify20,633 +SetTextureParams18,056 +ResourceCreate4,536 条各等一次, 而ResourceSubData12,671 条零等待(B 的实机证据);这些记录都是真实状态变化,客户端没有可去重的(同一值的glTexParameteri本来就不产生记录)。 - 单次往返那 ~5 ms 是设备侧的深度空闲退出,不是链路也不是客户端(P12,本轮实测):同一帧、同一批记录,
客户端自旋 40× 只快 ~10%;换
adb forward(USB)快 ~25–30%;而把设备 8 核钉performance并关掉cpuoff_l/clusteroff_l/mcusysoff/s2idle后, 单次等待 5,040 → 3,715 µs、那一帧墙钟 221.5 s → 166.5 s(−25%)——记录数与字节数都不变。 这解释了 handoff §3.6「换快 3.4 倍的链路墙钟不变」:钱花在设备每次唤醒上;handoff §3.2 那 249 s 是在未定频的机器上取的,含这份空闲税。 同一个诊断给出一条可移植修法:把服务端的自旋预算调大(Activity 的envextra →MOBILEGL_IPC_SPIN_US=2000,不需要 root、不需要改代码), 那一帧 221.5 s → 182.8 s(−17%);设备定频+关深度空闲则是 166.5 s(−25%)。服务端日志会打印spin 2000 us自证。 见notes/p12/DEVICELOST-AND-UPLOAD-WAITS.md§2.6–2.10。 - 画面正确:Vulkan 后端真机画面检查 36/36 通过,CTS 五块相对基线没有超过 0.5 个百分点的退步、没有新崩溃(P7);server 自有窗口上屏两后端 SSIM 1.0(P12)。
按阶段
| § | 阶段 | 一句结论 | 全文 |
|---|---|---|---|
| 1 | P0 | 能从应用进程拉起第二个进程;跨进程共享 GPU 内存只有一条路在所有设备上可用 | notes/p0 |
| 2 | P1 | 逐 draw 核对推送状态,79 条 trace 零分歧 | notes/p1 |
| 3 | P2 | 桌面基准:新 tracker 比它替掉的旧填充更便宜 | notes/p2 |
| 4 | P3a | 两机真机 Release:接口代价 +6–12%,VAO 切换密集的场景 +27–30% | notes/p3a |
| 5 | P4a | 换到 Redmi;P4a 自己只加 3–6 个百分点 | notes/p4a |
| 6 | P5 | 两线程第一帧画对;真机两线程臂还跑不完 | notes/p5 |
| 7 | P5b | 真机两线程跑通四条游戏 trace;两线程额外代价 +6–18% | notes/p5b |
| 8 | P5c | 两线程之间零共享内存后,全部测试仍绿 | notes/p5c |
| 9 | P5d | 游戏内 7–13 → 103–106 fps,client CPU 15.0 → 9.2 ms/帧 | notes/p5d |
| 10–11 | P5e | 发完就走比每条都等快 69%;重负载下与单线程持平 | notes/p5e |
| 12 | P6 | 两进程与两线程持平;每帧数据量与记录数首次实测 | notes/p6 |
| 13 | P3b/P4b | 纹理上传形状在四种拓扑下完全一致 | notes/p34b |
| 14 | P6.5 | 跨机 TCP 102/102;断线约 5 s 检测到 | notes/p65 |
| 15 | P7 | 真机画面 36/36;server 内存无界增长收住(主机 825 → 546 MiB) | notes/p7 |
| 16 | P12 | 审查后真机复测:Espryt SSIM 1.0;Magma 1.0 / 0.999999511;P12 定向 CTest 46/46;纹理上传回包等待 1→0(主机机制门,真机墙钟待测);FCL 与跨机 TCP 收官门仍待完成 | notes/p12 |