松田研究室
FindingID: p3-c2-bubble-attribution
Status: stable / task C2: 12.5k の残差 bubble 帰属計測と分析
← Findings Index
2026-09 ゼミ milestones · C2 実測 · 残差 bubble 帰属 (host-late 支配)

C2 実測 — 残差 bubble は host-late 支配 (7.2〜8.1s)、refine tick drain は A7 で半減済み (3.0〜3.8s)。handoff は定常帯で headroom ほぼ無し

`p3-kernel-share-post-s3.toml` §8 が実装した `gpu_gap_report()` を 12.5k full run (M4 radix simd_ballot + A7 refine 3-pass 削減、default 込みの現行スタック) で初めて実測した。<code>reliable=true dropped=0 kernel_invalid=0 sum/union=1.000000x</code>、<code>Σcb_gap=11.085s</code> は sync-tax 全量 11.129s の <strong>99.6%</strong> を説明する。band 別 <code>p50×n</code> (通常 iteration の robust 推定、refine tick という外れ値に不感) と <code>mean×n</code> (全量) の差分から、<strong>残差 (通常境界の bubble) は 7.2〜8.1s (wall 124.75s の 5.8〜6.5%)、refine tick drain は 3.0〜3.8s (2.4〜3.1%)</strong> とブラケットで分解した。恒等式 <code>cb_gap=−host_lead+drvproc+handoff</code> を中央値ベースで見ると、定常帯 (band2〜4) の <code>handoff</code> 中央値は <strong>0.047〜0.153ms</strong> と極小で <code>cb_gap</code> 中央値 (0.297〜0.307ms) のほとんどは <code>host_lead</code> の負側 (中央値 −0.24〜−0.25ms) が説明する — <strong>残差の主因は driver/GPU キュー待ちではなく host-late</strong>。<code>ts_chain_commit_wait</code> (backward CB, gpu 6.379ms/call) と <code>ts_fwd_chain_commit_wait</code> (forward CB, gpu 2.000ms/call) の非対称から、host work (waits を除く総計 23.387s/12500=1.871ms/iter) は forward CB の 2.000ms shadow をほぼ埋め切っており (fill率 ~93.6%)、<strong>残差は「2.00ms の狭い shadow からのはみ出し」がほぼ全て</strong>という機構仮説を提示する。

mixedrank: highresidual-is-host-late-dominated / handoff-headroom-thin / refine-drain-already-halved-by-a7第 1 軸第 3 軸c2gap-reportcb-gaphost-leaddrvprochandoffresidual-bubblerefine-drainpost-m4-a7legomeasurement-only
Δ PSNR
n=1 self-eval: 36.068 dB (100 views)。C2 は測定目的の run で PSNR gate 対象ではないが、p3-final-stack の n=3 mean (36.219 dB) からの乖離は n=1 ノイズ帯として妥当な範囲
Δ Wallclock
train elapsed 124.75s (n=1)。p3-final-stack n=3 mean 124.393s (σ0.756%) の guard 内 — profile=true + gap report 計装のオーバーヘッドは計測可能な歪みを生んでいない、と読める
Impact
`p3-kernel-share-post-s3.toml` §4/§8 の宿題 (「残差は既存計装では分解不能、実装後も 12.5k 実測がまだ無い」) を、`2026-08-30-c2-12500-depth2-prof.toml` (M4+A7 default 込み、S3 gate arm B と [backend] bit-exact) の 1 run で埋めた。reliable=true / dropped=0 / kernel_invalid=0 / sum/union=1.000000x — 信頼性ゲート健全、全列使用可。wall 124.75s / busy 113.627s (91.1%) / sync-tax 11.126〜11.129s は `p3-final-stack` の n=3 mean (124.393s, σ0.756%) の guard 内 (n=1 の点推定として妥当)。Σcb_gap=11.085s が sync-tax 全量の 99.6% を説明し、`p50×n` (band 別合計 7.244s) と `mean×n` (11.081s) の差 3.837s を refine tick 由来の外れ値と読むと、残差 (通常境界) 7.2〜8.1s (5.8〜6.5%) / refine tick drain 3.0〜3.8s (2.4〜3.1%) にブラケットできる。refine 側は `ts_refine`(2.869s)+`ts_opacity_decay`(0.185s)=3.054s の独立 host 実測が下限とほぼ一致し、クロスチェックが成立した。旧 3 分解 (refine 6.26s / encode(B) 3.41s / 残差 4.54s、旧 sync-tax 全量 14.206s) との整合: 旧「残差」+「encode(B)」= 4.54+3.41=7.95s ≈ 新「通常境界」7.24s (wall が 151.70→124.75s に縮んだ分を割り引けば近い) — 旧 encode(B) バケツは独立した加算成分ではなく、非重複だった encode コストが host-late として `cb_gap` に同じ形で現れていたと判明し、旧 3 分解を「refine drain / それ以外 (通常境界)」の 2 分解へ訂正する形になった。帰属の結論: 通常境界の bubble は host-late が支配的、driver 処理 (`drvproc`) と GPU キュー待ち (`handoff`) は定常帯で中央値がほぼゼロ (headroom 薄い) — task が例示した「handoff → CB 統合」は主因ではないと実測が明示的に否定した。
01

