mandelbrot/AUDIT.md
2026-08-22 20:55:27 +09:00

9.8 KiB
Raw Blame History

v18 数値・性能監査

Archive notice: この監査はv18時点の履歴資料です。現行renderer v23の受入値ではありません。v23のsource/配布baselineはaudit/v23-source-baseline.json、実行時browser baselineはaudit/v23-browser-baseline.jsonへ分離します。

目的

v7〜v17で積み重なった補正処理を「残っているから残す」のではなく、正しさ・速度・相互作用を測定して再判定した。

絶対時間は実行環境に依存するため、誤判定率・同条件での比率・処理の計算量を主な判断材料とする。

結論

処理 v18判断 理由
Arbitrary precision + Reference Orbit 維持 deep zoomの座標精度と基準軌道に必須
Perturbation + Rebasing 維持 全pixelをBigIntで直接計算するより圧倒的に有利
BLA 維持・監視強化 deep pixel kernelの主高速化手段。ただし適切なεは画面依存
Persistent Worker / Reference 維持 warm stateの価値が大きい
固定距離によるReference維持 改廃 距離だけではrecenterの損得を判定できない
Pilot render 縮小して維持 コスト予測専用なら有用。画素の代用には不正確
数学的iteration上限を途中で切るwork cap 廃止 黒/外部分類を壊す
Pilotのnearest-neighborで未解決pixelを補完 廃止 境界で誤差が大きい
coarse periodic interior mask 廃止 効く画面が偏り、pilotコストも増える
全strip strict verification 廃止 deep zoomで隠れた巨大ボトルネック
1点の誤差で全画面strict再描画 廃止 局所誤差に対して再計算範囲が過大
複数の解像度feedback controller 統合 controller同士が競合して粗いまま固定されることがあった
Dither 廃止 detail detectorの勾配を人工的に増やし、余計な高精細tileを誘発
Adaptive detail refinement/cache 維持 idle時へ遅延すれば費用対効果が良い
Autoの黒/色境界追従 維持 kernelと独立で軽く、誤航行抑制に有用
Synthetic Worker Wisdom 廃止 実際のWASM+BLA負荷と相関しにくい
Real BLA Wisdom 維持 実kernelを使ってWorker数を選べる

1. v17のiteration work capは数学的に不正確

v17はdeep base描画で、表示用global iterationより小さいcomputeIterを使い、そこまで発散しなければ事実上黒候補として扱っていた。

Seahorse付近、48×30、global 3490 / cap 2870をBigInt直接計算で照合した。

  • capまで残ったpixel: 1440 / 1440
  • その後3490までに発散したpixel: 1066
  • cap survivor中のlate escape: 74.03%

つまり「2870で未発散だから黒」とみなすのは、この画面では4分の3近くを誤分類する。

v18: computeIter = colorIterへ戻した。負荷制限は数学的iteration数ではなく、BLA operation / perturbation operationの回数に対して行う。上限到達はUNRESOLVEDであり黒ではない。少数なら局所再計算、多ければそのstripだけ無制限BLAへ戻す。

Raw: audit/raw/workcap_truth_v17.json

2. Pilot画像による未解決pixel補完は不正確

128×78のfull BLAと56×34 pilotのnearest-neighbor補完を比較。

  • 黒/外部分類の不一致: 451 / 9984 = 4.52%
  • escape iteration差が8超: 43.71%

境界付近では低解像度pilotを「計算結果」として使えない。

v18: pilotはコスト推定にだけ使う。画面へ表示せず、未解決pixelの色・黒判定にも使わない。

Raw: audit/raw/pilot_fill_audit.json

3. Interior detectionは「追加反復」ではなく早期終了で入れる

以前の黒専用look-aheadは、黒pixelへ追加iterationを課すため重かった。v18では逆に、内部と判定できたpixelを早く終了する。

実装:

  • main cardioid / period-2 bulbの解析判定
  • 軌道微分の収縮判定
  • BLA jump時はBLAの線形係数で微分も更新

96×72、2500 iterationでInterior detection OFF/ONを比較。黒/外部分類不一致は全テスト0。

場所 OFF ON 分類不一致
period-3 wide 766.7 ms 6.0 ms 0
period-3 mid 438.7 ms 2.3 ms 0
period-2近傍 364.7 ms 1.0 ms 0
mixed interior/exterior 282.8 ms 16.2 ms 0
cardioid cusp近傍 329.9 ms 1.8 ms 0

これは「黒を正しくするために重くする処理」ではなく、黒の多い画面を軽くする処理として残す価値が高い。

Raw: audit/raw/interior_safety_v18.json

4. BLA εは単一固定値にできない

Seahorse z≈14、160×98で保守的BLAを基準に比較。

ε 時間 class mismatch iteration差>1
2^-23 約299 ms 1.00% 5.23%
2^-32 約786 ms 0.383% 1.16%
2^-40 約1218 ms 0.083% 0.198%

