Files
daedalus-fourier/docs/k3_mc_phase7.md
T
marfrit 2dd774a9ab Issue 003 closed: mixed-kernel M4 validates V4 deployment shape
bench_concurrent_mixed runs NEON-N on kernel A + QPU on kernel B
concurrently. Matrix on hertz:

  V3 (CPU MC + QPU MC same-kernel): CPU 22.64 + QPU 0.39 Mblock/s
  V4 (CPU MC + QPU LPF4):            CPU 27.87 + QPU 12.74 Medge/s
  V1 (CPU MC + NEON-fb CDEF):        CPU 24.49 + 1.75 Mblock/s CDEF
  V2 (CPU LPF4 + NEON-fb CDEF):      CPU 27.28 Medge + 1.70 Mblock/s

V4 is the daedalus-fourier deployment shape (CPU runs MC; QPU runs
LPF4 via cycle 2 GREEN offload). Both substrates productive; CPU
MC +23% per-core vs same-kernel V3 control. Same-kernel M4 in
cycles 1-5 was a worst-case contention bound, not a deployment
number — user's "5%/50%" framing was correct.

Cycle 3 MC verdict unchanged (QPU MC contributes ~0.4 under any
contention); cycle 5 CDEF deferred verdict softened to
opportunistic helper (NEON-fallback proxy used since cycle 5
Phase 6 not yet built).

- tests/bench_concurrent_mixed.c (configurable cpu-kernel /
  qpu-kernel matrix; supports MC, LPF4, LPF8, IDCT real QPU
  dispatch; CDEF uses NEON-on-core-3 fallback)
- CMakeLists.txt: build target wired with all FFmpeg + dav1d sources
- docs/issues/003-mixed-kernel-m4-bench.md: closure + matrix
- docs/k3_mc_phase7.md: M4 methodology caveat extended with V3/V4
- docs/k5_cdef_phase3_partial.md: deployment recommendation updated

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 13:44:08 +00:00

