mandelbrot/docs/IMPLEMENTATION_RESULTS.md
2026-09-06 23:28:03 +09:00

8.7 KiB
Raw Permalink Blame History

軽量化の実装と確認結果

更新日2026-09-06。対象index.html改善案実装設計 に基づく変更。

この文書は軽量化実装時点の記録。以後の色相・時間表示の修正と正確モードの削除はビューワー修正を参照。

実装した処理

計画 変更 確認方法
A判定と上限 目標の最後の更新後に脱出・誤差・参照範囲を確認する。正常な未脱出は実到達反復数を記録して継続キューへ残す。Direct DSも未脱出をreason 6へ統一した 実GPUの目標境界・誤差超過・参照末尾テスト
A分割 DSの適応バッチを毎回400万pixel-iterationsへ制限。幅1行でも上限を超える場合は横に分割する。PNGの重いタイルも分割する 幅3203840、350150000反復の上限・全画素被覆テスト
B同期 継続を14 passずつ適応投入し、最後の件数コピーをmapする。直前の全queue待ちは省く 0・1・63・64・65件、奇数偶数pass、次目標への再投入
BCPU補修 比較済みの高精度結果を次の比較へ使う。最大8軌道を5軌道にする。12 Workerへ画素数・反復数・精度に応じて小分けに投入し、完成した結果をまとめてGPUへ渡す 実Workerの軌道呼び出し数と採用条件を確認
C状態保持 数値補修で正常画素を再初期化しない。metaだけ回復した画素を別に保持し、それらだけ次目標で再計算する。Deepの初期計算も同じ継続stateを作る キューの保持・コンパクトslot・描画回帰テスト
C参照 同一の原点・実精度の軌道をWorkerで末尾延長する。基準軌道と高精度検証軌道は独立したBigInt終端を持つ。GPU側も容量内では末尾だけ転送する 延長結果と独立再生成のbyte一致、精度変更時のID分離
D失敗転送 既存のGPU histogramprefixscatterをタイル補修へ使う。CPU補修へ渡す際も失敗indexのみ読み戻す タイル内のindex集合をGPU出力と厳密比較
D結果反映 CPU結果をGPU scatterで反映する。書き込み前に描画世代を確認し、GPU側でも現在のmetaが数値失敗であることを確認する 古い世代の拒否、確定画素・反復待ち画素の保持
E内点 主カージオイドと周期2円に矩形全体が入ることをBigIntの整数区間で確認し、該当タイルを継続対象から除く 256 bitの境界内外・境界をまたぐ矩形、実軸のGPU描画
E優先順位 大きく重い継続ラウンドでは既存境界を先に進め、残りも同じ目標まで必ず進める 実コントローラーのテストで両グループの目標到達・index全件保持を確認
E反復予算 「反復上限」で画素精度から独立した有限予算を指定できる。自動設定では従来の停止方針を維持する。指定値はURLと表示履歴へ保存する 初期反復5124096から指定4096への到達、未脱出全画素のmeta、PNGの予算一致
E表示とメモリ 現在の画素格子の暫定結果を公開する。完成履歴へは入れない。疎な候補はコンパクトslot、密な候補は32 byteのstateを使う 暫定PNG拒否、キャンセル、slotと画素indexの一致

数値・品質の扱い

数値故障、有限反復での未脱出、証明できた内点を区別する。誤差guardを緩めたり、未確定画素を周囲の色で埋めて成功件数へ算入したりしない。

既定の「自動」では、従来の最低反復予算と安定ラウンド判定を維持した。「反復上限」を指定すると、その有限予算まで必要な全画素を処理して終了する。優先順位は表示順を変えるもので、低優先度の画素を省くものではない。pixelBits × 256 や安定2回を内点証明とは扱わず、結果には有限予算の方針を記録する。一般周期成分の包含証明や新しい近似加速器は、元の計画どおり研究候補として残している。

参照が実際に脱出した場合や採用精度が変わった場合は、同じstateを無条件には使えない。その場合の再初期化と、少数の補修による不要な全体再初期化は別に扱う。

