`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>という機構仮説を提示する。
`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」という推定値を、実装済み計装による実測値で置き換える。
| flag | 値 | 判定 |
|---|---|---|
| `reliable` | true | 全列 (`cb_gap`/`drvproc`/`handoff`/`host_lead`) 信頼可 |
| `dropped` | 0 | GPU timeline に穴なし — `cb_gap` の blast radius 対象外 (無条件で健全) |
| `kernel_invalid` | 0 | `drvproc`/`handoff`/`host_lead` も無傷 (該当した場合のみ縮小するが今回は 0 件) |
| `sum/union` | 1.000000x | CB 間 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 のオーバーヘッドは無視できる |
| band (iter) | n | mean(ms) | p50(ms) | p90(ms) | max(ms) | mean×n(s) | p50×n(s) |
|---|---|---|---|---|---|---|---|
| [1, 3125] | 6251 | 0.511 | 0.256 | 1.168 | 42.728 | 3.194 | 1.600 |
| [3126, 6250] | 6250 | 0.457 | 0.297 | 0.904 | 48.050 | 2.856 | 1.856 |
| [6251, 9375] | 6250 | 0.394 | 0.307 | 0.469 | 48.600 | 2.462 | 1.919 |
| [9376, 12500] | 6249 | 0.411 | 0.299 | 0.499 | 44.924 | 2.568 | 1.868 |
| **overall** | **25000** | **0.443** | **0.278** | **0.860** | **48.600** | **11.081 (Σ=11.085)** | **6.950 (band和 7.244)** |
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) とほぼ一致することのクロスチェック根拠になる。
| band (iter) | metric | n | mean(ms) | p50(ms) | p90(ms) | max(ms) |
|---|---|---|---|---|---|---|
| [1, 3125] | drvproc | 6252 | 0.043 | 0.026 | 0.056 | 6.603 |
| [1, 3125] | handoff | 6252 | 1.695 | 0.569 | 5.126 | 6.657 |
| [1, 3125] | host_lead | 6251 | 1.225 | **−0.200** | 5.144 | 6.683 |
| [3126, 6250] | drvproc | 6250 | 0.076 | 0.026 | 0.145 | 3.226 |
| [3126, 6250] | handoff | 6250 | 3.375 | **0.153** | 7.254 | 8.984 |
| [3126, 6250] | host_lead | 6250 | 2.994 | **−0.240** | 7.265 | 8.995 |
| [6251, 9375] | drvproc | 6250 | 0.096 | 0.027 | 0.173 | 4.098 |
| [6251, 9375] | handoff | 6250 | 3.650 | **0.047** | 7.731 | 9.128 |
| [6251, 9375] | host_lead | 6250 | 3.352 | **−0.253** | 7.740 | 9.137 |
| [9376, 12500] | drvproc | 6249 | 0.103 | 0.029 | 0.182 | 4.188 |
| [9376, 12500] | handoff | 6249 | 3.719 | **0.056** | 7.884 | 9.130 |
| [9376, 12500] | host_lead | 6249 | 3.411 | **−0.247** | 7.895 | 9.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** |
`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オーダーの丸め誤差を含むが、ランキングを覆すほどの誤差ではない)。
| 区分 | 推定範囲 | 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.13s | 8.9% | `[gpu]` summary line / reconcile 行 |
`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 コスト削減主張と整合する。
| # | 対象 | 施策 | 期待 Δ (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 drain | refine 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`** |
(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 と同じスコープ外項目)。
この finding が観測された / 言及している実験 run。