food_chain/docs/integrated-improvements/IMPLEMENTATION.md
2026-09-29 23:45:12 +09:00

153 lines
6.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 5改善案の本体統合と再評価
## 対象
前回評価表の「Numeric tile cache」より上にあった次の5案を `index.html` に統合した。
1. 一般周期検出
2. perturbation series approximation
3. sparse active state
4. dynamic multi-reference
5. CPU Worker fallback
`Numeric tile cache` 以下は今回の対象外。基準は統合前の `index.html`(SHA-256 `8355da57...086a935`)。
## 実装
### 1. 周期検出
- direct f32 kernel に Brent 型 O(1) candidate search を追加。
- 単純な「近いから内部」判定は再評価で危険と判明したため、候補後に **2周期分の再一致**と **周期乗数 `|μ| < 0.95`** を確認してから `FIELD_INTERIOR_HEURISTIC=2` にする。
- `FIELD_INTERIOR_PROVEN=3` とは分離し、heuristic が1画素でもあれば `membershipCertified=false`。
- strict/export では無効。
- FAST perturbation 上の周期早期停止は撤回。forced-direct 診断で deep seahorse に false candidate が残ったため、deep path は series / continuation に任せる。
### 2. Series approximation
- reference worker で 1〜6次係数を更新。
- GPU に送るのは 1〜4次係数。5・6次は truncation error の安全側判定に使用。
- validity 条件を満たす最大 jump を reference ごとに計算し、FAST perturbation の初期反復を4次多項式評価へ置換。
- strict/export では series jump を無効化し、従来 recurrence を使う。
### 3. Sparse active state
旧 continuation は state/queues/mark をほぼ全画素サイズで持っていた。新構成は以下。
- `DeepState`: active slot ごと 32 B
- queue A/B: active slot ID
- `pixelMap`: active slot → pixel index
- membership: 1 bit/pixel bitset
- 初期 capacity: `active * 1.25 + 256`(全画素上限)
- correction により新しい `OPERATION_LIMIT` が生じた場合は、slot allocator を複雑化せず metadata から compact session を再構築する。
### 4. Dynamic multi-reference
- failure-guided reference recovery を最大3 passまで反復。
- 既に試した reference identity は再試行しない。
- 1 pass の改善が `max(8 pixels, 2%)` 未満なら打ち切る。
- 固定 2x2 / 3x3 配置ではなく、既存 failure sample + scorer を使って必要箇所だけ reference を追加する。
### 5. CPU Worker fallback
- WebGPU 非対応/初期化失敗時に最大4 Workerで direct Mandelbrot を描画。
- cardioid / period-2 bulb、有限 iteration、既存 palette の主要表示をサポート。
- JS `Number` で adjacent pixel を区別できない deep zoom では停止し、誤った deep image を出さない。
- CPU fallback の `OPERATION_LIMIT` と周期 heuristic は未確定扱い。WebGPU の high-precision path の代替ではなく互換経路。
## 再評価結果
### 周期検出
96×64、maxIter=8192、candidate は 65,536 iteration まで escape を追跡。
| view | production backend | 反復仕事量削減 | false candidate |
|---|---|---:|---:|
| overview | direct | 84.9% | 0 |
| period3-bulb | direct | 99.09% | 0 |
| period3-core | direct | 99.12% | 0 |
| seahorse-boundary | direct | 0% | 0 |
| exterior | direct | 80.0% | 0 |
| seahorse-deep | fast-extended | **周期停止を使用しない** | — |
forced-direct では seahorse-deep に false candidate が残るため、FAST 側を無効化した判断は維持する。
### Series approximation
production fast-reference worker の実出力を使用し、4次 series と直接 perturbation の delta を8点で比較。
| span | jump | 最大絶対誤差 |
|---:|---:|---:|
| 1e-5 | 53 | 7.11e-9 |
| 1e-7 | 446 | 7.74e-9 |
| 1e-9 | 930 | 7.46e-9 |
| 1e-11 | 1037 | 2.28e-9 |
reference build の一部として係数を作るため CPU 側の追加仕事はあるが、deep zoom ほど jump が大きい。実 GPU frame time はこの環境では測れていない。
### Sparse active state
standard 1,048,576 px の continuation workspace モデル。
| active ratio | 旧 | 新 | 削減 |
|---:|---:|---:|---:|
| 100% | 44.0 MiB | 44.13 MiB | -0.28% |
| 25% | 44.0 MiB | 13.89 MiB | 68.4% |
| 10% | 44.0 MiB | 5.64 MiB | 87.2% |
| 1% | 44.0 MiB | 0.686 MiB | 98.4% |
active がほぼ全画面なら pixel map + bitset の分だけわずかに悪化する。狙いは sparse frontier であり、その条件では効果が大きい。
### Dynamic multi-reference
production は failure-guided 最大3追加 reference。GPU end-to-end の `A_num` は実 GPU 不在で測れないため、前回と同じ f32 perturbation locality surrogate を再実行した。
seahorse span=1e-7:
- center 1 ref: class mismatch 2.578%
- center + 2x2 (5 refs): **1.445%**
- center + 3x3 (9 refs): 1.953%
reference を無制限に増やすのは逆効果になり得るため、「失敗箇所から選ぶ + 3 pass cap」は妥当。
### CPU fallback
production `cpuFallbackWorkerSource()` 自体を Node worker shim で実行。640×360、350 iter、7 run median。
- 1 Worker: 約 97.2 ms
- 4 Workers: 約 36.0 ms
- speedup: **2.70×**
- escaped / OP_LIMIT / heuristic / work count は 1 Worker と4 Workerで一致。
これはブラウザ 2D canvas compositing を含まない worker compute 値。
## 回帰・サイズ
- JS syntax: PASS
- production regression: **5/5 PASS**
- regression median: 約 0.08 s
- WGSL kernels: 19本、hash 更新済み
- `index.html`: 208,576 → 223,672 bytes(+7.24%)
- gzip -9: 52,563 → 57,198 bytes(+8.82%)
## 実 GPU 検証の限界
コンテナの Headless Chromium + SwiftShader は EGL 初期化に失敗し、WebGPU smoke を開始できなかった。そのため以下は未測定。
- stable frame p50/p95
- GPU series jump の実時間短縮
- sparse scatter/gather の実 GPU overhead
- dynamic multi-reference 導入後の production `A_num`
したがって **CPU/数値 surrogate を GPU frame-time として扱わない**。
## 結論
| 改善 | 統合判断 | 再評価 |
|---|---|---|
| 周期検出 | 採用(directのみ) | 高周期内部で非常に有効。FASTでは安全性不足のため無効 |
| Series | 採用(interactive) | deepほど jump が増え、有望 |
| Sparse active state | 採用 | active≪100%ならメモリ効果が明確 |
| Dynamic multi-reference | 採用(最大3 pass) | reference増加は非単調。failure-guided capが妥当 |
| CPU fallback | 採用 | 互換性改善。4 Workerで約2.7×、deep precision代替ではない |
次に実機で確認すべき優先順位は **series GPU frame time → sparse continuation latency → multi-reference の `A_num`**。