Measure the span: the mode survives, and it is an encoder format
FINDINGS 29 priced a literal-span mode at 4*(50 + 4L*9.08) cycles and labelled
the whole section DERIVED. Session 8 step 0 was to measure it before optimising
over the mode set it implies. Two variants in blit.s, one stream per span length
from prep_spans.py, timed by span.lua, driven by span.sh in ~25 s:
v5, handed (x, npix) and left to work the copy out: 97.9/span + 10.459/px
v6, handed an address and a jump displacement: 43.7/span + 9.152/px
29 assumed 50.0/span + 9.080/px
So 29's arithmetic was right about a format nobody had written. The difference
is not tuning: v5 spends ~122 cycles a span computing a destination, dividing
npix into bursts and handling a 0..15 remainder, all of which the encoder knows
at build time. v6's record is {u32 absolute GVRAM address, u16 jump
displacement} into an unrolled chain of 24-pixel copy units -- no loop, no
remainder, no arithmetic -- and it fits 11 span lengths to 0.3%.
Three things that measurement showed and derivation could not:
- The per-pixel cost is a function of REGISTER PRESSURE. FINDINGS 24's 9.08
was a fixed blit with 12 registers free; v5 can spare 8 and pays 10.46; v6
gets 12 back only because the encoder holds the state.
- Short spans die in the remainder path -- a 12-pixel span costs MORE than a
16-pixel one -- and the fix is padding, not avoidance.
- Odd-x alignment is free (259.0 vs 261.8 cycles/span), as a 16-bit bus
implies but nobody had checked.
Re-priced against the unchanged mode maps, sasi: median 74.4% -> 52.0% (29 said
43.0), misses 37 -> 10/120 (29 said 8), 448.0 KB/s. Break-even moved from runs
of 2 blocks to runs of 4. 29.4 survives: a scene cut needs x >= 0.196 of the
frame as spans and the bus allows x <= 0.373, so it fits at 12fps.
All 23 timing configs are also checked pixel-exact, so none of this was timed
against a decoder that quietly skipped work.
FINDINGS 30. Next: lever B, the cost-aware mode decision.
Claude-Session: https://claude.ai/code/session_01194oWYW8DQXK1SZ2DnChW6
This commit is contained in:
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
# Measure the cost of a row-linear literal span on the 68000 (FINDINGS 30).
|
||||
# ~25 s. Run from the repo root. Needs tmp/frame256.bin (check.sh makes it).
|
||||
#
|
||||
# NOT part of check.sh, for the same reason blit.s is not: the output is a wall
|
||||
# timing, so gating on it would make the green light host-sensitive. What IS
|
||||
# gated here is correctness -- all 23 configs must draw a pixel-exact frame,
|
||||
# which is what stops a config timing fast by quietly writing nothing.
|
||||
set -e
|
||||
cd "$(dirname "$0")/../.."
|
||||
[ -f tmp/frame256.bin ] || { echo "need tmp/frame256.bin -- run tools/bench/check.sh"; exit 2; }
|
||||
|
||||
python3 tools/bench/prep_spans.py
|
||||
tools/vasm/vasmm68k_mot -Fbin -o tmp/blit.bin tools/bench/blit.s > /dev/null
|
||||
mkdir -p tmp/snap_span
|
||||
rm -f tmp/snap_span/x68000/*.png
|
||||
( cd tmp && SDL_VIDEODRIVER=dummy timeout -k 5 1800 mame x68000 -bios ipl10 \
|
||||
-ramsize 2M -video soft -window -sound none -nothrottle -plugins \
|
||||
-autoboot_script ../tools/bench/span.lua \
|
||||
-snapshot_directory ./snap_span -snapview native -seconds_to_run 150 \
|
||||
> span.log 2>&1 )
|
||||
grep -a "^\[SPAN\]" tmp/span.log
|
||||
|
||||
n=0
|
||||
for f in tmp/snap_span/x68000/*.png; do
|
||||
python3 tools/bench/verify_frame256.py "$f" > /dev/null || {
|
||||
echo "FAIL: $f is not pixel-exact"; python3 tools/bench/verify_frame256.py "$f"; exit 1; }
|
||||
n=$((n+1))
|
||||
done
|
||||
[ "$n" -eq 23 ] || { echo "FAIL: $n snapshots, expected 23"; exit 1; }
|
||||
echo "OK $n/23 span configs drew a pixel-exact frame"
|
||||
Reference in New Issue
Block a user