本文

`p3-kernel-share-post-s3.toml` §8 は C2 計装 (`CbInterval` / `gpu_gap_report()` / `print_gap_report()`) を実装したが、1000 iter smoke (splat 6.9k、refine コスト無視できる regime) のみで、12.5k 本番 regime (400k splats、M4/A7 default 込み) での実測は「main が実行すべきコマンド」として申し送りに残っていた。本 finding はその実測を行い、旧 (pre-M4/A7) の「残差 4.54s / refine drain 6.26s」という推定値を、実装済み計装による実測値で置き換える。

1. 健全性フラグと repro

flag値判定
`reliable`true全列 (`cb_gap`/`drvproc`/`handoff`/`host_lead`) 信頼可
`dropped`0GPU timeline に穴なし — `cb_gap` の blast radius 対象外 (無条件で健全)
`kernel_invalid`0`drvproc`/`handoff`/`host_lead` も無傷 (該当した場合のみ縮小するが今回は 0 件)
`sum/union`1.000000xCB 間 overlap なし、単一 queue 上で GPU 区間が交わらないという前提が成立
`host_ahead_frac`49.5%host が GPU 先行だった CB は全体の 49.5% (= 50.5% は host が遅れて始まった、後述§4 で機構を説明)
band 境界の epoch driftなし`iter [1,3125]/[3126,6250]/[6251,9375]/[9376,12500]` の n 合計 6251+6250+6250+6249=25000=`cb_gap`の n と一致、§8 未解決点(4) の懸念は解消 (epoch_lo=1 で clean)
reconcile (Σcb_gap vs sync-tax全量)11.085s / 11.129s = 99.6%sync-tax から host encode を引く必要はないという §4.1 の規約どおり (二重控除なし)
wall (train elapsed)124.75s`p3-final-stack` n=3 mean 124.393s (σ0.756%) の guard 内 — profile=true+gap report のオーバーヘッドは無視できる
config
`splat/configs/2026-08-30-c2-12500-depth2-prof.toml` ([backend] は `2026-08-16-s3-12500-depth2-prof.toml` と bit-exact、[experiment] メタデータのみ差し替え)
flag 実測確認
run log の `[backend] BackendConfig {...}` 行で `radix_scatter: SimdBallot` (M4) / `refine_scratch_persist: true` / `refine_direct_write: true` (A7) を確認 — post-M4/A7 の現行 default スタックで走っていることの直接証拠
run
1 run のみ (GPU 専有、他 run なし、n=3 化はしていない — 本 finding の値は n=1 の点推定)。commit `2e16af0` (main HEAD) の release binary
wallclock / busy / sync-tax (final)
wall 124.750〜124.754s / busy 113.627s (91.1%) / sync-tax 11.123〜11.129s (計測タイミングの僅かなずれで 3 箇所の printout に ±6ms の差、本文中は reconcile 行の 11.129s を採用)

2. `cb_gap` の分布 — band 別 mean/p50/p90/max、通常分と refine tick 分の分離

band (iter)nmean(ms)p50(ms)p90(ms)max(ms)mean×n(s)p50×n(s)
[1, 3125]62510.5110.2561.16842.7283.1941.600
[3126, 6250]62500.4570.2970.90448.0502.8561.856
[6251, 9375]62500.3940.3070.46948.6002.4621.919
[9376, 12500]62490.4110.2990.49944.9242.5681.868
**overall****25000****0.443****0.278****0.860****48.600****11.081 (Σ=11.085)****6.950 (band和 7.244)**
band 1 の突出 (excess 1.594s) は refine ではなく arena 成長 — 誤帰属注意

