信号のベンチを速くする
走行スタンプ: 2026-09-02、このリポジトリの七番目のコミット、rustc 1.97.1、 AMD Ryzen 5 5600X (1 スレッド)、wasm の行は node v24.0.1。 以下はすべて完全なゲートの下を通った: 凍結済みの blargg のエンベロープを すべて含む 58 テストが緑、MUTATE=1 は 33 を赤にし、clippy は清潔、 check-self-counts は 54 件の主張を検証。M2 のスループット表が「前」で あり、これが「後」だ。
三つのてこ、どれも組む前に docs/m2-report.md で名指しされていた
- U/V ローパスの前で間引く。 復調したクロマの幅は 0.6 MHz なので、
生の積を 4 で間引き、全レートでの 101 タップではなく fs/4 で 15
タップで濾す (支配的な段で 13 倍の削減)。それから Catmull-Rom で
補間して戻す (10.7 MHz の間引いたグリッドの上の 0.6 MHz 信号で、
誤差は 1 パーセントの十分の一ほど)。フィルタは他のすべてと同じく
出自付きで生成され (
data/filters/rung-a.toml、[uv_lowpass_decimated])、折り返した像の帯域での阻止量を実測して 記録してある (折り返しの 2.58 MHz で -50.3 dB)。 - 畳み込みをベクトル化器のために組み直した。 どの FIR も今は、 端を詰めたバッファの上をタップ外側・標本内側で走る: 1 タップにつき 要素ごとの積和が一つで、LLVM はこれをそのまま 8 幅で、wasm の simd128 の下では 4 幅でベクトル化する。標本ごとの位相引きは、 要素ごとに適用する 12 標本の回転表になった。
- ガンマの往復を wasm の経路から外した。 decode() は信号の RGB を 2.2 乗で線形の光に符号化し、ベンチはそれをすぐに元へ戻していた: 数学的な恒等変換のために 1 フレームあたり 300 万回の powf 呼び出しだ。 push_frame は今、同じ行列とクランプを通して YUV からバイトへ直接行く。
折り返しの解析が見落とし、コムのテストが捕まえたもの
素朴に 4 つおきを拾う間引きは、ノッチのラングには正しく (その帯域通過が 積のスペクトルを閉じ込める)、コムには間違いだった: 分離したクロマは 広帯域で、方形波の第 5 高調波の復調積は 21.48 MHz、ちょうど間引き後の レートの 2 倍にあたり、DC へ折り返す。直す前の実測: 2 フレームの時間比 0.897 に対してフェーザの 0.866、3 フレームの彩度 1.035 に対して 1.000、 縞のコムは 58% 高い。直し方はブロック平均 (ボックスカー 4) の間引きで、 その零点は DC と間引き後のナイキストへ折り返す周波数の上にちょうど乗り、 標本あたり 4 回の加算と 0.5 パーセント未満の通過帯域のだれで済む。 コムの数値はすべてエンベロープの中へ戻った。
同じく記録しておくこと: 古い MUTATE の摂動 (U/V の中央タップに +0.05) は、 色相のラダーの許容を下回って薄れていた。間引く経路が、古いテストが実は 検出していた広帯域のリップルを補間で消してしまうからだ。摂動は今 +0.15 で、赤が戻っている。対象が滑らかになると、妨害は静かに効かなくなり得る。 それに気づいたのは check-self-counts の計数だった。
実測、前と後
パイプライン全体 (符号化 + 復号、2048 x 240)、フレーム/秒、3 回の最良。 wasm の行は、新しい node プロセス 3 つにわたる幅を示す:
| 経路 | M2 (前) | 今 | 倍率 |
|---|---|---|---|
| NES ノッチ、ネイティブ | 7.54 | 40.69 | 5.4x |
| NES コム 3、ネイティブ | 8.49 | 44.30 | 5.2x |
| NES 時間方向 3 の復号 | 12.41 | 65.76 | 5.3x |
| 放送のノッチの復号 | 8.21 | 33.56 | 4.1x |
| 放送のコム 2 の復号 | 9.97 | 36.78 | 3.7x |
| NES ノッチ、wasm | 4.87 | 27.9 から 28.6 | およそ 5.8x |
| NES コム 3、wasm | 5.20 | 43.3 から 44.1 | およそ 8.4x |
| NES ノッチ、wasm +simd128 | 4.97 | 41.5 から 42.2 | およそ 8.5x |
| NES コム 3、wasm +simd128 | 5.18 | 44.4 から 47.5 | およそ 8.8x |
simd128 のフラグは、ベクトル化されるものが何も書かれていなかった M2 では不活性だったが、今はノッチのラングにさらに 1.5 倍を買ってくれる。 それがてこ 2 の狙いだ。wasm のベンチはコム 3 でソース自身の 60.09881 Hz に届くかその近くに座り、ノッチでは毎秒およそ 42 フレーム: スライド ショーではなく、生きた計器だ。60 に固定されるまでの残りの距離は符号化器 (今はフレームのおよそ半分) で、それを必要とする消費者が現れるまでは棚に 置いておく。
ビルド時に ntsc-crt/docs/perf-report.md から取り込まれる。写しはリポジトリの一つだけだ。報告は独自の作業用の言葉をいくつか使う: 報告書で使われる言葉。