松田研究室
FindingID: p1-axis1-phase-g2-brush-dispatch-architecture
Status: stable / task P1 axis 1 Phase G.2
← Findings Index
P1 axis 1 · Phase G.2 · structural finding · 4.7× gap explained

Phase G.2 brush 4.7× per-iter 速度差の真因 — command buffer batching、Phase F 全 kernel-level 改善試行への統一的構造説明

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 評価必須。

mixedrank: highstructural-explanation第 1 軸第 2 軸p1-axis1phase-gbrush-comparisondispatch-architecturecommand-buffer-batchingstructural-findingburn-cubeclmetal-direct
Δ PSNR
N/A (audit)
Δ Wallclock
0% (audit) / estimated +3-5% if async readback backport (要 prototype 検証)
Impact
Explore subagent (Sonnet very thorough) で brush 18ms/iter vs splat-rs 84ms/iter (4.67×) の真因を architectural 差で構造特定。brush は Burn/CubeCL backend の 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 候補。
01

本文

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 だったから。

Headline (structural explanation for Phase F)

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 が圧倒的に効く

1. brush dispatch architecture (Burn/CubeCL backend、render.rs/train.rs 読解)

  1. Forward pass: 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)
  2. Backward: CubeCL async Burn ops、autodiff 境界で defer sync。explicit awaits ~1-2
  3. Optimizer (train.rs:286-303): optimizer.step() ×3 (transforms / sh / opacity)、Burn AdamScaled 実装で内部 fused (推定 ~3 → ~1 actual flushes)
  4. Total per-iteration: ~5-7 explicit awaits、Burn batching で ~5 actual GPU flushes
  5. Key pattern: launch_unchecked() 即返却 + 依存先 kernel が .into_data_async().await で待つ pipeline parallelism

2. splat-rs dispatch architecture (Metal 直、trainer.rs 読解)

stepdispatchwait_until_completedcode location
project_soa1 cmd buf1project.rs:148-207 [WAIT 1]
emit_pairs1 cmd buf1tile_bin.rs:199-221 [WAIT 2]
radix_sort (GPU prefix、F.3 default)GPU scan in 1 cmd1 finaltile_bin.rs:336-396 [WAIT 3]
radix_sort (legacy CPU scan)16 cmd buf16tile_bin.rs:398-481 [WAITS 4-19]
extract_offsets1 cmd buf1tile_bin.rs:544-557 [WAIT]
rasterize forward1 cmd buf1rasterize.rs:153-169 [WAIT]
loss eval1 cmd buf1loss.rs
rasterize backward1 cmd buf1rasterize.rs:277-368
project_backwards1 cmd buf1project.rs:238-285
Adam (5 components)5 cmd buf5adam.rs:124-200
**Total per-iteration**: GPU prefix scan path (F.3) で ~10 explicit waits、legacy CPU scan path で ~40+ waits。brush の ~5 flushes と比較で 2-8× の sync overhead。各 wait の固定 overhead ~2.5ms (subagent assessment、ただし F.3 calibration では partial overlap で実 cost ~1-2ms と推定) × 10 waits = ~10-25ms overhead = 4.7× gap の 50%+ を説明。

3. 真因仮説 ranking (subagent assessment、Phase F calibration で hedge)

#仮説subagent confidencegap 寄与移植 costPSNR riskF.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
2Deferred async readbackMED-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% 圏かもしれず
3Kernel fusion (Burn compile)MED 65%~5-10% (0.2-0.5×)EXTREME (8-12 週)MED現実的不可能 (CubeCL port 必須)、卒論 narrative のみ
**hypothesis #1 (batching) が dominant**: brush の 4.7× 速度優位の半分以上を説明。但し移植 cost extreme (Burn 採用 = L1 独立性放棄)。**hypothesis #2 (async readback) は prototype 検証必須**: subagent +3-5% 予測だが F.3 calibration data (wait overlap CPU work) を踏まえ +1-3% に hedge、prototype 1-2 日で確認可能。

4. backport candidate (cost × benefit × risk)

