Explore subagent (very thorough) で brush (Burn/CubeCL) と splat-rs (Metal 直) の dispatch architecture を実装まで降りて比較。<strong>4.7× 速度差は architectural (command buffer batching) で kernel-level ではない</strong> と 95% confidence で判明。brush は <code>launch_unchecked()</code> + Burn 内部 batching で per-iter 5-7 awaits → ~5 actual GPU flushes、splat-rs は per kernel 毎に <code>wait_until_completed()</code> で 10-50 flushes。84ms / 18ms = 4.67× は計算と一致 (17ms GPU compute + ~25ms wait overhead = ~2.5ms × 10 wait)。<strong>これは Phase F 5 連続 falsification (emit SIMD / f16 / radix GPU prefix / refine GPU / target cache) への統一的説明</strong>: kernel-level optimization が効かなかったのは bottleneck がそこではなかったから。Top 3 hypotheses (batching 50% / async readback 15% / kernel fusion 5-10%)、最 ROI 高い backport は async readback (1-2 週、+3-5% wallclock) だが、F.3 falsification calibration 踏まえ実装前 skeptical 評価必須。
launch_unchecked() async dispatch + 内部 command buffer batching で per-iter 5-7 explicit awaits → ~5 actual GPU flushes。一方 splat-rs は per kernel 毎に cmd.wait_until_completed() で 10-50 GPU flushes。計算: 17ms GPU compute + ~25ms wait overhead (~2.5ms/wait × ~10) = ~42ms、実測 84ms とは ~2× ずれあるが (subagent quantification の不確実性)、order-of-magnitude は一致。これは Phase F 5 連続 falsification への統一的構造説明: kernel-level micro-opt (SIMD reduction / f16 accumulator / radix GPU prefix / TBDR imageblock 等) が効かなかったのは bottleneck が per-kernel compute ではなく dispatch synchronization architecture だったから。**主仮説 ranking** (subagent assessment): (1) command buffer batching (50% of gap、移植 VERY HIGH cost 6-10 週)、(2) async readback (15%、MEDIUM cost 1-2 週、+3-5% expected)、(3) kernel fusion (5-10%、EXTREME cost)。**ただし subagent quantification は overestimate 傾向あり** (Phase F.3 で「removed wait was overlapping with CPU work, not idle」発覚と矛盾、wait は free な場合もある)。卒論 narrative としては structural explanation として極めて価値高い、§5.4 negative findings 章で「Phase F 全 kernel-level 改善試行は architectural mismatch だった」統一的 paragraph 候補。brush per-iter 18ms vs splat-rs per-iter 84ms (4.67×) の真因を Explore subagent (very thorough) で audit。真因は kernel-level ではなく architectural: brush は Burn/CubeCL backend の async dispatch + internal command buffer batching で per-iter ~5 actual GPU flushes、splat-rs は per kernel 毎に cmd.wait_until_completed() で 10-50 flushes。これは Phase F 5 連続 falsification への統一的構造説明: kernel-level 改善が効かなかったのは bottleneck が dispatch sync architecture だったから。
4.7× per-iter 差は kernel-level ではなく architectural。brush は launch_unchecked() + Burn 内部 batching で per-iter 5-7 explicit awaits → ~5 actual GPU flushes、splat-rs は per kernel 毎の wait_until_completed() で 10-50 flushes。これは Phase E refine GPU 化 / target_upload cache / F.1 emit_simd / F.2 f16 / F.3 radix GPU prefix の 5 連続 falsification に対する統一的説明: 全部 kernel-level optimization で、architectural mismatch (per-kernel sync vs batched async) を fix できなかった。卒論 §5.4 narrative の核心: 「Apple Silicon native Metal 直叩き = kernel-level 最適化の自由度はあるが、dispatch architecture の trade-off (per-kernel sync vs batched async) で wgpu→Burn/CubeCL backend に劣後」、第 2 軸 (wgpu 抽象コスト) は再 framing 必須 — wgpu 自体は遅くないが Burn 経由の dispatch batching が圧倒的に効く。
project_forward_kernel / project_visible_kernel / map_gaussians_kernel / rasterize_kernel 全て launch_unchecked() (async Task 返却、即座に next dispatch chain)。explicit await は TransactionOps::tr_execute() 1 回 (multiple buffer atomic read、render.rs:150-168)optimizer.step() ×3 (transforms / sh / opacity)、Burn AdamScaled 実装で内部 fused (推定 ~3 → ~1 actual flushes)launch_unchecked() 即返却 + 依存先 kernel が .into_data_async().await で待つ pipeline parallelism| step | dispatch | wait_until_completed | code location |
|---|---|---|---|
| project_soa | 1 cmd buf | 1 | project.rs:148-207 [WAIT 1] |
| emit_pairs | 1 cmd buf | 1 | tile_bin.rs:199-221 [WAIT 2] |
| radix_sort (GPU prefix、F.3 default) | GPU scan in 1 cmd | 1 final | tile_bin.rs:336-396 [WAIT 3] |
| radix_sort (legacy CPU scan) | 16 cmd buf | 16 | tile_bin.rs:398-481 [WAITS 4-19] |
| extract_offsets | 1 cmd buf | 1 | tile_bin.rs:544-557 [WAIT] |
| rasterize forward | 1 cmd buf | 1 | rasterize.rs:153-169 [WAIT] |
| loss eval | 1 cmd buf | 1 | loss.rs |
| rasterize backward | 1 cmd buf | 1 | rasterize.rs:277-368 |
| project_backwards | 1 cmd buf | 1 | project.rs:238-285 |
| Adam (5 components) | 5 cmd buf | 5 | adam.rs:124-200 |
| # | 仮説 | subagent confidence | gap 寄与 | 移植 cost | PSNR risk | F.3 calibration 補正 |
|---|---|---|---|---|---|---|
| 1 | **Command buffer batching (Burn/CubeCL)** | **95%** | ~50% (2.35×) | VERY HIGH (6-10 週) | MED | **confidence 維持** — F.3 で「wait は完全 idle ではない」発覚も、batching 自体は別の structural pattern |
| 2 | Deferred async readback | MED-HIGH 78% | ~15% (0.7×) | MED (1-2 週) | LOW | **partial overestimate**: F.3 が「removed wait was overlapping with CPU work」を直接実証、async readback の純 gain は 1-2% 圏かもしれず |
| 3 | Kernel fusion (Burn compile) | MED 65% | ~5-10% (0.2-0.5×) | EXTREME (8-12 週) | MED | 現実的不可能 (CubeCL port 必須)、卒論 narrative のみ |
| candidate | expected wallclock | cost | PSNR risk | F.3 calibration 補正後 ROI |
|---|---|---|---|---|
| **GPU Prefix Scan (Phase F.3)** | 実現済 -0% (regression) | DONE | NONE | **falsified** (Metal hazard tracker fence overhead 発覚) |
| **Async readback chains** | +3-5% (subagent) / +1-3% (hedged) | MEDIUM 1-2 週 | LOW | **prototype gate**: 1-2 日 PoC で実 gain 計測、不明確なら drop |
| **Manual cmd buffer batching** | +10-15% (subagent) / +3-8% (hedged) | HIGH 2-4 週 | MED | **high uncertainty**: kernel 間依存 graph 解析必須、F.3 fence trap 再発 risk |
| **CubeCL/Burn port** | +50-70% (subagent) | EXTREME 6-10 週 | MED-HIGH | **実行不可**: L1 独立性 (research-plan.md 2026-04-24 pivot) を放棄、卒論 narrative 大改変 |
wait_until_completed vs batched async)cmd_creation / encoding / commit / wait を分けて計測、wait が dominant か確認 (subagent 仮説検証)m4-brush-bench (brush 9m08s / splat 26m32s の M4 直接比較)、p1-d-stage2-30k-results (Phase D 41m54s 確定)p1-e-refine-gpu-smoke (refine GPU 化)、p1-axis1-target-cache (cache async overlap)、p1-axis1-phase-f1-emit-simd-falsified (emit SIMD + f16)、p1-axis1-phase-f3-radix-gpu-prefix-falsified (radix GPU prefix)p1-axis1-metal-opt-audit (5 候補 + Tier 分類)chapter-5-4-negative-findings (axis 1 audit predictions section + G.2 structural explanation)