band 別 mean×n − p50×n (= 外れ値=大 gap の寄与) は band1 1.594s / band2 1.000s / band3 0.544s / band4 0.700s。band1 が最大に見えるが、refine tick は `refine.every=100`・`start_iter=500` のため band1 (iter 1〜3125) には約 26 tick しか含まれず、band2〜4 (各 ~31 tick) より少ない — band1 の突出は run 冒頭の `arena overflow at iter 1, growing to 1480454 and retrying` (log 先頭) と splat 数の急成長 (5207→初期数十万規模まで iter 1〜数千で急増) による host/driver ワークロードの過渡的な変動であり、refine 由来ではない。band1 を除いた band2〜4 の excess (1.000+0.544+0.700=2.244s) と band1 込み全体 (3.837s) を見比べ、refine tick 由来の外れ値は band2〜4 の 2.24s + band1 の refine 分 (tick 数比で按分すると ~0.6s) ≈ 2.8〜3.0s 程度が構造的な下限、band1 の arena-growth 分 (~1.0s) を除いた残りが真の refine 寄与と見るのが妥当 — これが §3 で `ts_refine`+`ts_opacity_decay` の独立 host 実測 (3.054s) とほぼ一致することのクロスチェック根拠になる。

3. `drvproc` / `handoff` / `host_lead` — band 別分布、中央値ベースの寄与ランキング

band (iter)metricnmean(ms)p50(ms)p90(ms)max(ms)
[1, 3125]drvproc62520.0430.0260.0566.603
[1, 3125]handoff62521.6950.5695.1266.657
[1, 3125]host_lead62511.225**−0.200**5.1446.683
[3126, 6250]drvproc62500.0760.0260.1453.226
[3126, 6250]handoff62503.375**0.153**7.2548.984
[3126, 6250]host_lead62502.994**−0.240**7.2658.995
[6251, 9375]drvproc62500.0960.0270.1734.098
[6251, 9375]handoff62503.650**0.047**7.7319.128
[6251, 9375]host_lead62503.352**−0.253**7.7409.137
[9376, 12500]drvproc62490.1030.0290.1824.188
[9376, 12500]handoff62493.719**0.056**7.8849.130
[9376, 12500]host_lead62493.411**−0.247**7.8959.134
**overall****drvproc****25001****0.079****0.027****0.155****6.603**
**overall****handoff****25001****3.110****0.489****7.624****9.130**
**overall****host_lead****25000****2.745****−0.220****7.635****9.137**
定常帯 (band2〜4) の中央値ベースでは host-late が支配的、`handoff` の headroom は薄い — 足してはいけない組み合わせ規約に従い mean は wall 比較に使わない

`drvproc`/`handoff`/`host_lead` の mean×n は band を通して数十秒規模 (例: overall handoff mean×n ≈ 77.75s) になり、明らかに sync-tax (11.13s) より大きい — これは §4.1 が明記する「足してはいけない組み合わせ」そのもの (mean は CB ごとの正負が巨大に打ち消し合う量であり、時間軸として加算すると意味を失う)。恒等式 cb_gap=−host_lead+drvproc+handoff は各 CB 個別値でも band 別 mean でもほぼ一致することを確認した (例 band4: −3.411+0.103+3.719=0.411 ≈ 実測 cb_gap mean 0.411) — handoff (mean) と host_lead (mean) はほぼ打ち消し合い、cb_gap (mean) はその小さな差分として残る。定常帯の中央値で見ると構図がはっきりする: band2〜4 の handoff 中央値は 0.047〜0.153ms と極小 (=driver がキューで待たされる時間は typical には ほぼゼロ)、一方 host_lead 中央値は −0.240〜−0.253ms と一貫して負 (=host は typical には次 CB の driver 処理を GPU 完了より後にしか始められていない)、drvproc 中央値は 0.026〜0.029ms とさらに小さい。cb_gap 中央値 (0.297〜0.307ms) の内訳を大まかな寄与比で言うと host-late (≈80%) ≫ drvproc (≈10%) ≈ handoff (≈10〜15%) — task が例示した施策候補「handoff → CB 統合」は、定常帯では handoff にほとんど headroom が残っていないため主因ではないことが実測で判明した (中央値どうしの加算は近似であり thousand分の1msオーダーの丸め誤差を含むが、ランキングを覆すほどの誤差ではない)。

4. 機構仮説 — forward CB の 2.00ms shadow が host work でほぼ埋まっている

