1347fb961c
PR #36 reported a 4.30x QPU-over-CPU win for the H.264 1080p hot-path sum. That number was a measurement artifact. This commit makes the artifact impossible to reproduce by ANYONE running the bench again. THE BUG ------- v3d_runner read_spv() did fopen(spv_path, "rb") with no path search: the caller passes a bare filename like "v3d_h264_idct4.spv" and fopen resolves it relative to cwd. The cmake build puts SPVs in $builddir (e.g. ~/src/daedalus-fourier/build/), but the bench (and test_api_h264) were typically invoked from ~/src/daedalus-fourier/, so fopen failed. On failure read_spv printed perror and returned NULL; pipeline create then returned -1; dispatch then returned -1; the bench loop ignored the return value and timed the failure path. Each iter cost ~1-5 µs (open + perror + return), which divided across 256 ops gave ~10-20 ns/op — looking convincingly like real-but-fast QPU work. PR #36's "QPU 2.47 ns/op" for IDCT 4x4 was that artifact. PR #10's much-slower "QPU 37.77 ms" measurement was REAL (SPV apparently found that time, perhaps run from build/), so the artifact is what made it look like the gap had closed. The gap never closed. CORRECTED NUMBERS ----------------- Run from hertz (Pi 5 V3D 7.1, 30 iters x 5 warmup) AFTER this commit: kernel CPU ns/op QPU ns/op winner IDCT 4x4 luma 10.75 217.63 CPU 20.24x IDCT 8x8 luma 29.69 785.94 CPU 26.47x Deblock luma_v 17.63 467.42 CPU 26.51x Deblock luma_h 38.30 498.53 CPU 13.02x qpel mc20 (8x8) 30.17 1300.44 CPU 43.10x qpel mc02 (8x8) 17.69 1363.40 CPU 77.08x qpel mc22 (8x8) 71.60 1948.37 CPU 27.21x 1080p worst-case sum (IDCT4 + deblock luma + qpel mc22): CPU NEON only: 5.57 ms QPU only: 123.54 ms Ratio: CPU/QPU sum = 0.05x (QPU 22x SLOWER than CPU) QPU is currently 12-77x slower per kernel. The post-buffer-pool / post-persistent-cmdbuf dispatch overhead (tasks #160, #161) did NOT close the gap with NEON. Whether those tasks helped at all needs re-measurement — the previous "we saw a big win" reading was the same artifact. PR #36's commit-message claim "PR #10's verdict is reversed" is withdrawn. PR #10 was right; PR #36 was wrong. THE FIX ------- Two changes: 1. v3d_runner: SPV search now tries, in order: - cwd (legacy) - $DAEDALUS_SHADER_DIR (env override) - <readlink /proc/self/exe>/.. (binary-relative) - /opt/fourier/share/daedalus-fourier/ (Pi 5 install) - /usr/share/daedalus-fourier/ (system-wide) Found-anywhere succeeds silently. Found-nowhere prints one error naming all searched locations. 2. bench_h264_primitives: bench_fn now returns int. bench_ns does a single preflight call; if rc != 0 it prints "DISPATCH FAILED rc=N — kernel skipped" and bails on the kernel. Main loop counts QPU failures and exits 2 BEFORE printing the comparison table if any kernel failed — so the next person running this can't read fail-fast timings as substrate numbers. POLICY IMPLICATIONS ------------------- The QPU substrate decree (2026-05-23) was conceived as a policy choice that overrides per-kernel measurement. With the corrected data the gap is not "fixable defect we'll close with one more optimization", it's an order of magnitude. Whether to keep the decree, soften it (auto = QPU only where measured advantage), or revert is now a clear-eyed decision for the user. This commit doesn't change the recipe table — that's a separate question, taken on its own merits with this data in hand. Related: marfrit-packages PR #104 (libavcodec ctx flipped no_qpu → qpu-capable) was justified by PR #36's artifact and should be reverted; that revert lands in a follow-up to marfrit-packages.