Align the container to the disc, and find the decoder-free packed player fits
Two sessions, unrecorded until now, committed together because their edits share files and cannot be split cleanly after the fact. Session 28 (FINDINGS 60): the container is DLX5 -- every record sector-aligned, 120/120 starting on a boundary where 3/120 did, +0.48% on the wire and zero clocks -- and the ring's release rounds to RECALN so no pad is stranded. Two encoder levers measured and refused: `--spans all` buys +0.19 dB for +67% of the wire, and joint span/lam selection emits byte-identical containers because `lam` never leaves its floor on any of 120 frames. Session 29 (FINDINGS 61): the packed full-frame blit is 27.3% of a 12 fps frame, a channel fills GVRAM in buffer mode off the disc with the CPU halted, and it walks the 1,024 B line stride itself through array chaining. At the 9 clk/B dual-address floor the codec is 110.4% of a frame and a decoder-free packed literal player is 55.2%, at +4.89 dB -- 2.75 dB past a ceiling the codec's scene-wide palette cannot cross. Encoder work is parked; the codec is kept and not built on. check.sh is ALL GREEN before and after, plus one new stage that gates the ORDER of the measured paint costs rather than their values. Claude-Session: https://claude.ai/code/session_01194oWYW8DQXK1SZ2DnChW6
This commit is contained in:
+91
-14
@@ -353,7 +353,7 @@ echo "--- session 23: the 68000 fills its own ring (FINDINGS 55) ---"
|
||||
# rather than faulting (49.2);
|
||||
# * the host AUDITS every placement against its own index and its own list of
|
||||
# live records, and refuses the run on the first disagreement;
|
||||
# * the wrap policy still produces the SAME 18 wraps and 14.7 KB mean hole the
|
||||
# * the wrap policy still produces the SAME 18 wraps the
|
||||
# host producer produced in FINDINGS 49.4 -- a third independent
|
||||
# implementation of `aligned` landing on the same tiling;
|
||||
# * zero underruns at a two-deep request queue, which is the finding: a
|
||||
@@ -445,13 +445,17 @@ echo "--- session 26: the ring is filled off a real SCSI volume (FINDINGS 58) --
|
||||
# * pixel-exact, which is the only test that can see a wrong record: the
|
||||
# window in scsi.i decides which of a sector's bytes reach the ring, and a
|
||||
# window off by one byte desyncs the bitstream rather than faulting (49.2);
|
||||
# * the SAME 18 wraps and 14.7 KB mean hole -- ring.i's placement policy must
|
||||
# not be able to tell which transport answered it, and this is the assertion
|
||||
# that says it could not;
|
||||
# * every record accounted for: 120 READ(10)s, 4,488,588 B into the ring, and
|
||||
# 4,548,608 B off the disc. The two byte counts differ by 1.34% because a
|
||||
# record is not a sector, and that gap is a delivery cost (58.3) -- gating
|
||||
# both numbers means neither can drift silently into the other;
|
||||
# * the SAME 18 wraps -- ring.i's placement policy must not be able to tell
|
||||
# which transport answered it, and this is the assertion that says it could
|
||||
# not. The WRAP COUNT is gated and the mean hole is only reported: DLX5's
|
||||
# records are up to 511 B longer than DLX4's, so the hole moved (14.7 KB ->
|
||||
# 13.5 KB) while the tiling did not. Gating a number that the container's
|
||||
# record lengths move would gate the container, not the policy;
|
||||
# * every record accounted for: 120 READ(10)s, and the bytes into the ring
|
||||
# EQUAL to the bytes off the disc -- both read out of the container rather
|
||||
# than written here. Under DLX4 they differed by 1.34% because a record was
|
||||
# not a sector (58.3); DLX5 aligns records to sectors and the covering-sector
|
||||
# read disappears, so the gate is now their IDENTITY;
|
||||
# * a real mid-stream SEEK with the real transport, in the second pass. This
|
||||
# is the one path that could not exist before: ring_seek waits for the
|
||||
# channel to go quiet, and with the transport INSIDE the machine the only
|
||||
@@ -470,15 +474,34 @@ if command -v chdman > /dev/null; then
|
||||
| sed "s/^ *//;s/^/ /"
|
||||
grep -aq "TRANSPORT FAILED" tmp/p4b_check.log && {
|
||||
echo "FAIL: a record's READ(10) reported an error."; exit 1; }
|
||||
grep -aq "REAL TRANSPORT: 120 READ(10)s by the 68000, 4488588 B into the ring" \
|
||||
# THE BYTE COUNTS COME OUT OF THE CONTAINER, not out of this file. They were
|
||||
# two hardcoded constants fitted to the DLX4 gate container, and session 28's
|
||||
# re-encode went red on both of them for the right reason -- the container had
|
||||
# changed and the expectation had not. A gate whose expected value is a
|
||||
# literal tests the literal.
|
||||
EXPECT_B=$(python3 -c "
|
||||
import sys; sys.path.insert(0, 'tools/encoder')
|
||||
from dlx import DLX
|
||||
print(sum(DLX('$DLX').record_lengths()))")
|
||||
grep -aq "REAL TRANSPORT: 120 READ(10)s by the 68000, $EXPECT_B B into the ring" \
|
||||
tmp/p4b_check.log || {
|
||||
echo "FAIL: the 68000 did not fetch all 120 records, or did not fetch"
|
||||
echo " 4,488,588 B of them. A short record is a desync, not a shortfall."
|
||||
echo " $EXPECT_B B of them. A short record is a desync, not a shortfall."
|
||||
exit 1; }
|
||||
grep -aq "SECTOR OVERHEAD: 4548608 B off the disc" tmp/p4b_check.log || {
|
||||
echo "FAIL: the bytes the DISC moved are no longer 4,548,608. A record is"
|
||||
echo " not a sector; this is the covering-sector read, and if it moved"
|
||||
echo " then either the layout or scsi.i's window did. See FINDINGS 58.3."
|
||||
# DLX5 MAKES THESE THE SAME NUMBER, and that identity IS the finding (59.4,
|
||||
# and 58.3 option C): a sector-aligned container has no covering-sector read,
|
||||
# so the disc moves exactly the records and nothing else. Under DLX4 they
|
||||
# differed by 1.34% and both were gated so neither could drift into the other;
|
||||
# under DLX5 the gate is that they are EQUAL. If a windowed read ever came
|
||||
# back -- a container that was not aligned, or a layout that lost the
|
||||
# alignment -- the disc figure would exceed the ring figure and this goes red.
|
||||
grep -aq "SECTOR OVERHEAD: $EXPECT_B B off the disc for $EXPECT_B B of record = 0.00%" \
|
||||
tmp/p4b_check.log || {
|
||||
echo "FAIL: the disc no longer moves EXACTLY the records. On a sector-"
|
||||
echo " aligned container (DLX5) there is no covering-sector read at"
|
||||
echo " all, so these two counts must be the same $EXPECT_B B. If they"
|
||||
echo " differ, either the container lost its alignment or scsi.i is"
|
||||
echo " windowing again -- and a DMA channel cannot window (59.4)."
|
||||
exit 1; }
|
||||
grep -aq "ring: 18 wraps" tmp/p4b_check.log || {
|
||||
echo "FAIL: the placement policy tiled this container differently with a"
|
||||
@@ -574,4 +597,58 @@ else
|
||||
echo " (git clone --depth 1 https://github.com/icculus/DirkSimple)"
|
||||
fi
|
||||
|
||||
echo "--- session 29: the packed paint, and what it does to the codec (FINDINGS 61) ---"
|
||||
# tools/bench/blit.s gained V8/V9/V10 -- the packed full-frame blit, and the two
|
||||
# ways a 4x4 BLOCK decoder could survive the packed layout. 47.6.1 had filed the
|
||||
# packed paint's `movem` shape as an ASSUMPTION since session 16; this measures
|
||||
# it, in the same run as V1/V3/V4 so it is quoted against numbers that have not
|
||||
# moved since session 9.
|
||||
#
|
||||
# WHAT IS GATED IS STRUCTURAL, not numeric, for the reason the load stage gives:
|
||||
# MAME samples these on a 1/56.69 s clock and no cost model in the tree depends
|
||||
# on their exact value. What DOES depend on them is the ORDER, and the order is
|
||||
# the whole of FINDINGS 61:
|
||||
# V8 < V1 packing halves the full-frame literal paint
|
||||
# V9 > V4 packing makes a BLOCK decoder DEARER, not cheaper
|
||||
# V10 < V4 unless the blocks are paired, which costs SKIPs instead
|
||||
# A tree where any of those flipped has a different answer to 44.7 and should
|
||||
# say so out loud rather than let 29_packed_player.py narrate the old one.
|
||||
python3 tools/bench/prep_frame.py tmp/fr_00020 tmp/frame256.bin 0 --reserve-black
|
||||
rm -f tmp/blit_v8.log
|
||||
( cd tmp && SDL_VIDEODRIVER=dummy stdbuf -oL timeout -k 5 300 mame x68000 \
|
||||
-bios ipl10 -ramsize 2M -video soft -window -sound none -nothrottle -plugins \
|
||||
-autoboot_script ../tools/bench/blit.lua -seconds_to_run 120 \
|
||||
> blit_v8.log 2>&1 )
|
||||
grep -aq "summary (instruction cycles only" tmp/blit_v8.log || {
|
||||
echo "FAIL: the blit timing run produced no summary -- it did not finish."
|
||||
tail -8 tmp/blit_v8.log; exit 1; }
|
||||
python3 - <<'EOF' || exit 1
|
||||
import re, sys
|
||||
v = {}
|
||||
for line in open("tmp/blit_v8.log", errors="replace"):
|
||||
m = re.search(r"V(\d+)\s+(\d+) cyc", line)
|
||||
if m: v[int(m.group(1))] = int(m.group(2))
|
||||
need = (1, 2, 3, 4, 8, 9, 10)
|
||||
missing = [n for n in need if n not in v]
|
||||
if missing: sys.exit(f"FAIL: blit.lua reported no V{missing} -- run incomplete.")
|
||||
for a, op, b, why in ((8, "<", 1, "packing did not halve the literal paint"),
|
||||
(9, ">", 4, "packed BLOCK order came out CHEAPER than "
|
||||
"unpacked -- 61.3's conclusion is inverted"),
|
||||
(10, "<", 4, "pairing the blocks did not buy back the "
|
||||
"movem shape")):
|
||||
ok = v[a] < v[b] if op == "<" else v[a] > v[b]
|
||||
if not ok:
|
||||
sys.exit(f"FAIL: V{a} {v[a]:,} is not {op} V{b} {v[b]:,} -- {why}.")
|
||||
print(f" V1 {v[1]:,} / V8 PACKED {v[8]:,} = {100*v[8]/v[1]:.0f}% -- "
|
||||
f"and V3, the unpacked WRITE-ONLY floor, is {v[3]:,}")
|
||||
print(f" V4 {v[4]:,} / V9 packed-block {v[9]:,} = {100*v[9]/v[4]:.0f}% -- "
|
||||
f"packing costs a BLOCK decoder {100*v[9]/v[4]-100:.0f}%")
|
||||
print(f" V10 paired blocks {v[10]:,} = {100*v[10]/v[4]:.0f}% of V4, and pairing "
|
||||
f"is paid for in SKIPs")
|
||||
EOF
|
||||
python3 tools/analysis/29_packed_player.py "$DLX" > tmp/packed_player.log 2>&1 \
|
||||
|| { tail -20 tmp/packed_player.log; exit 1; }
|
||||
grep -aE "SKIP block PAIRS|free / DMAC->GVRAM / PACKED|^ CODEC, gate" \
|
||||
tmp/packed_player.log
|
||||
|
||||
echo "ALL GREEN"
|
||||
|
||||
Reference in New Issue
Block a user