backward CB の GPU shadow
`ts_chain_commit_wait` gpu_ms/call = 79,736.871ms / 12,500 = **6.379ms/call**
forward CB の GPU shadow
`ts_fwd_chain_commit_wait` gpu_ms/call = 25,001.586ms / 12,501 = **2.000ms/call**
host work (waits を除く全 label 合計)
TOTAL(sum) 116.125s − ts_chain_commit_wait(host) 81.707s − ts_fwd_chain_commit_wait(host) 11.031s = **23.387s / 12,500 = 1.871ms/iter**
forward shadow の fill 率
1.871 / 2.000 ≈ **93.6%** — depth2 pipelining は host work のほとんどを forward CB の GPU 実行の影に隠せているが、狭い 2.00ms 窓に対しほぼ余裕なく詰まっている
host_ahead_frac=49.5% との整合
backward CB (6.379ms) の後に来る境界では driver が大きく先行できる (host_lead 大きく正、handoff も大きい = 「余裕がある」境界)。forward CB (2.000ms) の後に来る境界では host work が 2.00ms を僅かに超えることが半々の確率で起き、超えた分がそのまま cb_gap に現れる (host_lead 中央値が僅かに負、handoff 中央値が僅かに正 = 「余裕が薄い」境界)。2 種類の CB が交互に来るため、handoff/host_lead の分布は band4 の mean(3.7/3.4) vs p50(0.06/-0.25) のように<strong>二峰的</strong>になる — task の想定していた単一分布ではなく、この 2 CB 交互構造が背景にある

5. 残差 (通常境界) と refine tick drain のブラケット、旧 3 分解との整合

区分推定範囲wall 比根拠
残差 (通常境界の bubble)**7.2〜8.1s****5.8〜6.5%**下限=band別`p50×n`合計 7.244s、上限=`mean×n`合計 11.081s − 独立 host 実測の refine 下限 3.054s ≈ 8.03s
refine tick drain**3.0〜3.8s****2.4〜3.1%**下限=`ts_refine`(2.869s)+`ts_opacity_decay`(0.185s)の独立 host 実測=3.054s、上限=`mean×n合計 11.081s − p50×n合計 7.244s`=3.837s
(参考) sync-tax 全量11.13s8.9%`[gpu]` summary line / reconcile 行
旧 3 分解 (refine 6.26s / encode(B) 3.41s / 残差 4.54s) との整合 — encode(B) は独立成分ではなく host-late として cb_gap に混入していた

`p3-kernel-share-post-s3.toml` §4 が記録した旧値 (pre-M4/A7、sync-tax 全量 14.206s) は refine drain 6.26s (44%) / encode(B) 3.41s (24%) / 残差 4.54s (32%) の 3 分解だった。本 finding の新 2 分解 (残差 7.2〜8.1s + refine 3.0〜3.8s、sync-tax 全量 11.13s) と突き合わせると、旧「残差」+「encode(B)」= 4.54+3.41 = 7.95s は新「残差 (通常境界)」7.24s (band別`p50×n`下限) とほぼ同じオーダー(wall が M4/A7 で 151.70→124.75s に縮小した分を比例で割り引けば 7.95×(124.75/151.70)≈6.5s とさらに近づく)。これは encode(B) が sync-tax の独立した加算成分ではなく、depth2 で重なりきらなかった encode コストが `host_lead` の負側 (host-late) として `cb_gap` に同じ形で現れていた、ということを意味する — §4.1 の「sync-tax から host encode コストを引く必要はない」という規約は、まさにこの吸収関係の裏付けとして再確認された。旧「refine drain 6.26s」と新「refine 3.0〜3.8s」の差 (-39%〜-52%) は A7 (refine 3-pass 削減、default flip) が既に refine tick drain を大きく削っていたことの直接証拠であり、`p3-refine-3pass` finding の host コスト削減主張と整合する。

6. 施策提案 (期待 Δ 付き)

