Separate the two axes: profiles are I/O, the CPU ceiling is one target for both
The profiles were chosen against disk bandwidth and say nothing about CPU. The locked CPU target is a stock 10MHz 68000 for both of them, so both must fit 833,333 cycles -- picking sasi does not rescue it, it still misses 31% of frames against scsi's 42%. Splits the miss into what the encoder can fix and what it cannot: re-coding every non-SKIP block as V1 is the floor, and it still misses 11 frames at sasi and 12 at scsi, all of them above ~90% non-SKIP. So a cost-aware mode decision can reach about three quarters of the misses; the rest need a structural answer, not a better encoder. Also: V4 is 448 cycles against RAW's 400, and RAW is pixel-exact. On the CPU axis V4 is strictly dominated and the byte lagrangian's mode preference inverts. Only the byte-rich profile can take that escape, so the cycle ceiling should cost sasi MORE quality than scsi despite costing it fewer cycles. FINDINGS 28.7/28.8. Claude-Session: https://claude.ai/code/session_01194oWYW8DQXK1SZ2DnChW6
This commit is contained in:
@@ -1371,3 +1371,55 @@ One 10 s window of one stream at one profile, and MAME still models no GVRAM
|
|||||||
wait states. The `scsi` profile will be worse: FINDINGS 25.5 has it collapsing
|
wait states. The `scsi` profile will be worse: FINDINGS 25.5 has it collapsing
|
||||||
to RAW under stress, and RAW is 1.93x the old model's block. Nothing here has
|
to RAW under stress, and RAW is 1.93x the old model's block. Nothing here has
|
||||||
been run on `00020` or on quiet content, where the median frame is far cheaper.
|
been run on `00020` or on quiet content, where the median frame is far cheaper.
|
||||||
|
|
||||||
|
### 28.7 The profiles are an I/O axis; the CPU limit is the clock
|
||||||
|
`sasi` and `scsi` are two points on one rate-distortion curve, chosen against
|
||||||
|
**disk bandwidth**. They say nothing about CPU, and the locked target CPU is a
|
||||||
|
stock 10MHz 68000 for both. So both have to fit the same 833,333 cycles:
|
||||||
|
|
||||||
|
| | sasi | scsi |
|
||||||
|
|---|---:|---:|
|
||||||
|
| stock / Super, 10 MHz | median 74.4%, **31% of frames miss** | median 94.9%, **42% miss** |
|
||||||
|
| XVI, 16.67 MHz | median 44.6%, 0% miss | median 56.9%, 0% miss |
|
||||||
|
|
||||||
|
Clocks confirmed from MAME 0.277 `x68k.cpp:1133/1194/1200`: `x68000` and
|
||||||
|
`x68ksupr` are **both** `40_MHz_XTAL/4` = 10 MHz, and only `x68kxvi` is faster
|
||||||
|
at `33.33_MHz_XTAL/2`. The Super has SCSI at 10 MHz, so a faster bus does not
|
||||||
|
imply a faster CPU — the XVI column above is headroom, not a target.
|
||||||
|
|
||||||
|
`sasi` is the cheaper profile, but choosing it is not a fix: it still misses
|
||||||
|
31% of frames. The cycle ceiling has to be enforced in the encoder either way.
|
||||||
|
|
||||||
|
**How much of the miss is the encoder's to fix.** Re-coding every non-SKIP block
|
||||||
|
as V1 — the cheapest mode, quality ignored — is the floor any mode assignment
|
||||||
|
can reach:
|
||||||
|
|
||||||
|
| | frames that miss | recoverable by re-coding | impossible at 12fps |
|
||||||
|
|---|---:|---:|---:|
|
||||||
|
| `sasi` | 37/120 | 26 | **11** (from 89.8% non-SKIP up) |
|
||||||
|
| `scsi` | 51/120 | 39 | **12** (from 91.9% non-SKIP up) |
|
||||||
|
|
||||||
|
So a cost-aware mode decision can reach about **three quarters** of the misses.
|
||||||
|
The remaining ~10% of frames are 28.5's ceiling in practice: past ~90% non-SKIP
|
||||||
|
no mode assignment fits, because the blocks have to be drawn at all. Those
|
||||||
|
frames need a structural answer — a late frame at a cut, a cut spread over two
|
||||||
|
frame times, or a lower framerate — not a better encoder.
|
||||||
|
|
||||||
|
### 28.8 V4 costs more cycles than RAW, so it is CPU-dominated by it
|
||||||
|
448.2 against 400.4 cycles. RAW is also pixel-exact where V4 is lossy, so V4's
|
||||||
|
only advantage is that it costs 4 payload bytes instead of 16. **On the CPU
|
||||||
|
axis V4 is strictly dominated**, which inverts the mode preference the byte
|
||||||
|
lagrangian has: an encoder short of cycles but not of bytes should buy RAW
|
||||||
|
wherever it would have bought V4, and gain quality doing it.
|
||||||
|
|
||||||
|
That escape is only open to the byte-rich profile. `scsi` already spends 41.3%
|
||||||
|
of its blocks on RAW (FINDINGS 25.5 saw it "collapse to RAW under stress" and
|
||||||
|
read that as a failure; on the CPU axis it is the cheap direction). `sasi` at
|
||||||
|
110 KB/s cannot afford it, so its only lever is V4 -> V1 -> SKIP, every step of
|
||||||
|
which costs quality. **The CPU constraint therefore bites harder on `sasi` in
|
||||||
|
quality terms even though it bites less in cycles.**
|
||||||
|
|
||||||
|
Caveat: this ordering is a property of *this* decoder, not of the codec. V4's
|
||||||
|
cost is four indexed `movem.l` lookups; pairing sub-block rows into
|
||||||
|
`movem.l d0/d2,(a4)` would save ~16 of 448 cycles, which narrows the gap to RAW
|
||||||
|
without closing it.
|
||||||
|
|||||||
@@ -43,6 +43,18 @@ worth 4 bytes, with no idea what it costs to draw.
|
|||||||
cliff? `tools/analysis/11_cpu_budget.py` scores a container without needing
|
cliff? `tools/analysis/11_cpu_budget.py` scores a container without needing
|
||||||
MAME, so the search loop is cheap; confirm the winner on the 68000 with
|
MAME, so the search loop is cheap; confirm the winner on the 68000 with
|
||||||
`tools/bench/decode.lua`.
|
`tools/bench/decode.lua`.
|
||||||
|
3b. **Know which misses are yours to fix before starting.** Re-coding every
|
||||||
|
non-SKIP block as V1 is the floor any mode assignment can reach, and it
|
||||||
|
still misses 11 frames at `sasi` and 12 at `scsi` — every frame above ~90%
|
||||||
|
non-SKIP. So the cost-aware decision can reach about three quarters of the
|
||||||
|
misses (26 of 37 at `sasi`) and the rest are item 4. FINDINGS 28.7.
|
||||||
|
|
||||||
|
3c. **Buy RAW, not V4, wherever the bytes allow.** RAW is 400 cycles against
|
||||||
|
V4's 448 *and* is pixel-exact, so on the CPU axis V4 is strictly dominated —
|
||||||
|
the byte lagrangian's preference inverts. `scsi` can take that escape and
|
||||||
|
`sasi` cannot afford it, so expect the cycle ceiling to cost `sasi` more
|
||||||
|
quality even though it costs `sasi` fewer cycles. FINDINGS 28.8.
|
||||||
|
|
||||||
4. **28.5 may not be solvable by the encoder at all.** An all-V1 frame — the
|
4. **28.5 may not be solvable by the encoder at all.** An all-V1 frame — the
|
||||||
cheapest possible full redraw — is **110.5%** of the budget. A scene cut
|
cheapest possible full redraw — is **110.5%** of the budget. A scene cut
|
||||||
changes 100% of the screen, so *no* mode assignment fits one at 12fps. Decide
|
changes 100% of the screen, so *no* mode assignment fits one at 12fps. Decide
|
||||||
@@ -157,6 +169,7 @@ the display path is pixel-exact.
|
|||||||
| Double buffer | **none** — page 1 sacrificed | enables `movem.l` 24px bursts; delta coding needs a RAM reference frame anyway |
|
| Double buffer | **none** — page 1 sacrificed | enables `movem.l` 24px bursts; delta coding needs a RAM reference frame anyway |
|
||||||
| **Codec** | **hybrid VQ: SKIP / V1 4x4 / V4 four-2x2 / RAW, per-block rate-distortion** | flat 4x4 VQ was measured and rejected — see FINDINGS 9-10 |
|
| **Codec** | **hybrid VQ: SKIP / V1 4x4 / V4 four-2x2 / RAW, per-block rate-distortion** | flat 4x4 VQ was measured and rejected — see FINDINGS 9-10 |
|
||||||
| **Quality modes** | **two: `sasi` and `scsi`** (USER DECISION, session 2) | one codec, one decoder, one bitstream; only `lam` differs |
|
| **Quality modes** | **two: `sasi` and `scsi`** (USER DECISION, session 2) | one codec, one decoder, one bitstream; only `lam` differs |
|
||||||
|
| Profile axis | **I/O bandwidth only** | the profiles say nothing about CPU; **both target the same stock 10MHz 68000**, and the Super has SCSI at 10MHz. FINDINGS 28.7 |
|
||||||
| Framerate | 12 fps, **explicit decimation** | source has zero duplicate frames; no free "twos" win |
|
| Framerate | 12 fps, **explicit decimation** | source has zero duplicate frames; no free "twos" win |
|
||||||
| Emulator | MAME 0.277 x68000 | accurate enough that measured cycles mean something |
|
| Emulator | MAME 0.277 x68000 | accurate enough that measured cycles mean something |
|
||||||
| SNES project reuse | **MIT — cleared** | `data/events/` scene graph is reusable with attribution |
|
| SNES project reuse | **MIT — cleared** | `data/events/` scene graph is reusable with attribution |
|
||||||
|
|||||||
Reference in New Issue
Block a user