candidateexpected wallclockcostPSNR riskF.3 calibration 補正後 ROI
**GPU Prefix Scan (Phase F.3)**実現済 -0% (regression)DONENONE**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 大改変
Phase F.3 calibration data 踏まえると、subagent assessment の +3-5% / +10-15% は overestimate 傾向。最 actionable は async readback prototype (1-2 日 PoC、+1-3% 実 gain か検証)、不明確なら drop して thesis narrative に focus。

5. 卒論 §5.4 narrative 価値 (structural finding)

  • Phase F 5 連続 falsification への統一的構造説明: kernel-level optimization が効かなかったのは bottleneck が dispatch sync architecture だったから (per-kernel wait_until_completed vs batched async)
  • axis 2 narrative 再 framing: 「wgpu 抽象は遅い」予想は false (m4-brush-bench で確定済)、Burn/CubeCL の dispatch batching が圧倒的に効く。「Metal 直 = 最速」の常識を覆す
  • axis 1 native impl の honest reporting: 我々の splat-rs Metal 直は kernel-level 自由度はあるが、dispatch architecture の trade-off で brush に -77% wallclock 劣後。PSNR は M5 で +0.63 dB 上回り、quality-speed Pareto 上の異なる point
  • §6 future work: 「Metal 直 + async readback / cmd buffer batching」を non-Burn path として明示、また「Burn 採用 (P2 fork) を pragmatic 後継路線として認める」future work
  • 方法論 paragraph: 「kernel-level audit (p1-axis1-metal-opt-audit) → 5 連続 falsification → architectural audit (Phase G.2) で根本特定」の honest iteration、bottoms-up vs top-down audit の対比

6. 次のアクション

  1. G.1 (early stop) 完了待ち: 既進行中 Lego stop_iter=15000 結果、PSNR ≥ 35 dB なら 7 scene chain で 50% wallclock 節約 (高確度)
  2. G.3 (SH progressive) 着手: 既 plan、deterministic compute 削減で kernel-level だが SH coeff 数 3→48 の単純算術。Phase F とは違う mechanism family、advisor 評 -8-12% wallclock
  3. G.6 (option) async readback prototype: 1-2 日 PoC、emit_pairs / radix の readback を completion handler 化、ts_fwd_emit_pairs 単体で gain 計測。+1-3% なら採用、ROI 不明確なら drop
  4. G.7 (option) Burn 採用 (P2 fork) 検討: 卒論 axis 2 narrative の 大改変、6-10 週 cost。本 G.2 finding は P2 への argument を強化するが、即時実行は recommend しない
  5. 卒論 §5.4 統合: G.2 finding を 「structural explanation」として §5.4 negative findings 章に追加、Phase F 5 連続 falsification + G.2 architectural audit の組み合わせで強い narrative

7. instrumentation 推奨 (subagent 追加 suggestion)

  • per-dispatch timing instrumentation: cmd_creation / encoding / commit / wait を分けて計測、wait が dominant か確認 (subagent 仮説検証)
  • Xcode Instruments Metal System Trace: brush vs splat-rs 同時計測で GPU Utilization (brush 60-70% / splat 30-40% 予想) と Command Buffer Submission Frequency (brush 2-3/iter / splat 12-15/iter 予想) の実測値
  • kernel launch latency: cmd.commit() から first GPU thread wakeup までの時間 (brush 0.5-1ms 予想、splat 2-3ms 予想)、これが repeated flushes で蓄積するか確認

8. 関連

  • audit baseline: m4-brush-bench (brush 9m08s / splat 26m32s の M4 直接比較)、p1-d-stage2-30k-results (Phase D 41m54s 確定)
  • Phase F 5 連続 falsification: 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)
  • axis 1 audit (本 G.2 で structural explanation 付与): p1-axis1-metal-opt-audit (5 候補 + Tier 分類)
  • 卒論統合候補: chapter-5-4-negative-findings (axis 1 audit predictions section + G.2 structural explanation)
03

関連 finding

© 2026 大竹律輝 — 松田研究室