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:
prosolis
2026-08-23 15:14:12 -07:00
parent ed353d24a9
commit 31c4c1aba1
2 changed files with 65 additions and 0 deletions
+52
View File
@@ -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
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.
### 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.