#対象施策期待 Δ (wallclock)制約 / 根拠
1残差 (host-late 支配)post-backward の host 仕事 (`ts_refine_accumulate` 407µs/iter・grad readback 等) を forward CB の 2.00ms shadow ではなく backward CB の 6.38ms shadow 側にエンコード順序を並べ替えて隠す**-3〜-5%**ceiling は host-late bucket 全量 (5.8〜6.5%) だが、`refine_accumulate` は backward N の grad を消費し backward N+1 が同じバッファを上書きするため、そのままでは競合する — grad の double-buffer 化が必要 (depth3 pipelining と同じコストクラスの変更)。ceiling ではなく現実的な値として -3〜-5% を見積もる。**実装 + 12.5k n=3 gate 実施済み、Δ +5.63% (逆符号) で棄却確定 — 詳細 `p3-s4-host-shadow` §8**
2残差 (host-late 支配)depth 3 pipelining (scratch 世代をもう 1 段増やす)**-2〜-4%**#1 と同じ的を狙うがより鈍い代わりに実装が単純。追加の scratch 世代分メモリコスト増、depth2 default flip (`p2-s3-iteration-pipelining`) と同じ検証手順 (12.5k A/B n=3、PSNR guard) が必要
3残差 (drvproc)dispatch 数削減 (kernel 統合等)**-0.5〜-1.5%**drvproc は定常帯で中央値 0.026〜0.029ms とほぼ横ばいだが mean は 0.043→0.103ms と band を追うごとに増加 — 増加は tail (max 3.2〜6.6ms) にのみ表れ中央値は動いていないため、'dispatch 数削減' が効くのは tail のみで通常ケースへの寄与は薄い。3 案中最も ceiling が低く優先度は最後
4 (refine)refine tick drainrefine tick の host 仕事 (accumulate/opacity_decay) を in-flight forward CB の GPU 実行と重ねる non-draining refine 化**-1.5〜-2.5%**ceiling は refine bracket 全量 (2.4〜3.1%)。`sync_iters=121/12500` = tick ごとに 1 回の full drain が発生している構造そのものを崩す必要があり、実装コストは #1/#2 より高い
5 (refine)refine tick drain`refine.every` を 100→200 に緩め tick 頻度を半減**-1.2〜-1.5%**A7 で refine tick drain は既に旧 6.26s→3.0〜3.8s まで半減済みのため、残りの headroom も比例して小さい。密度化スケジュールが変わるため PSNR gate 必須 (free ではない、と明記して提案)。**実装不要 (config のみ) + 12.5k n=3 gate 実施済み、PSNR Δ -0.421dB で guard (≥-0.05dB) を約 8.4 倍超過し棄却確定。wallclock は Δ -25.6% と大幅短縮したが drain 削減 (sync_iters 121→61、期待帯どおり寄与) ではなく densification 予算削減 (最終 splat 数 -35%) の副作用が主因 — 詳細 `p3-refine-every-200`**

7. 規約 / 次段への含意

  • **C2 の宿題 (`p3-kernel-share-post-s3.toml` §8 未解決点(1)) を解消** — 12.5k 本番 regime (M4+A7 default 込み) での `gpu_gap_report` 実測が完了。§C2 に本 finding への参照を追記した
  • **残差 bubble の主因は host-late、handoff (CB 統合) は主因ではない** — task が候補に挙げていた「handoff → CB 統合」は定常帯で headroom がほぼ無いため見送り、host work のエンコード順序変更 (#1) か depth3 pipelining (#2) を優先候補とする
  • **refine tick drain は A7 で既に大きく削減済み (旧 6.26s → 3.0〜3.8s)** — 残り headroom は task が想定していたより小さく、#4/#5 の効果も相応に小さい。追加投資の優先度は上記 3 提案 (残差側) より低いと見るべき
  • **旧 3 分解 (refine/encode(B)/残差) は 2 分解 (refine/通常境界) に訂正** — encode(B) は独立加算成分ではなく通常境界の host-late に吸収される。今後 sync-tax を語るときはこの 2 分解を使うこと
  • **中央値ベースの 3 分解 (host-late/drvproc/handoff) は近似** — 中央値は加算的でないため定量的な寄与%は出していない (定性的なランキングのみ)。追加 GPU run による精緻化は本 finding では見送り (advisor レビューでも「追加 run は不要」と確認済み)
未解決点

(1) 本 finding は n=1 の点推定 — 提案 #1〜#5 を実装した後の A/B gate では n=3 化が必要 (規約どおり)。(2) 中央値ベースの host-late/drvproc/handoff 寄与比 (≈80%/10%/10-15%) は band2〜4 の代表値からの概算であり、CB ペアごとの正確な寄与分解ではない。(3) band1 (arena growth + warm-up) の excess をどこまで refine 分と非 refine 分に按分するかは tick 数比による粗い見積りのみ — 正確な分離には CB 単位のラベル付け (どの CB が refine tick に属するか) が必要で、現行計装のスコープ外。(4) `commit()`→`kernelStart` の真の driver 投入 latency は依然未計装 (`host_lead` が代替、`p3-kernel-share-post-s3.toml` §8 と同じスコープ外項目)。

02

関連する run

この finding が観測された / 言及している実験 run。

03

関連 finding

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