一方、同じSeahorseでもz≈20では2^-23が基準と一致したテストがある。したがって「常に厳密」「常に緩い」の両方が非効率。

v18: fast BLAを使い、1フレームあたり固定少数点だけsafe BLAと照合する。誤差が出たstripだけsafe BLAで再計算する。

  • 通常の検証はstrict perturbationではない
  • 1stripごとに何点もstrict計算しない
  • 1点の不一致で全画面をstrict再描画しない

Raw: audit/raw/audit_v18_kernel.txt

5. per-strip strict verificationは隠れたボトルネックだった

旧設計では各stripのBLA後にstrict perturbationを複数点実行していた。非常に深い場所ではBLA本体が数msでも、strict検証が毎strip積み重なりwall timeを支配する。

v18の設計:

  1. fast BLAでstrip計算
  2. フレーム全体で固定個数だけsafe BLAと比較
  3. mismatchがあればそのstripだけsafe BLAで再計算
  4. status failureの少数pixelだけexact fallback

これで検証コストが「strip数 × deep iteration」に増えにくくなった。

6. Reference recenterは距離だけで決めない

z≈14ではrecenterが有利なケースが多かった。

  • 0.8画面横移動: first-frameで約91 ms節約
  • 0.8横+0.5縦: 約40 ms節約

しかしz≈20では、0.5画面横移動でrecenterが約14.5 ms損するケースもあった。

同じ「0.5画面離れた」でも損得が逆転するため、固定距離閾値は合理的でない。

v18:

  • Referenceは基本的に維持
  • 実測kernel MPPが基準より悪化したときだけ、予測損失とReference rebuild EMAを比較
  • rebuildの方が安いと予測できる場合だけrecenter
  • 極端に離れた場合だけhard safety limitを使う

Raw: audit/raw/reference_recenter_audit.json, audit/raw/reference_recenter_audit_z20.json

7. Resolution controlを一本化

過去版では以下が同時に解像度へ作用していた。

  • pilot推定
  • renderPerf MPP
  • deepScale
  • Device WisdomのresScale
  • 品質段階ごとのmin/max width

複数feedbackが同時に動くため、負荷変化後に過剰縮小したり、逆に最低幅に張り付いたりしやすかった。

v18: deep base resolutionは一つの時間予算モデルで決定する。pilotまたは最近の実測MPPを入力にし、detail tileは別のidle品質レイヤーとして扱う。

8. Ditherをdetail判定の前に入れない

Ditherはグラデーションbandingには効くが、画像のRGB勾配を人工的に増やす。detail detectorの入力へ先に適用すると「存在しない細部」を検出して追加tileを計算する。

v18: runtime ditherは削除。Canvasのhigh-quality scalingは維持。再導入するならdetail選定後の表示/export段階だけにする。

9. Real BLA Wisdomは残す

旧Synthetic Wisdomは単純なJS浮動小数点loopでWorker数を選んでいた。実際の負荷はWASM、BLA table、reference memory、postMessageを含むため別物。

v18: 長時間idle時のみ実際のBLA mini renderを1〜4 Workerで測定し、実スループットからWorker数を決める。解像度feedbackとは切り離した。

10. v17→v18 end-to-end確認

同一のclean Chromium 144 headless、780×441 viewportで、UI操作に相当するdeep base passを比較した。動的解像度を含む実際のbase-frame pipeline比較であり、pixel-for-pixel kernel benchmarkではない。

Scene v17 v18 改善
Seahorse z≈14 1059 ms 288 ms 3.68×
Seahorse z≈20 1226 ms 238 ms 5.15×
Seahorse z≈100 983 ms 474 ms 2.07×
period-3 z≈20 1931 ms 781 ms 2.47×

v18のclean runではruntime exception 0。

Raw: audit/raw/v17-final-browser-benchmark.json, audit/raw/v18-final-browser-benchmark.json, audit/benchmarks.json

11. 残した処理

次はデータ上、削る理由が弱いので維持した。

  • BigInt fixed-point coordinate
  • Reference Orbit cache + precision promotion
  • Perturbation / Rebasing
  • BLA
  • Series Approximation(主にfallback側)
  • Persistent Worker
  • smooth coloring LUT
  • Auto black/colour boundary tracking + safe rollback
  • world-space HQ tile cache
  • progressive detail refinement
  • high-quality Canvas scaling

12. 今後のボトルネック

v18ではpixel hot-loopの補正処理を大幅に整理した。さらに深い地点で残る主候補はReference OrbitのBigInt生成である。

特にReferenceが長く、かつ高bit精度になるケースでは、次の候補は:

  1. Reference Orbit専用Worker
  2. 次Referenceの先読み / double buffer
  3. Reference orbitの圧縮・周期利用

ただしz≈20程度ではReference生成が常に主因ではないため、常時複雑化するよりtelemetryで必要なときだけ有効化する方がよい。