Files
MobileGL/docs/Disaggregated/MEASUREMENTS.md
T

429 lines
45 KiB
Markdown
Raw 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.
# 实测记录
> 每张表写明设备、提交与命令。设备:`35d0befa` = Xiaomi 24129PN74CSM8750 / Adreno 830v2)与 `3B159D009VZ00000` = Oppo PLG110MT6993 / Mali)用于 P0P3a`2f7cbe2e` = Redmi M332BFSM8750 / Adreno 830v2,与小米同 SoC 同定频点)是 P4a 起唯一的 A/B 设备。定频、风扇与热协议见 `devices/pin-verification-2026-09-07.md`。
>
> 口径(用户 2026-09-08 起):性能对着 pull 臂**记录**、不作阻塞门;正确性门是硬门。两条读数纪律:`acc/draw` 是约 10 个热入口的**静态**计数,把读点搬走与把工作去掉在它上面长得一样,判性能只看 CPU 时间序列与六个 memo 门;`ctest -V` 做拒绝普查是假零(console sink 在发布配置里被编译掉),必须逐用例读私有日志。
## 1. P02026-09-05trace APK `7ef7c7e5`spike `8a239177`
### 1.1 Spike A — 从应用自身进程 exec 第二个原生可执行文件
| 设备 | 结果 |
|---|---|
| Adreno 830 | **OK**`untrusted_app` 父进程 `fork`+`execve` `<nativeLibraryDir>/libMobileGLServer.so`,子进程同域同 category、exit 0、`execErrno=0`、零 avc denial |
| Mali | **OK**,同形 |
主机侧已证:AGP 会把改名成 `lib*.so``add_executable` 打进 `lib/arm64-v8a/``RUNTIME_OUTPUT_DIRECTORY` 重定向到 `CMAKE_LIBRARY_OUTPUT_DIRECTORY`);`posix_spawn` 在 minSdk 26 不可用;应用进程 stdout/stderr 是 `/dev/null`,子进程用 marker 文件证明自己活过。代码:`tools/spikes/server_stub/``android-plugin/app/src/trace/cpp/spawn_spike.cpp``MOBILEGL_BUILD_SERVER_SPIKE`
### 1.2 Spike B — 跨进程外部内存分档(`tools/spikes/extmem_probe/``shell` 域,4 MiB payload,每行一次真 GPU 访问 + 两侧字节校验)
| 路线 | Adreno 830 | Mali |
|---|---|---|
| T1-opaque-fdserver 导出 `VkDeviceMemory` fdclient `mmap` + 导入) | **OK** 完整往返 | UNSUPPORTED`VK_ERROR_INVALID_EXTERNAL_HANDLE` |
| T1-dma-buf | UNSUPPORTED | UNSUPPORTED |
| T1-gles-memobj-fd`GL_EXT_memory_object_fd` | **FAIL**:导入接受,但每次 `glMapBufferRange``GL_INVALID_OPERATION` | UNSUPPORTED |
| **T0-ahb-blob-transfer**client 分配 `AHardwareBuffer` BLOB → socket 交接 → server Vulkan + GL 导入) | **OK** 全链 | **OK** 全链 |
| T3-external-memory-host | UNSUPPORTED | PARTIALGPU 写对宿主映射不可见(只读档) |
决定:唯一在两台设备、两个后端上都是完整读写的档是 **T0**Adreno 另有 T1Vulkan 路径);Mali 无任何 server 导出路线。Caveat:运行域是 `shell` 不是 `untrusted_app``ROADMAP.md` 开放问题 3)。
```sh
ANDROID_NDK=$HOME/android-sdk/ndk/27.3.13750724 tools/spikes/extmem_probe/build_android.sh /tmp/extmem-build
adb -s $S push /tmp/extmem-build/extmem_probe /data/local/tmp/ && adb -s $S shell "chmod 755 /data/local/tmp/extmem_probe && /data/local/tmp/extmem_probe"
```
### 1.3 边界计数器基线(`MOBILEGL_PIPE_STATS=1`,最后一个完整 120 帧窗口;accessor / memo 数字是软件确定的,两台设备相同)
| trace(窗口内帧数) | 后端 | draws/f | acc/draw | buf B/f | tex B/f(发射 box / rect | ubo-global B/f | ubo-named B/f | memo 门(hit/miss |
|---|---|---|---|---|---|---|---|---|
| `minecraft-1.21.4-in-world`360 | Espryt | 91.6 | **9.28** | 13.5 K | **635 K**185 box / 0 rect | 16.7 K | 0 | ers 9257/2577etl 10538/1296eub 10720/1114 |
| 同上 | Magma | 91.6 | **8.56** | 13.5 K | 39.9 K97 box / 89 rect | 16.7 K | 0 | mfp 0/10994mpm 9240/1754mdt 9120/1874 |
| `minecraft-1.21.4-fabric-iris-bsl-in-world`120memo 冷) | Espryt | 23.2 | 21.04 | 32.6 K | 8.8 K | 1.8 K | 0 | ers 1958/1843etl 722/3079 |
| 同上 | Magma | 23.2 | 11.26 | 313 K | 256 K | 1.8 K | 0vtxc 1.7 K | mpm 1890/895mdt 1573/1212 |
| `improved-transparency-minecraft-26.3`1200 | Espryt | 1320 | **8.44** | 333 K | 0 | 0 | 0 | ers 156925/2791etl 148606/11110eub 148246/11470 |
| 同上 | Magma | 1320 | **6.53** | 173 K | 0 | 0 | **331 K** | mfp 21360/137036mpm 134421/2615mdt 156611/1785 |
门缩写:ers = `EsprytRenderState`etl = `EsprytTextureSyncList`eub = `EsprytUnitBindingsEpoch`mfp = `MagmaDrawFastPath`mpm = `MagmaPipelineMemo`mdt = `MagmaDynamicTail`。读法:真机稳态动态 accessor 成本是每 draw 6.59.3 次(预测区间 10–25 的下沿),推送要打败的是 ~8 次 accessor + memo 探测;Magma 在 26.3 每帧重打包 **331 KB** 具名 UBO 字节(D-B8);同样 185 次发射,Espryt 整 box 路径 635 K 纹素字节 / 帧、Magma rect 路径 40 K16×("server 选上传形状"的依据)。
```sh
ANDROID_SERIAL=<serial> MSYS_NO_PATHCONV=1 python3 tools/trace_replay/run_android_retrace_local.py \
--case minecraft-1.21.4-in-world --backend DirectGLES --env MOBILEGL_PIPE_STATS=1 --env MOBILEGL_PIPE_STATS_PERIOD=120
# 数字在结果目录的 mobilegl.log 里,grep 'MGPipe stats:'
```
### 1.4 桌面数据点与语料事实
- llvmpipe / lavapipe 动态 accessor`GuiBatchScenario`memo 冷):Espryt 20.65 / Magma 15.54 次 / draw。
- dirty-surface 面:`MG_Impl/GLImpl` 41 个文件、926 次 mutator 调用、73 个不同 mutator`RecordError` 占 836 次);92 次位于同函数内也到达后端的即时发布点,其余由紧随的 verb 发布。
- 读点覆盖:63 个 `PipeInputs` 字段;后端读点清单 → 调用映射 **0 UNMAPPED**
- OOM 探测惯用法:41 个 trace fixture 中 0 例(9 次 `glRenderbufferStorage` 无一在 3 个调用内跟 `glGetError`)→ `glRenderbufferStorage*` 不 ack。
- `FramebufferSrgb` / `DepthClamp`:六个后端读点消费编译期常量 `false` / 零读点;`glEnable` 落到 `default:` 分支既不存储也不报错;41 个 fixture 无一开启。
- payload 尺寸(`MGPipeTypes.h``static_assert`arm64 与 x86-64 一致):`MGPDrawInfo` 56、`MGHostSpan` 32、`MGPBindRenderState` 12、`MGPResourceDesc` 88、`MGPFramebufferState` 304、`MGPProgramDesc` 192、`MGPSubData` 72`SEG_CMD` 按 56 B 头定尺,MC 帧 10004000 draw 时每帧 56224 KiB 头字节。
- persistent map 采纳的既有基线(`dev`MC 26.3Adreno):p99 163→21 ms、稳态 40→115 fps、省 ~400 MBP11 的回归上限对着它。Mali 上传作业数悬崖:~100 个精灵 rect 对一个 union box 是 +6 ms/frame。
### 1.5 Harness 事实与陷阱
- trace app 从不到达 `MobileGL::DestroyImpl``MOBILEGL_PIPE_STATS_FILE` 在设备上永远不会写;只有 `mobilegl.log` 的周期汇总行,`MOBILEGL_PIPE_STATS_PERIOD` 为此而加。
- `run_android_retrace_local.py` 每棵树共用一个 `.trace-work/android-retrace-result` 根并 `rmtree`,两台设备必须从一棵树**串行**跑。
- `--env` 值里的 `/data/...` 会被 MSYS 路径转换,用 `MSYS_NO_PATHCONV=1`
- ColorOS 首次 `adb install` 卡在 `InstallGuideActivity` 确认页;streamed install 进行中点它会让设备掉线几秒。
- `minecraft-1.21.1-neoforge-create-indirect-in-world` 在两台设备上都失败,`dev@81b17c0b` 基线 APK 复现——`dev` 侧问题(`ROADMAP.md` 开放问题 17)。
## 2. P1lavapipe / llvmpipe
### 2.1 规模
| 量 | 值 |
|---|---|
| 后端 `pGLContext->` 箭头站点 | 277Espryt 113、Magma 164 |
| 非箭头行 | 58Espryt 9、Magma 49,其中 43 条是 Magma 的逐 verb `MOBILEGL_ASSERT` |
| `PipeInputs` 字段 / 不同访问器 | 63 / 62Espryt 32、Magma 56 |
| 填充点 | 83 条 `MGP_FILL`,覆盖 69 个 verb、9 个类 |
| `SyncPersistentMappedRange` / `SyncGpuWrites` | **21**Espryt 9 + Magma 12P5 b1 复核,原记 20 漏了共享 helper `ResolveIndirectCommandBytes`/ 6 |
### 2.2 verify 通道发现的两类真问题
**缺填充行(9 处)**`kReadback``IsTransformFeedback{Active,Paused}``kTextureOp``kDispatch``IsCapabilityEnabled``kBlitOrCopy`/`kTextureOp` 缺着色器 blit 用到的 viewport 与顶点 / 缓冲绑定。其中 8 行是静态过近似(代码路径可达但通道未跑到),有意保留——能退役它们的证据只能是动态的(完整 CTS caselist + `MOBILEGL_PIPE_POISON_OMIT`,未做)。
**verb 内后端改前端(3 个字段)**Magma 在 draw 里写前端对象(合成回退纹理、材质化排队清除、覆写 sampler filter),8 条 DirectVulkan 用例与 2 条 trace 报 `Fatal{PipeVerifyDiffer, "GetSamplingResolutionGeneration@Draw*"}`。解法 **push-on-mutation**:前端计数器移动时用 `MGP_NOTE_MUTATION(Field)` 刷新推送块里那一个字段——钩子挂在三个计数器上(`BumpSamplingResolutionGeneration``BumpTextureBindGeneration` / `NoteUnitTouched`、高水位分支),不挂在四十个写入点上。
### 2.3 验收
| 门 | 结果 |
|---|---|
| pull 构建符号与 `.text` | 0 增 / 0 删 / 0 改尺寸 / 0 重命名,`.text` 不变 |
| `MG_Backend` 里的 `pGLContext` | 0 |
| 单元(pull / push / verify | 1485 × 3 |
| `integration-gpu`pull / `integration-verify` | 878 / 818 零 `Fatal{` |
| 79 例 retrace`MOBILEGL_PIPE_VERIFY=1` | 79/7979/79 armed,零 `Fatal{` |
| 两个阴性对照 | 篡改字段变红、抽掉一个填充戳记在那条 verb 上变红 |
| 测试名 | 0 删除,+29 |
verify 构建的代价:`integration-verify``integration-gpu` 同量级;79 例 retrace 在 4 路下约 20 分钟。
## 3. P2`738b289d`
### 3.1 门
| 门 | 结果 |
|---|---|
| G1 pull 构建符号 | 0 增 / 0 删 / 0 重命名;**4 处认定 resize**`RenderState::{RenderState, SetCapability, IsCapabilityEnabled}``_GLOBAL__sub_I_DirectGLES.cpp`);`.text` +160 B |
| G5 `SyncRenderState` | `RenderStateImpl` 段 sha 逐字节相同 |
| G2 / G14 | 名差 00 删除 / +119 |
| 单元 | 1566 × {pull, push, verify} |
| `integration-gpu` | 916/916 × {pull, push, `MOBILEGL_PIPE_PUSH=0`};渲染状态敏感子集 72/72 |
| `integration-verify` | 828 零 `Fatal{` |
| 79 例 retrace | push 79/79verify 79/79 armed 零分歧 |
| G7 setter 一致性阴性对照 | 变红并点名 `SetColorMask` |
| `CsoContentAddressing` / verify 三组对照 | 6/6 / 44/44`PoisonOmitted``VerifyCorrupted``HandleRecycle` |
### 3.2 设备配对 A/B-O0 勘误)
两机 64 次运行(小米 + Oppo,四 trace × 两后端 × finish 开/关,reboot-clean、钉频、best-of-3、尾 200 帧)所用的两臂 APK 是**未优化构建**(`libMobileGL.so` 43.2 MB / `.text` 21.8 MB,对 Release 15.5 / 9.4 MB),绝对值与差值都是 -O0 读数,不作基准线;Release 基准线以 §4.4 为准。-O0 读数:小米 p50 **+814%**(四 trace 两后端),Oppo Espryt **+1618%** / Magma **+1011%**p99 同向;finish 开关两臂几乎一致(多出的是客户端 CPU);计数器两机逐字相同。原始 32 行表在 git 历史(`ea34bccb` 版本的本文件 §10)。harness 误杀记录:`trace-replay-ci.sh``pidof` 单次采样失败即 force-stop`dev` 侧跟进。
### 3.3 DriverBenchT1 / T2(桌面 llvmpipe / lavapipe`wsl_p2_bench.sh`Release240 帧 × 5 次取中位数,`ns_per_op`
| 臂 | `mc_vanilla_draw`ns/draw | `mc_state_toggle`ns/开关对) | `mc_pass_switch`ns/pass |
|---|---|---|---|
| native | 4771 | 22968 | 437759 |
| Espryt pull / push / push `PIPE_PUSH=0` / push 位 63 | 5121 / 5443 / 5671 / 5374 | 23753 / 24869 / 24584 / 24630 | 443300 / 446017 / 443807 / 435454 |
| Magma pull / push / push `PIPE_PUSH=0` / push 位 63 | 16900 / 17245 / 17599 / 17444 | 32705 / 33857 / 34082 / 34780 | 438406 / 446067 / 445006 / 444758 |
| `mc_vanilla_draw`ns/draw | Espryt | Magma |
|---|---|---|
| **T1** = push pull(整个边界) | **+322**+6.3% | **+345**+2.0% |
| **T2** = push(`PIPE_PUSH=0`) pullP1 残余填充) | +550 | +699 |
| **T1 T2**P2 自己加的减的) | **228** | **354** |
| 位 63 push(CSO 内容寻址净值) | −69(≈ 0) | +200(内容寻址每 draw 省 200 |
| blend-toggle / pass switch | +4.7% / +0.6% | +3.5% / +1.7% |
读法:P2 的 tracker + CSO 比它替掉的 P1 残余填充便宜;剩下的 T1 是尚未句柄化的填充与 dirty 走查。`mc_state_toggle``DriverBenchStateToggle` 钉住每帧 46 对开关;位 63 对照的开关 `CsoContentAddressingScenario` 常开(内容寻址臂 `csom ≤ 4``csom < csob`,位 63 臂 `csom == csob`)。
### 3.4 计数器读数
`resid=` 已非零且棘轮压到底(1248 → 8):桌面 push retrace `iris-bsl``resid=197.07` B/帧 = 每 draw 0.64 块;`csom/csob` = 8 / 1415CSO 复用比)。小米 push 臂(-O0,计数器与优化无关):
| trace | Espryt `ers` / `etl` / `eub` | Magma `mfp` / `mpm` / `mdt` | `resid=` B/帧 | `csom` / `csob`(每 120 帧) |
|---|---|---|---|---|
| `minecraft-1.21.4-in-world` | 6020/1850 · 6884/986 · 6962/908 | 0/7278 · 6030/1248 · 5928/1350 | 178.31 | 2 / 1719 |
| `improved-transparency-minecraft-26.3` | 78960/1367 · 75378/4949 · 75199/5128 | 10740/68928 · 67660/1268 · 78800/868 | 185.36 | 0 / 1157 |
| `minecraft-1.21.4-fabric-iris-bsl-in-world` | 113/133 · 85/161 · 82/164 | 0/177 · 86/91 · 81/96 | 370.67 | 1 / 122 |
| `minecraft-1.21.4-startup` | 174/185 · 305/54 · 305/54 | 0/118 · 0/118 · 0/118 | 25.08 | 9 / 181 |
CSO 内容寻址在稳态窗口里几乎不再铸造;memo 门形状与 §1.3 的拉取基线一致。**未测**:逐 dirty 位触发率(`FireCount`/`WalkCount` 已实现但不在汇总行)、每 draw payload 直方图(只在 teardown JSON 里)。
### 3.5 遗留判定
- `MOBILEGL_ESPRYT_DISABLE_INVALIDATE_FLUSH=1` 的 186 条过滤不进比对器(P3a 在 push 下跑了一次 958/958;进比对器推迟到 P3b)。
- Track H 单位成本的日历口径未记录(产出侧在案:11 条 memo 删除 + 2 条重键零回归)。
- 句柄 ABA 对照"重键前红":修复前 `HandleRecycle` 28 条中 1 条红(`AbaControl` 期望死对象的红却看到替换对象的绿);修后 32/32,且关掉 `MOBILEGL_PIPE_HANDLE_ABA_CONTROL` 两臂都 `observed=FRESH` 并失败——污染只由被打掉的身份产生。
## 4. P3a`fde5fda3`,基线 `5cb826b0`44 个提交,37 文件 / +9273 / 230
### 4.1 五部分门(本地 `~/w7/pipe`
| 门 | 结果 |
|---|---|
| 构建 pull / push / verify | rc 0 / 0 / 0fail-fast,绝不拿陈旧二进制下判决) |
| A 门 include 闭包 / C 门 `pGLContext` / G13 | 4 probes 0 problem / 空 / 空 |
| **G1** | `.text` 10806323 → 10806323+0);27811 符号 **0 / 0 / 0 / 0** |
| **G5** 十一函数(pool / 延迟释放 / ring / `FlushPendingRangesNow``FlushPendingRangesFrom` | 对 `44c2b5cf``5cb826b0` 都逐字节相同;self-test 两个阴性对照按名变红 |
| `integration-verify` / 79 retrace verify | 842/842 零 `Fatal{` / 79/79 armed 零分歧 |
| G2 / G14 | 差 0 / 0 删除 +58 |
| 单元 | 1619 × 3 |
| `integration-gpu` | 958/958 × {pull, push, `PIPE_PUSH=0`, `0x7f`G12 子系统关闭臂), `ESPRYT_DISABLE_INVALIDATE_FLUSH=1`} |
| buffer/VAO 族 / `RenderStateSpans`+`Residual`+`VertexInputEmit`+`ResourceEmit` | 202/202 / 48/48 |
| `HandleRecycle`verify / 子系统对照 / verify 对照组 | 60/60 / 10/10 / 64/64 |
| G7 vertex-input 阴性对照 | 变红并点名 `IsBgra` |
| 79 retrace push | 79/79 |
| G3b 具名五条 | 桌面全绿(都在 79 例扫描内),但单独的具名扫描因门脚本把正则写成逗号清单而选中 0 例;设备侧按开放问题 17 排除 `create-indirect` → 记为"桌面全绿、设备侧部分" |
| `gen_pipe` / `gen_pipe_dirty_surface`(扫描根扩到 `MG_State/GLState` | self-test 7 / 21 个阴性对照全部触发;75 个 mutator 全映射,0 COARSE / 0 UNDECIDED |
### 4.2 "重键前红"与验证轮找到的三个缝隙缺陷
buffer 类的红前证据(package C 尚未注册 `MGPipeResourceOps` 时):`HandleRecycle``.AbaControl` 臂通过(它断言的就是被污染的内容)、`.Legacy` 通过、`.Handles` 可见地 skip;C 注册后两条 skip 转为断言,最终 60/60。
| # | 缺陷 | 表现与修法 |
|---|---|---|
| F1 | vertex buffer 条目按属性的 GL 绑定点解析,而不是按属性下标 | 两者只在 `KHR-GL43.vertex_attrib_binding` 题材上分叉;`VertexAttribBindingScenario` 6 → 3 |
| F2 | ensure 路径读 `MGPResourceDesc::HasDefinedContent`(上一次 respecify 时的事实)判断影子有无字节 | `glBufferData(size, NULL)` + `glBufferSubData` 后应用字节被静默丢掉;改为持有前端对象时读 `HasDefinedContent()` |
| F3 | 惰性生成的 twin 从不发布影子基址,fp64 收窄拒绝每个 draw | `hostBytes` 终身 null → Adreno workaround 禁用属性;在算出基址处补发布,只对非采纳资源 |
方法学:包 worktree 里 `tools/trace_replay/fixtures` 是 LFS 指针,对着指针跑 retrace 报 `passed 2 / 79``ssim=None`——**假红**base-instance 对照在 llvmpipe 上要先关掉原生 `GL_EXT_base_instance` 才可证伪。
### 4.3 Track H 单位成本
日历:四个包(contract/wire、client、espryt、gates)各一轮实现 + 对抗性评审 + 至多两轮返工,全部在 2026-09-08 一天内,对 27 天绊线 1/27。memo 账:直接删除普查 11 条里的最后一条(`ConvertedVertexStreamKey::sourcePin`);句柄臂上退役 VAO twin 五个同步 memo 成员;重键 VAO twin 索引槽 memo、`ResolvedDrawBuffers`、twin 同步门、`ConvertedFloat64Stream`**保留**`MOBILEGL_PIPE_LEGACY_MEMOS` 下仍编译):以上全部成员、`g_pendingFetchBaseInstance` 族、D-K 那组——真删会移走 pull 符号或改 `sizeof`G1 的 0/0/0/0 就是这条的度量,随 P13 退役。
### 4.4 两机 Release 配对 A/B、MC 26.3 的 p99、DriverBench(记录项)
协议:reboot-clean、`pin_device.sh` 钉频并前后 `check`、两臂背靠背、`--benchmark-repeats 3 --benchmark-tail-frames 200`、best-of-3、`--benchmark-no-finish` 主臂;APK 都是 `3e298c9a` 的 Release trace 构建(`.text` 9.4 MB)。臂:pull = pull 库;P2 = push APK `MOBILEGL_PIPE_PUSH=0x7f`P3a = push APK 默认 `0x1ff``create-indirect` 排除(开放问题 17)。单位 ms/帧。
| 设备 | trace | 后端 | pull p50 | P2 p50 | P3a p50 | pull p99 | P3a p99 | 备注 |
|---|---|---|---|---|---|---|---|---|
| 小米 | `improved-transparency-minecraft-26.3` | Espryt | 10.810 | 11.485+6.2% | 11.697**+8.2%** | 25.457 | 26.322 | |
| 小米 | 同上 | Magma | 10.675 | 11.473+7.5% | 11.459**+7.3%** | 25.014 | 26.035 | |
| 小米 | `minecraft-1.21.4-rd12-odinlite-in-world` | Espryt | 8.220 | 9.117+10.9% | 10.650**+29.6%** | 21.895 | 24.487 | |
| 小米 | 同上 | Magma | — | — | — | — | — | 三臂都 SIGABRT`scudo::reportMapError``dev` 侧) |
| 小米 | `minecraft-1.21.4-fabric-sodium-in-world` | Espryt | 1.292 | 1.349+4.4% | 1.382**+7.0%** | 2.418 | 2.443 | |
| 小米 | 同上 | Magma | 0.485 | 0.504 | 1.010 | 1.469 | 2.187 | 亚毫秒帧,噪声 |
| 小米 | `create-instancing` | Espryt / Magma | 944.4 / 1003.9 | 945.2 / 1019.5 | 949.9 / 1015.6 | — | — | 两帧 fixture |
| Oppo | `improved-transparency-minecraft-26.3` | Espryt | 9.741 | 10.570+8.5% | 10.542**+8.2%** | 26.312 | 27.022 | |
| Oppo | 同上 | Magma | 8.162 | 8.920+9.3% | 8.973**+9.9%** | 22.851 | 23.638 | |
| Oppo | `minecraft-1.21.4-rd12-odinlite-in-world` | Espryt | 9.938 | 11.009+10.8% | 12.963**+30.4%** | 27.137 | 29.765 | |
| Oppo | 同上 | Magma | 8.001 | 8.933+11.6% | 10.161**+27.0%** | 24.723 | 27.355 | |
| Oppo | `minecraft-1.21.4-fabric-sodium-in-world` | Espryt / Magma | 1.896 / 0.399 | 1.770 / 0.431 | 1.841 / 0.437 | 2.993 / 1.206 | 3.079 / 1.409 | 噪声内 |
| Oppo | `create-instancing` | Espryt / Magma | 1075.1 / 758.3 | 1045.1 / 731.0 | 1060.1 / 760.0 | — | — | 两帧 fixture |
读法:(1) **P2 边界在 Release 下的真实代价是 +612%**,两机两后端一致;(2) P3a 在 26.3 与 sodium 上几乎不再加价,**但在 rd12 上把差距从 +11% 推到 +2730%**——rd12 每帧 VAO/buffer 绑定切换远多于 26.3,每次切换走一遍 `set_vertex_buffers` 构造 + `ContentHash` + applier 记录 + 逐属性走查(P4a 补的 `csob-blob` 计数器给了字节口径:rd12 1.06 MB/帧,其余用例中位数 2.9 KB/帧;DirectVulkan 恒 0);(3) **MC 26.3 在 Adreno 上的 p99**25.46 → 26.32 ms+3.4%),仍在采纳基线的 2126 ms 档;(4) `mpr` 在设备上成立(26.3 两机都是 8,P2 臂恒 0);(5) 计数器三臂逐字相同。
小米 rd12 + Magma 三臂(含 pull)都 `SIGABRT``scudo::reportMapError``scudo_calloc`pull 库与 P3a 前的 Magma 路径符号一致——既有 bug,`dev` 侧任务。
DriverBench`wsl_p3a_bench.sh``c20e2f2b``mc_vanilla_draw` ns/drawT2 = `0x7f` 臂):
| | Espryt | Magma |
|---|---|---|
| **T1** = push(`0x1ff`) pull | **+1048**+20.5% | **+611**+3.6% |
| **T2** = push(`0x7f`) pull | +349 | +189 |
| **T1 T2 = P3a 自己加的** | **+699** | **+422** |
| 位 63 push | 6 | +20 |
| blend-toggle / pass switch | +5.2% / ≈ 0 | +2.8% / ≈ 0 |
读法:P3a 的 buffer/VAO 句柄路径每 draw 多花 Espryt 699 / Magma 422 nsMagma 没有句柄化的 VAO 消费者,全是 client 侧发射 + applier 记录);进优化清单:vertex-input 发射的 per-draw 抑制与 applier 记录就地更新。`DriverBench` 必须经 `DRIVERBENCH_EGL_LIB` 显式 `dlopen` provider,不得靠 `LD_LIBRARY_PATH`glvnd 会把 GPU 悄悄换成 llvmpipe)。
### 4.5 决定与遗留
- **ID-15**`Managers.cpp` 的三层 flush 排水梯每个预处理臂各一份——push 构建跑 `FlushPendingRangesFrom`pull 构建跑逐字节不变的 `FlushPendingRangesNow`;两个名字都是 G5 行,各对自己的 pin 比。转发函数不可行(G5 提取器不认预处理)。
- **M-3**:fp64 顶点数组收窄在句柄臂上少做一处 `SyncGpuWrites``SyncFloat64AttributeAsFloat32ByHandle` 手里只有句柄)——默认掩码下两臂唯一的行为差异(fp64 数组 + shader 写过的源 buffer + 无显式回读),P8 把拉取搬到 client 侧即关闭。
- 整体 diff 终审抓出两个跨包接缝:client 为每个 VAO 铸的 `VertexElementsCso` 槽在 Magma 下泄漏(修为 `~VertexArrayObject` 走后端无关的死亡路径);`FlushPendingRangesFrom` 在 G5 覆盖之外(→ ID-15)。
- CI 独有的 teardown 崩溃(`exit()` 时静态析构顺序 UAF):`MGPipeSlots()` 等单例与四个持有前端 `SharedPtr` 的静态 `PipeInputs` 改为退出时泄漏(`d54ec57a``6515c8e6``fde5fda3`),ASan 10/10 干净;复现钥匙 `GLIBC_TUNABLES=glibc.malloc.tcache_count=0`
- `dev` 侧跟进(拆分不顺手修):`g_uploadRing` 不被 `OnBackendContextDestroyed` 重置(良性,`RingAvailable` 自愈);`ScopedDefaultUnpackState::s_synced` 没有失效路径。
- `MG_Test/Buffer/BufferTest.cpp` 的 fixture 只 scope 了 `BufferBackendOps` 不 scope `MGPipeResourceOps`,26 条被路由进 pipe——修后 86/86;给它一个 pipe 形 mock 是跟进项。
- 峰值 RSSpush vs pull79 例):`retrace_gate.py` 不报,没有数。
## 5. P4a`8c458cd5`,基线 `37da3c3a`101 个提交,86 文件 / +30066 / 384
### 5.1 全门(`6035c9d7` 全量 + `8c458cd5` 复跑)
| 门 | `6035c9d7` | `8c458cd5` |
|---|---|---|
| **G1**(认定 resize 集为空) | 0 / 0 / 0 / 0`.text` 不变 | 同上 |
| **G5** | P3a 十一函数 rc 0P4a **17 区 / 3 文件** rc 0self-test 8 个阴性对照按名变红 | 同上 |
| G2 / G14 | 差 0 / +275 | 差 02902 条)/ +314 |
| 单元 | 1772 × 3 | **1785 × 3** |
| `integration-gpu` | 1091/1091 × 七臂 | **1117/1117 × 七臂**(默认 `0x1fff``0x1ff``0``0x9ff``0x5ff`、pull、`ESPRYT_DISABLE_INVALIDATE_FLUSH=1`DirectVulkan 559/559 |
| `integration-verify` | 896/896 零 `Fatal{` | **920/920** |
| retrace79 例) | verify 79/79 armed 零分歧;push 79/79G3b 12/12 | push 79/79 |
| 阴性对照脚本 | `g7_negative_control.sh``p3a_vertex_input_negative_control.sh``IsBgra`)、**`p4a_descriptor_negative_control.sh``Layered``borderColorForm`** rc 0 | 同上 |
| 子系统对照套件 | `CsoContentAddressing` + `ResourceSubsystemControl` + `ObjectSubsystemControl` 24/24`0x9ff` 依赖拒绝臂 14/14`HandleRecycle`verify180/180 | 同上 + 184/184 controls |
| 八族拒绝普查 | — | **0**(逐用例读私有日志;`ctest -V` 是假零) |
G9 的"落地前必须红"没能通过公共 GL 达成(回读模拟自己会设 `GL_DEPTH_STENCIL_TEXTURE_MODE`):改成 `PipeApplyPeek` 白盒断言,变异下 4/4 变红。真正红过再绿的两条来自终审:per-level respecify 丢上传(`0x1fff` 下读回全黑)与 delete-then-draw`pure virtual method called`)。CTS `direct_state_access.framebuffers*` / `packed_pixels`G15)未跑,随 P3b/P4b 补。
### 5.2 缝的分类(契约七次修正 `c0b`…`c0g` + 一轮缝类审计 + 一轮终审修复)
| 类 | 实例 | 症状 | 预防 |
|---|---|---|---|
| 编码没定死 | `MGPSubData::Target``DepthStencilMode``MGPSurface::Kind`、缺 `TextureTarget` | 两侧各自发明一套;`Texture1D == 0``kMGPipeResourceTargetBuffer == 0` 撞上 | 编码表放进契约 |
| 身份 vs 内容 | 内置 samplerclient 按身份铸、cache 按内容铸 | 查找永远落空 → 17 条 Iris trace 用驱动默认采样器 | 每 kind 两侧 handle 规则表 |
| 记录键错了维度 | framebuffer 记录按"当前绑定"存,DSA 按名字来 | 打进从没收到附件的 FBO | 记录按对象存;`Named = 3` |
| 进程级单例 vs 每上下文命名 | `CompositeResolver` 按管线 GL 名记忆 | 释放另一个上下文还活着的合成体 | 单例的键含上下文身份 |
| 破坏性客户端动作缺前置条件 | 按 acceptance 清 dirty,但 Magma 无消费者、依赖位只在服务端拒 | 上传丢失:66 条 DirectVulkan 用例、`0x7ff` 下 438/491 | 消费者门 + 依赖门都在客户端:一条不发 |
| 快门看不见自己的主体 | `glBindSampler`、SSO 下 `GetCurrentProgram()``glBindImageTexture` 只换 level | 记录停在上一次的值(`create-indirect` SSIM 0.887 | "记录字段 → setter → 快门"完备表;优先混入已有世代 |
| 清得太宽 | `resource_respecify` 清掉整张待上传表 | 已接受的那一级永久丢失 | 作用域随调用走 |
| 死亡没通知发射方 | 六个死亡 helper 只释放 slot | 已删句柄解析到已释放对象 → UAF | 死亡转发给每个 emitter |
| 门不能变红 | G7 脚本永远编译不过、`HighWater(ShaderCso)` 取段顶、G9 红前态公共 GL 不可见 | 绿得毫无意义 | 每个门带阴性对照并真跑过一次红 |
方法论结论:六个包的 v1 全部通过自己的门、六份对抗性复审全部判 REWORK,最贵的两个缺陷(丢上传、delete 后 UAF)是**整体 diff 终审**才抓到的——它们跨包,各方自洽。终审是唯一能看见跨包契约的那一轮。
### 5.3 Redmi 三臂 A/B、MC 26.3 的 p99、上传形状(记录项)
设备换为 Redmi `2f7cbe2e`(与小米同 SoC 同定频点,数值可比;GPU 当时钉 1050 MHz;主动风扇 level 240 个样本 40 个 PINNED)。APK `8c458cd5` Release 双臂;`--benchmark-no-finish`,尾 200 帧、best-of-3、逐线程 CPU p50 ms`0x1ff` = P2+P3a 边界,`0x1fff` = P4a 默认。
| 用例 | 后端 | pull | `0x1ff` | `0x1fff` | Δ P2+P3a | Δ 合计 | **P4a 自己** |
|---|---|---|---|---|---|---|---|
| improved-transparency-26.3 | Espryt | 10.716 | 11.754 | 12.124 | +9.7% | +13.1% | **+3.4 pt / +0.37 ms** |
| improved-transparency-26.3 | Magma | 10.603 | 11.543 | 11.585 | +8.9% | +9.3% | +0.4 pt(噪声) |
| rd12-odinlite | Espryt | 8.210 | 10.798 | 11.182 | +31.5% | +36.2% | **+4.7 pt / +0.38 ms** |
| rd12-odinlite | Magma | — | — | — | — | — | 三臂全 `rc=1``scudo``dev` 侧,换机仍复现) |
| fabric-sodium | Espryt | 1.312 | 1.406 | 1.454 | +7.2% | +10.8% | +3.6 pt / +0.05 ms |
| fabric-sodium | Magma | 0.474 | 0.502 | 0.507 | +5.9% | +7.0% | +1.1 pt(噪声) |
| 1.21.4-in-world | Espryt | 2.369 | 2.732 | 2.867 | +15.3% | +21.0% | **+5.7 pt / +0.14 ms** |
| 1.21.4-in-world | Magma | 1.028 | 1.147 | 1.145 | +11.6% | +11.4% | 0.2 pt(噪声) |
| fabric-iris-bsl | Espryt | 1.727 | 1.740 | 1.811 | +0.8% | +4.9% | +4.1 pt / +0.08 ms |
| fabric-iris-bsl | Magma | 0.742 | 0.788 | 0.786 | +6.2% | +5.9% | 0.3 pt(噪声) |
读法:P4a 自己在 Espryt 上是 +3.4 +5.7 pt0.050.38 ms/帧),大头仍是 P2+P3a 的边界;Magma 两臂在四个用例上落在噪声内——消费者门在设备上的读数(Magma 一条 P4a 记录都不发);`vanilla` 是 P4a 占比最高的用例(draw 少、状态切换密)。**MC 26.3 在 Adreno 上的 p99**pull 25.297 → P4a 26.841 ms+6.1%),仍在 2126 ms 档。**上传形状 pull 与 push 逐项相同**79 例两臂 `tex[emit/box/rect/jobs]`18451/16060/2391/39926 对 18453/16062/2391/39928,唯一差异是 2 次 `trp` 带来的重放上传)。线索:设备上 26.3 Espryt 的 `sve` ≈ draw 数(9143 / 9138),桌面 ~0.07/draw——每 draw 重发一次 sampler-view 集合,进 P3b/P4b 优化清单。`acc/draw` 在这一波普遍下降而 CPU 上升,不是矛盾而是该计数器的定义。
### 5.4 DriverBench`wsl_p4a_bench.sh``8c458cd5``mc_vanilla_draw` ns/draw
Espryt T1`0x1fff` pull= +1076.1T2`0x1ff` pull= +1064.7T1 T2 = +11.4Magma T1 = +629.0、T2 = +452.6、T1 T2 = +176.4。两臂绝对值在两轮之间各漂 ~200 ns 而差只有 10130 ns**桌面 bench 分辨不出 P4a 这一档**;可引用的是 T1 ≈ +1.1 µs/draw 的总边界(Espryt)与设备侧三臂表。Magma 的 +176 ns 不是"Magma 在跑 P4a"(消费者门让它一条不发),是 tracker 多算的快门加噪声。
## 6. P5joint `e61d0012` → 落地 `eec0e836` → 收尾头 `37fc4fdb`
### 6.1 五部分门(joint)与落地快门
| 部分 | joint 实测 |
|---|---|
| 1 接口纯度 | include closure 4 probes / 0 problemspull `MG_Remote` 符号 0、split 610G1 `.text` 10806611 → 10806611、27814 符号 0/0/0/0P3a/P4a G5 对 `ff2994d9` byte-identical |
| 5 覆盖 / 生成器 | `gen_pipe` self-test 9/9dirty-surface 27/27`UseProgram` 一项明确 UNDECIDED);field ownership 15/15emitter/CSO 185/185verify controls 4/4 |
| 3 行为 A/B | G2 差 0G14 0 / +42unit 1816×3、split 2038Wire 58/58`integration-gpu` pull 1128、push 1128、split-monolith 1149split-inproc 普查 426 pass / 185 skip / 511 abort / 27 fail`integration-split` 21/2119 run、2 design-skip);persistent arm 2/2split `pmap=2160.00, mpr=1`push `pmap=0.00, mpr=1` |
| 2 语义 / retrace | `integration-verify` 930/930 零 `Fatal{`OpenRA inproc 2/2 双后端 SSIM 1.0push retrace 79/79verify retrace 79/79 armed |
| 4 设备 | 未跑(joint 禁止 adb);见 §6.4 |
落地快门(`eec0e836`ID-66):split unit 2038`integration-split` 22/22push `integration-gpu` 1128G1 0/0/0/0 `.text +0`
### 6.2 退出门 E1E6 与 27 个 wrong-answer
| 门 | 实测与"为什么会红" |
|---|---|
| E1 barrier | reduced path 19 pass / 2 skip / 0 fail`MOBILEGL_IPC_VERB_BARRIER=0` 选中的 14/14 全 abort,每个私有日志有自己的 `Fatal{BarrierViolation, "<slot>"}` |
| E2 OpenRA | 2/2 SSIM 1.0x2:丢 29 clears 仍 SSIM 1.0(被后续地形 draw 覆盖),改为丢 758 `DrawVbo` 后 SSIM 0.000036r2 验证真实 CTest 顺序 baseline → pull-library control → 恢复原库 → draw-drop,并断言库身份 |
| E3 persistent map | (a) 收尾头 6 selected 中 4 pixel red、2 条 `TheMapLandsInTheArmItsLaneDeclares` 设计性 skip 被 j0 判红 → r2 精选默认 / SmallRing 下 4 条 pixel case 各带自己的 assertion + 私有诊断;(b) ID-42 emulated membership green → 3 red → green(e) x2 证明 wrapr2 证明真实 retirement wait1 MiB 臂 `ringwraps=1 ringwaits=1`8 MiB 对照同时红) |
| E4 field ownership | 生成器 15/15strict lane 19 abort / 2 skip,首条 `Fatal{UnmigratedPipeInput, "GetTextureContextId@Clear"}`——BARRIER-PULLED 债务的响亮读法 |
| E5 honest inproc | 19 pass / 2 skipv1-r3 的 `StagedShadowProductionTest` 证明 ensure 上传 server shadow(删保护会读 client A 变红),覆盖 unmapped 对象;coherent-map 的 server 侧绕过由 r1 #1 关闭 |
| E6 phase gate | 普查在 v1-r3 修掉六条过宽 whole-store 拒绝后 **432 / 185 / 505 UnmigratedVerb abort / 27 failed / 0 segfault**1149 项,`~/w7/p5b-c0b-census-logs/results.json` |
| 27 个 wrong-answer 家族 | 条 | 去向 |
|---|---:|---|
| `LayeredAttachmentShapeScenario` | 14 | P4b/P7 layered texture readback |
| packed depth/stencil `GetTexImage` | 3 | P4b/P7 texture-shadow readback |
| framebuffer `HandleRecycleScenario` | 5 | P4b/P7 readback(不是已证明的 handle recycle bug |
| `PrimitivesGeneratedNoXfbScenario` | 3 | P7 query |
| `TextureParamsWithoutASamplerView` | 1 | P6 inspection forwarder |
| `P4aFinalFixScenario` FBO/RBO delete | 1 | 读回用 ReadPixels,完整像素因果未隔离;client-thread framebuffer death 归 r1 #2 |
### 6.3 R-10、逐帧 ledger 与内存
规范 ledger`ProtocolSmokeTest` 钉住):**SEG_CMD 8 MiB / SEG_STAGE 32 MiB / SEG_REPLY 16 MiB / SEG_EVENT 256 KiB**。`MOBILEGL_PIPE_STATS_PERIOD=1` 下 persistent-map 场景 `pmap=600.00 B/帧, mpr=1, rsp=35``rsp` 只是有 stamp 读点的下界)。inproc 进程峰值 RSSserver accept 时 11.5 MB、client teardown 141 MB(两角色共享一个进程,不是两个独立峰值)。
max record bytesx2`37fc4fdb`):Triangle / persistent map / OpenRA 25 帧 / SmallRing 都是 **`maxrec=784 B` / `SetVertexAttribDefaults`**,默认 cap 4 MiB(占 0.019%)——这些负载不需要 chunkingoversized `DrawVbo` 尾的 unit 具名拒绝 `Fatal{RingOverrun, "DrawVbo"}`
### 6.4 Redmi 四臂 A/Bsplit 未测)
会话 2026-09-16runner `eec0e836`,三份 APK 源码头 joint `e61d0012`;臂 = pull APK / push APK / split APK + `MOBILEGL_TRANSPORT=inproc` / splitctlsplit APK 不设 transport)。40 组前后 pin check 全 P/P37.239.9 °C。**27 组完成 / 13 组失败:全部 10 组 split 在 benchmark 前中止**improved-transparency 双后端 `DrawElementsInstancedBaseVertex`,其余 `DrawElements`),另 3 组是 rd12/DirectVulkan 的既有 `scudo` 崩溃。帧 p50 / p99ms):
| case / backend | pull | push | splitctl |
|---|---:|---:|---:|
| improved-transparency / DirectGLES | 10.535 / 25.415 | 12.106 / 26.973 | 12.235 / 27.131 |
| improved-transparency / DirectVulkan | 10.742 / 25.031 | 11.678 / 26.134 | 11.837 / 26.476 |
| fabric-sodium / DirectGLES | 8.314 / 9.573 | 8.311 / 9.701 | 8.303 / 9.486 |
| vanilla 1.21.4 / DirectVulkan | 1.043 / 2.293 | 1.159 / 2.404 | 1.179 / 2.426 |
| rd12 / DirectGLES | 7.999 / 22.089 | 11.105 / 24.865 | 11.261 / 24.771 |
splitctl 相对 push 的帧 p50 0.1% +1.6%split build 的 monolith 臂与 push 同源等价)。barrier tax 在 P5 未测得,归 P5b(§7.4)。
### 6.5 收尾头停止点、r1 / r2
`~/w7/p5-final-gate.log``37fc4fdb`):构建 4 × rc 0Part 1 G1 27,814 符号 0/0/0/0、`.text +0`、两条 G5 byte-identicalPart 5 完成;Part 3 unit 1817×3 / split 2086、Wire 58、pull/push GPU 1128、split-monolith 1149 零失败、reduced 22 零失败、broad lane 1149 selected532 non-success,含 abort);E1 14 red**E3(a) 因 2 条设计性 skip 被 j0-v3 的逐选项拒绝判失败,Part 2 / 4 未到达**。j0 的 skip 拒绝是对的(不能放宽),选择器才是错的。
收官审查(`p5-close-codex-review.md`,只读):1 blocker / 10 major / 2 minorID-73)。r1(核心四项):apply-role 不得进入 persistent-map producerframebuffer death 转 apply mailbox`PACK_SWAP_BYTES` 的 component / packed-word swapcommand-ring retirement 等待与重试。r2`37fc4fdb..d50183cb`,CI / 控制 / 跑器九项):broad debt lane 记录后继续硬门、全 skip 则 baseline 失败;E2 库身份 SHA256 恢复;E3(a) 精选 4 pixel case`ringwaits` 只计真正阻塞的分配;split unit 强制 `MOBILEGL_ITEST_REQUIRE_GPU=1`;普查跑器零执行拒绝、launch 前清私有日志;G5 pin 自测驱动生产选择路径;c1f 改用 ID-67 用例。r2 包门:split unit 2087、reduced 22、push 1128 零失败;E1 14 own reds、E3(a) 4 own redssmoke 16 core + 12 privatecensus 432/185/505/27。r2 没有新跑 pull G1(不影响 pull production code)。
过程记录(不计入实现产量):wave-1 跨族复审十项全部经独立 perturbation 确认(ring 空 wrap 算术、reply 几何差 16 B、blob 校验接受任意段、pad-bit 控制没发送该 bit、三个 CI 对照接受任意非零退出……);后续 v1 / c1 各轮的 review 计数在 ID-52/58/62/64;本地 `rereview` 身份污染的 81 + 58 个提交经 parent/env rewrite 接回 GitHub `ff2994d9`(ID-40),此后每阶段首个 commit 前先跑 `git var GIT_COMMITTER_IDENT`。这些数字是流程在 P5 尾声改变(ID-66)的原因。
## 7. P5b(主机门 `348d22a4`,设备源头 `82683d4a`
### 7.1 迁移与包证据
`348d22a4` 含 d1 / i1 / t2 / f1、r1 / r2、五槽 sync、具名 blit 与 GLES mip storage;发射表 A=2 / B=54 / C=15(目录 76 条,槽数与 opcode 数不是同一统计量)。
| 包 | 已落地行为与证据边界 |
|---|---|
| d1 | 19 个索引 / 实例 / multi-draw / indirect 槽经 `draw_vbo` 过线;独立包普查 77 个 Minecraft 后端用例 28 passed、49 first blockers,全部越过原 draw 首阻塞(默认 stage 32 MiB |
| i1 | 七个 image / compute / barrier / copy-image / storage-block 槽;原首阻塞 239 归零;CopyImage 的 client-shadow 镜像被跳过,`GetTexImage` 前端回退仍可能读旧 shadow |
| t2 | 六个 XFB / 曲面细分槽;原首阻塞实测 140(`BeginTransformFeedback` 95 + `PatchParameteri` 43 + `BindTransformFeedback` 2);包内基线 490 / 191 / 390 / 78,原 432 passes 全保留 |
| f1 | 11 个 clear / copy / mip 槽;原 34 个首阻塞归零;bound named-clear 接线,unbound 仍具名拒绝 |
| r1 / r2 | P5 收官 #113r1 定向 10 passed / 0 skippedclient-only push suppression 两个像素控制变红 |
| 具名 blit | `BlitNamedFramebuffer` 经 scoped read/draw binding 发布,退出恢复公开绑定;两后端四个 split 像素 entry 通过 + 15 unit |
| GLES mip storage | server 只验证 applier descriptor 的 Levels/extent;三个 mip 像素控制 3/3iris-BSL GLES 单例 SSIM 0.997496(默认 stage 32 MiB);registry 只 Find 不 mintbarrier 债);RGB 三通道 CPU fallback 保持 Fatal |
| sync | 五条现有 opcode 接线,wire 只传句柄,native fence 归 apply 线程;原 LOCAL guard 使 trace 的 `FenceSync` 没真正执行,所以 d1 旧普查里没有可扣除的 FenceSync 首阻塞数 |
包报告:`~/w7/notes/p5b/p5b-results/{d1-codex-v1,i1-v1,t2-codex-v1,f1-v1,r1-codex-v1,r2-v1,blit-codex-v1,mip-codex-v1,sync-codex-v1}.md`
### 7.2 主机收尾门与合并普查(`348d22a4``~/w7/p5b-final-host-348d22a4/`
| 车道 | Selected | Passed | Skipped | Failed |
|---|---:|---:|---:|---:|
| unit-linux / unit-push / unit-verify | 1817 × 3 | 1500 / 1782 / 1795 | 317 / 35 / 22 | 0 |
| unit-split | 2132 | 2122 | 10 | 0 |
| gpu-linux-monolith / gpu-push-monolith / gpu-split-monolith | 1148 / 1148 / 1178 | 895 / 953 / 953 | 253 / 195 / 225 | 0 |
| split`integration-split`inproc | 107 | 105 | 2 | 0 |
| verify / audit | 950 / 10 | 804 / 9 | 146 / 1 | 0 |
G1 27,814 符号 0/0/0/0、`.text` 10,806,611 → 10,806,611G5 两族 + pin 自测;生成器 / 纯度检查;G2 / G14 rc=0E1 / E3(a)(精选 4 caserc=0E2 OpenRA 2/2、draw-drop SSIM 0.000036 / 758 records、pull-library 拒绝与库 SHA 恢复一致;smoke 16 core + 12 private。retrace-push **79/79**retrace-verify 在 WSL 重启前完成 4/79,其余 75 条以 SHA-256 钉住的同一 verify 库串行续跑,合并 **79/79**;对账无缺步、无非零退出(`reconciliation-20260916.md`),`complete=true`、exit 0。一次 shell 异常(追加 runner 行触发 `-test-dir: command not found`)保留在原始输出,不冒充测试失败。
合并 inproc 普查(`~/w7/p5b-final-census-348d22a4/`):integration lane 显式 32 MiB**1267 selected = 811 passed / 203 skipped / 62 aborted / 191 failed**;旧 1149 名全部保留、新增 118;旧 432 passes 全保留、零回退;旧 505 abort → 265 passed / 18 skipped / 58 aborted / 164 failed;旧 27 failed → 1 passed / 26 failed。完整 trace 显式 256 MiB(容纳单次 128 MiB 上传,不是默认容量修复):**79 = 72 passed / 6 aborted / 1 failed**(主跑止于 73/79,三轮续跑补齐;`create-indirect` DirectVulkan 在 llvmpipe 上内存膨胀 >60 GiB RSS 被守护杀死,两次复现,记 failed)。7 条未过项首阻塞:`rd12` DirectGLES `Fatal{InitialBytesNotCarried,"resource_respecify"}`、DirectVulkan `Fatal{BarrierTimeout,"Present"}``iris-photon``iris-derivative``create-indirect` 三个 DirectGLES `Fatal{UnmigratedEmulation,"texture-remint-pull"}``iris-bsl-esc-menu-854` DirectGLES `InitialBytesNotCarried``create-indirect` DirectVulkan 内存守护。通过项含 `improved-transparency-minecraft-26.3` DirectGLES SSIM 1.0 / DirectVulkan 0.999914、`iris-iterationrp` DirectVulkan 0.995833、`iris-bsl-esc-menu-854` DirectVulkan 0.998402。逐 trace 见 `joint-codex-v1.md` 的 census 块与 `identity.json` / `counts.json` / `trace-transitions.json`
### 7.3 唯一收官审查与定向修复
审查 `p5b-close-codex-review.md``348d22a4`diff base `37fc4fdb`,只读):**0 blocker / 2 major / 1 minor**。
| 项 | 问题 | 处置 |
|---|---|---|
| Major 1 | user-index span 在段内但 Size 可能短于 Count × IndexSize | `a021e3cc`encoder / decoder / sink 共用 shape/extent gate(单 range、宽度 1/2/4、`Uint64(Count) × IndexSize ≤ Size`),三端短 span 均拒绝、段末 exact-fit 通过;定向 9/9 |
| Major 2 | `ClientWaitSync` 保留 64-bit timeout 但 applied/reply 等待一律 30 s | `82683d4a`:预算 = ceil(timeout ns / 1e6) + 30,000 ms,有限 chunk;普通容量等待 / `FenceWaitServer` 仍 30 sshutdown 可唤醒 |
| Minor 3 | ReadPixels exact-size reply 的未知 status 穿过 production helper | `82683d4a`tight 与 bounce 路径拒绝 status=3`Fatal{ReplyStatusInvalid}` |
定向 `RemoteClientTest` 7/70 ns、1 ns、60 s、UINT64_MAX 预算,`FenceWaitServer`、shutdown、未知状态)。合并后 quickgate 里 split 单元车道仅有的 2 个失败(`PipeWireCodecTest.UserIndexSpan*`)是测试日志捕获缺陷(库按进程截断日志,fork 子进程增量读读空),`7cb29d46` 修复后 3/3。本阶段不再做第二轮全门或审查;原始全门源头仍为 `348d22a4`,三项修复只以定向证据补齐。
### 7.4 Redmi 出口与四臂 A/B`82683d4a`APK `p5bcodex2`
Redmi `2f7cbe2e`,证据根 `MobileGL/.trace-work/p5b-redmi/p5bcodex2/2f7cbe2e/`;全部组合显式 `MOBILEGL_IPC_STAGE_MB=256`。**钉频口径变更**2026-09-11 的厂商 GPU 上限(1050 MHz)已消失,本次 deterministic pin 为 **1100 MHz**;与 1050 MHz 时代的活动不可比钟频,只有同场四臂配对可比。
**正确性 8/8**`improved-transparency-minecraft-26.3``minecraft-1.21.4-in-world`GLES SSIM 0.999995)、`minecraft-1.21.4-fabric-sodium-in-world``minecraft-1.21.4-fabric-iris-bsl-in-world` × 双后端,inproc split 臂,逐组钉频取证 + PNG / SSIM 阈值 + inproc + apply 线程 + 正 wire 记录三证,skip 即失败。**四条 A/B trace 首次在 Redmi 上以独立 apply 线程渲染——P5b 出口判据达成。**
**四臂 A/Bbarrier tax 首测)**:32 组中 24 组带 200 帧尾验证全绿;三次重复取 wall-time 均值最低者、尾 200 帧(`ab-tables.md`)。逐线程 CPU p50
| trace | 后端 | pushpull | **barrier taxsplitpush** | barrier tax 帧 p50 |
|---|---|---:|---:|---:|
| improved-transparency-26.3 | DirectGLES | +15.6% | **+10.3%** | +0.1% |
| improved-transparency-26.3 | DirectVulkan | +8.8% | **+13.1%** | +13.3% |
| minecraft-1.21.4-in-world | DirectGLES | +21.4% | **+18.2%** | +0.2% |
| minecraft-1.21.4-in-world | DirectVulkan | +11.8% | **+17.9%** | +19.7% |
| minecraft-1.21.4-fabric-sodium | DirectGLES | +10.9% | **+5.9%** | 0.1% |
| minecraft-1.21.4-fabric-sodium | DirectVulkan | +7.6% | **+8.3%** | +4.3% |
splitctlpush 全部在 ±1.6% 内(增量来自 inproc 传输与 barrier,不是 APK / 构建差);p99 同向放大(sodium DirectVulkan 帧 p99 +107.7% 为离群尾帧)。inproc 臂 peak RSS 389 MiB 2.5 GiB,全角色映射 560.5 MiB(256 MiB × 角色视图是虚拟映射容量,不是 RSS 增量)。
**fixture 受限的 8 组**`iris-bsl-in-world` 只有 123 个 benchmark 帧,低于 200 帧尾规则,四臂 × 双后端验证全部失败(pull 同失败,是 fixture 上限不是回归);123 帧完整序列按同法折算成补充表 `ab-tables-bsl-123frame-supplement.md`barrier tax CPU p50 DirectGLES **+7.1%**、DirectVulkan **+9.1%**,不混入上表。性能仍只记录、不作阻塞门。