Measure the finer chain tail: 84/120 becomes 18/120, and the derivation was right by cancellation

blit.s gains v7 -- v6's 24-pixel movem chain plus a second chain whose unit is
one `move.l (a0)+,(a2)+`. Measured over 13 span lengths by span.sh, every config
pixel-exact:

    cycles = 66.0 per span + 9.143 per COARSE pixel + 9.978 per FINE pixel

fitting all 13 to within 0.2%. v5 and v6 re-measure to FINDINGS 30 exactly, so
the harness has not drifted underneath the new variant.

Rescored against the same scsi window and the same additive model, v7 takes
84/120 frames over budget to 18/120 -- exactly what FINDINGS 39.4 derived, and
that agreement is two cancelling errors: the derivation's 2-register movem tail
is 29% too dear per pixel, and its "nothing per span" for the second chain entry
is 22.3 clocks too cheap. The plain post-incrementing move.l is the right tail
instruction, and it makes the padding quantum 2 pixels, which a run of 4x4
blocks pads to exactly zero.

The DMAC stays dropped on a measurement now rather than an argument: v7 takes
back 37 of the 43 frames the array chain would, with no reserved channel and no
timing neither emulator here can verify. Break-even against all-V1 moves from
L=4 blocks to L=2.

The fine displacement is carried mid-stream rather than in the span record, so
the decoder holds nothing across the copy and keeps all 12 payload registers --
which is the whole reason the coarse unit is 24 pixels.

span.sh is now -seconds_to_run 200 (30 s wall, 36 configs) and takes its
expected snapshot count from the generated metadata instead of a literal 23.

Claude-Session: https://claude.ai/code/session_01194oWYW8DQXK1SZ2DnChW6
This commit is contained in:
prosolis
2026-08-23 19:02:23 -07:00
parent c5ca56330e
commit c520a89e14
9 changed files with 522 additions and 52 deletions
+16 -5
View File
@@ -11,6 +11,10 @@ decoder occupies 86.7% of it once instruction prefetch is counted, and 52 of the
53 frames that miss the 12fps budget miss it on the bus, not the CPU
(FINDINGS 38). Read that before optimising anything for cycles.
The largest measured win on the table is the **literal span with a fine tail**
(`blit.s` v7): it takes the worst `scsi` window from 84/120 frames over budget
to 18/120, and `src/player/decode.s` does not implement it yet (FINDINGS 40).
**Green-light check:** `./tools/bench/check.sh` (~3 min, needs the Blu-ray
mounted) re-runs both display regression tests, the rate-control drift test, the
display-path coherency counterexample and a 120-frame 68000 decode, then prints
@@ -47,8 +51,10 @@ tools/analysis/ measurement scripts, numbered in the order they were written
scene cut still fits at 12fps; 13 measures what fitting the
CPU budget costs in dB (FINDINGS 31) and caches H.build so the
search loop is seconds, not minutes.
14 prices the HD63450 array-chain against the v6 span
(FINDINGS 39) and prints the sensitivity that decides it;
14 prices the HD63450 array-chain against the v6 and v7
spans (FINDINGS 39/40) and prints the sensitivity that decides
it -- v7 is measured, and takes 37 of the 43 frames the DMAC
would, so the DMAC stays dropped;
15 measures how much of the 68000's LOCAL bus the decoder
occupies (FINDINGS 38) and exits non-zero if its derived
model stops matching the harness's measurement.
@@ -58,9 +64,14 @@ tools/bench/ MAME Lua injection harness + 68000 benchmark sources.
`blit.s`/`blit.lua` time the full-frame GVRAM blit on the
68000 itself (FINDINGS 24) — not part of check.sh, because
wall timings would make the green-light check host-sensitive.
`span.sh` (prep_spans.py + span.lua + blit.s v5/v6) measures
the literal-span mode the same way (FINDINGS 30, ~25 s); it
also asserts all 23 timing configs drew a pixel-exact frame.
`span.sh` (prep_spans.py + span.lua + blit.s v5/v6/v7)
measures the literal-span mode the same way (FINDINGS 30 and
40, ~30 s); it also asserts that every one of its 36 timing
configs drew a pixel-exact frame, the count taken from the
generated metadata so a new config cannot weaken the gate.
v7 is v6 with a second, 2-pixel chain for the span tail:
66.0 cycles/span + 9.143 per coarse pixel + 9.978 per fine
pixel, MEASURED, which is the win FINDINGS 39.4 predicted.
`crtc_mode.lua` is the single source of truth for CRTC R00-R08
and R20 — do not write CRTC values anywhere else.
`prep_dlx.py`/`decode.lua`/`verify_decode.py` load, time and