初期描画用の参照と補修用の参照を分離し、同一のテスト入力では繰り返し描画・FASTDeepのmetaとsmoothのbyte一致を確認した。独立BigIntサンプルでは脱出分類・脱出反復数を厳密比較し、f32の再構成とlog2を含むsmoothは8 ULP以内を確認する。このサンプル検査を全画素の数学的証明とはしない。

主参照のCPUキャッシュは8 MiB、局所参照は2 Worker×2 MiBを基本上限とし、上限より大きな単独参照は1本だけ保持する。GPU参照は最大3種類。activeの密なstateは32 byte/画素、疎なslotは40 byte/候補とindex対応表を持ち、後者が実際に小さくなる場合だけ使う。密なframeでは既存の画素数上限とdeviceのbinding上限を使い、タイルごとに生存stateを捨てる方式は採らない。

通常の同一解像度PNGは補修済みのframeをコピーする。別解像度・複数sample出力は独立したタイル計算であり、残った未確定sample数を従来どおり出力メタデータへ記録する。任意の出力解像度・座標の数値失敗0は保証していない。

検証

検証用Edgeは専用プロファイル、1インスタンス・1タブで直列実行する。常時監査は追加せず、検証APIと詳細計測は ?test のみ。

node tests/regression.mjs
node tests/browser_smoke.mjs 9333 all

CPUテスト構文、シェーダー固定値、ルーティング、分割の被覆と上限、Workerの参照延長・精度再利用、内点区間、古い世代の拒否。

GPUテスト終端判定、queueの全index、コンパクトstate、scatterの対象保護、6つの描画座標、独立BigIntサンプル、パン往復、補修中のキャンセル、PNGの符号化と復号。

最終版で全回帰テストが通過した。640×480の実画面で「反復上限」を4096へ変更し、URLへの保存と再読み込み後の復元も確認した。検証終了後、専用Edgeとそのプロファイルを終了・削除し、残存Edgeプロセスがないことを確認した。

測定結果

Intel Gen-9の実GPU、Edge、320×240、標準負荷、自動の反復上限。Seahorseは re=-0.743643887037151, im=0.13182590420533, span=3.4e-13、初期512反復。各ケースを1回ウォームアップした後、同じタブで3回測定した。

ケース 3回の完成時間 (ms) 中央値 (ms) 暫定表示までの中央値 (ms) 最終反復 数値失敗 未脱出
初期表示 211.2 / 214.4 / 205.0 211.2 9.8 4096 0 1174
Seahorse FAST 12002.7 / 11637.2 / 11577.7 11637.2 55.9 32768 0 1
Seahorse Deep 11828.2 / 11164.0 / 11153.8 11164.0 84.7 32768 0 1

Seahorseでは最終的に残った1画素も32768反復へ到達しており、数値故障とは別の未脱出である。3回とも数値bufferのhashが一致した。FASTDeep間でも一致した。

FASTの継続バッチは6465回、主な数値readbackは約4.00 MB、CPU補修は3618軌道。Deepは6465回、約4.31 MB、3618軌道。仕事量の集計は入口件数×chunkの上界であり、早期脱出を差し引いた実反復数ではない。初期化157185画素には参照原点を変更した際の再初期化を含む。最終active workspaceは疎な1候補用48 byteだが、これは描画中の最大使用量やframe全体のメモリではない。

前回記録のFAST約36.7秒・Deep約41.3秒に対し、今回の同じ解像度・座標の中央値は約11.6秒・11.2秒だった。ただし今回は終端判定と補修も修正しており、旧版との数学的処理条件を完全に固定した速度比較ではない。全座標で同じ倍率の高速化を約束する値ではなく、p95も算出していない。

回帰用の実軸と既知の黒領域は64×48で確認した。独立サンプルはSeahorse FASTDeep・実軸・黒領域の各12画素。PNGは320×240の全画素を復号比較し、不一致0だった。処理中の操作で古いCPU補修が新しいframeを上書きせず、暫定frameが完成PNGへ入らないことも確認した。