201 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
cycle: 3
phase: 7
status: closed 2026-05-18 — RED engineering / PASS 30fps-floor / M4 NEGATIVE
date_opened: 2026-05-18
date_closed: 2026-05-18
parent: k3_mc_phase4.md (revised per phase5''')
host: hertz
verdict: cycle 3 closes; MC stays on CPU for higgs deployment; engineering negative documented
---
# Cycle 3, Phase 7 — Verification (v1 + M4''')
## v1 first-light
```
=== v3d MC 8h bench ===
n_blocks: 65536 iters: 100
=== M1''': QPU vs C reference bit-exact ===
blocks bit-exact: 65536 / 65536 (100.0000 %)
=== M2''': QPU throughput ===
M2''' = 1.413 Mblock/s
per-block = 707.9 ns
per-dispatch = 46390.5 us
R''' = 0.067 → RED band
30fps@1080p floor: 1.5x margin (isolation)
```
shaderdb (v1 MC):
```
SHADER-DB-ffcca249...: 488 inst, 2 threads, 0 loops, 197 uniforms,
25 max-temps, 0:0 spills:fills, 0 sfu-stalls, 488 inst-and-stalls, 7 nops
```
**Phase 5''' finding 2 prediction confirmed**: filter LUT inflated
uniforms to 197 (gate was at ~144). Compiler also forced to 2 threads
(from cycle-2's 4) due to register pressure (25 max-temps vs cycle-2's
21). The "no DP4A" structural deficit shows up directly here — 8
SMUL24 + 7 ADD per output pixel × 64 pixels per block × 8-lane
geometry = 488 instructions, 30× heavier than the LPF kernel.
## M4''' concurrent matrix (8s windows)
| Config | Mblock/s | per-core (NEON) | vs NEON-4 | 30fps |
|---|---|---|---|---|
| NEON 1-core | 14.479 | — | — | 14.9× |
| **NEON 4-core** | **15.248** | 3.24 4.48 | **baseline** | 15.7× |
| QPU only | 1.380 | — | — | 1.4× |
| **Mixed NEON-3 + QPU** | **12.277** | 3.78 4.16 | **19.5 %** | 12.6× |
| Mixed NEON-4 + QPU | 12.158 | 2.49 3.35 | 20.3 % | 12.5× |
**M4 gate: FAIL.** Mixed (12.28) < pure NEON-4 (15.25) by 2.97
Mblock/s. The QPU's 0.45 Mblock/s contribution under contention
doesn't compensate for losing one NEON core that delivers ~3.8.
## Cross-cycle comparison
| | Cycle 1 IDCT | Cycle 2 LPF | Cycle 3 MC |
|---|---|---|---|
| R isolation | 0.92 | 0.41 | **0.067** |
| 30fps floor margin (isolation) | 7.9× | 10× | **1.5×** |
| M4 mixed vs pure NEON-4 | +7.2 % | +6.9 % | **19.5 %** |
| 30fps floor margin (mixed) | 7.2× | 7.2× | **12.6×** |
| Verdict for higgs | GO QPU | GO QPU | **STAY CPU** |
| NEON 4-core scaling vs 1-core | 0.56× (bw-bound) | 0.82× (bw-bound) | **1.05× (compute-bound)** |
The MC result is **structurally consistent** with the V3D substrate
profile from `phase0.md`:
- No DP4A → 8-wide convolution doesn't pack as it does on NEON SDOT
- Filter coefficients drive uniform count high → register pressure → 2 threads
- High per-output-pixel multiply count → compiled instruction count
3× cycle 1, 6× cycle 2
NEON 4-core is *compute*-bound for MC (not bandwidth-bound like
the other two kernels). So 4-core scales nearly linearly with cores —
the NEON CPU has plenty of headroom and the QPU has nothing to add
even in concurrent mode.
## Deployment recipe (for higgs / libva-v4l2-request-fourier)
Per `project_consumer_target.md`, the eventual integration target is
V4L2 stateless → libva-v4l2-request-fourier → firefox-fourier. The
back-end-on-QPU/CPU split for the consumed decoder pipeline:
- **IDCT (cycle 1)** → QPU. R = 0.92, +7 % mixed, frees a CPU core.
- **LPF (cycle 2)** → QPU. R = 0.41, +7 % mixed, frees a CPU core.
- **MC (cycle 3)** → **CPU NEON baseline; QPU offload viable as
opportunistic helper, not yet measured.** R = 0.067 in isolation
was discouraging; M4 same-kernel mixed was 19.5 % which looks
conclusive but isn't — see *M4 methodology caveat* below.
- **Entropy** (VP9 Bool / AV1 ANS) → CPU. Structurally serial.
This is a **mixed-substrate deployment**, not a "QPU does everything"
plan. Realistic for higgs: entropy + MC on 2-3 ARM cores; IDCT + LPF
dispatched to QPU concurrently; 1-2 ARM cores left for vscode / etc.
## M4 methodology caveat (added 2026-05-18 after cycle 5)
The M4 mixed bench (`bench_concurrent_mc.c`) tests NEON-3 + QPU
running the SAME kernel concurrently. This is the **worst case** for
memory-bandwidth contention — both substrates competing for the same
bus with the same access pattern.
A real decoder pipeline has different shape: CPU runs entropy + MC
+ other CPU-bound work; QPU runs IDCT + LPF + (potentially) MC as
opportunistic helper. **Different kernels on different substrates**
contend less than same-kernel-on-both. Our M4-same-kernel result is
a pessimistic lower bound, not the actual deployment number.
Empirically supporting this: cycle 3 M4 showed per-core NEON
throughput in 3-core mode (3.78-4.16 Mblock/s) was higher than in
4-core mode (3.24-4.48), confirming bandwidth saturation at ≥4
cores. So freeing 1 core via QPU offload costs ~25 % of total NEON
MC throughput, but the QPU contributes 0.45 (-MC) or 1.4 (in CDEF
isolation) on top.
**To rigorously test the helper hypothesis**: see
`docs/issues/003-mixed-kernel-m4-bench.md`. A bench that runs
NEON-3 on kernel-A + QPU on kernel-B concurrently would close the
question. ~½ day of additional bench work; would update the
deployment recipe for cycles 3 + 5 if the result is positive.
### Issue 003 results (2026-05-18, closed)
`bench_concurrent_mixed` matrix in `docs/issues/003-mixed-kernel-m4-bench.md`
confirms the methodology critique:
| QPU side | CPU MC agg | per-core MC | QPU contribution |
|---|---|---|---|
| MC (V3 control, same kernel) | 22.64 Mblock/s | 7.5 avg | 0.39 Mblock/s MC |
| LPF4 real QPU (V4) | **27.87 Mblock/s** | **9.3 avg** | **12.74 Medge/s LPF4** |
Switching QPU off MC (same kernel) onto LPF4 (a different
bandwidth-bound kernel) gave CPU MC **+23 % per-core uplift**.
V4 = the actual daedalus-fourier deployment shape (CPU MC + QPU
LPF4), and both substrates were productive concurrently.
**Cycle 3 MC verdict unchanged**: QPU MC contributes ~0.4
Mblock/s under any contention scenario (V3, V5). The 4 NEON cores
do MC dramatically better. **MC stays on CPU.** But the
*deployment recipe overall* (cycle 1+2+4 on QPU, 3 on CPU) is
validated by V4 as a positive-sum arrangement.
## Decision per Phase 1 rules + 30fps-floor calibration
| Rule | Result | Status |
|---|---|---|
| M1''' bit-exact | 100.0000 % | ✓ PASS |
| R''' = M2'''/M3''' | 0.067 (RED) | structural mismatch |
| M4''' > pure-CPU 4-core | 19.5 % | ✗ FAIL gate |
| 30fps@1080p floor (isolation) | 1.5× | ✓ PASS (user-facing) |
| 30fps@1080p floor (mixed) | 12.6× | ✓ PASS (user-facing) |
**Engineering cycle verdict: do not deploy MC on QPU; deploy on CPU.**
**User-facing cycle verdict: 30fps floor easily met in any
configuration; either path works for daily YouTube.**
For the deployment recipe above, **MC stays on CPU**. The Phase 1
ORANGE/RED "honest close" rule applies here: cycle 3 closes as a
documented negative for this kernel without affecting the
project-level "continue" verdict (cycles 1+2 GO results stand).
## Phase 9 lessons (added to project memory)
1. **Multiply-heavy workloads expose V3D's no-DP4A deficit** in a way
that cycle 1+2 didn't. CPU SDOT/UDOT pack 4 INT8 MACs in one
instruction; V3D's SMUL24 is one scalar mult at a time. The 4×
gap shows up directly as a 6-15× per-block slowdown.
2. **Compute-bound CPU workloads make the QPU offload story collapse.**
When NEON 4-core scales near-linearly (not bandwidth-saturated),
the "freed-core" argument from cycle 1+2 doesn't apply — there
are no free cycles to free. Mixed mode is strictly worse.
3. **The 30fps@1080p user-facing test (`project_30fps_floor_is_fine.md`)
passes regardless of engineering verdict.** All three cycles pass
it in isolation. This is a project-level win to communicate
separately from per-cycle engineering R numbers.
4. **The shaderdb filter-LUT gate from phase5''' finding 2 fired
exactly as predicted** (197 uniforms > 144 threshold; 2 threads
instead of 4). This validates the cycle-discipline of running
`V3D_DEBUG=shaderdb` early and using the result as an actionable
gate. Cycle 4 (if any) should bake this in from Phase 4 §design.
## Leaves open
- Cycle 3 v2 with filter LUT escalated to SSBO (per phase5''' finding 2
trigger). Would reduce uniforms to ~30, potentially restore 4
threads. Expected upside: ~2× → R''' = 0.13. Still RED, still M4-
negative. Skipped — even doubling doesn't change the deployment
recipe.
- Vertical / hv / 4-tap / wider variants — all of cycle 3 same
multiply-shape, same structural verdict expected. Not worth Phase
1+ for those.
- Cycle 4 candidates (per phase7_M4.md §"Cycle 3 candidates"):
CDEF (AV1-only directional filter), Loop Restoration (AV1-only),
or higgs deployment plumbing.