@@ -146,12 +146,71 @@ cells only, boundary 0, DRAM flat at ~3 passes.
1461465 . ** Small-N (N ≤ leaf) stays on the current in-cache vectorized stages** — it
147147 is already fine there and needs no blocking.
148148
149- ## Status
150-
151- Corrected: the transpose-four-step is retired (fails transport conservation +
152- introduces complex arithmetic Bruun does not need). The real diagonal walk
153- ` phase_fft_real ` is the target — exact r2c, real cells only, boundary transport
154- 0 . The remaining build is the DEPTH-FIRST CACHE-BLOCKING of that walk (interior
155- log N → ~ 2 passes) with natural order preserved at both ends; the vectorized
156- real cells and the ordering theorem are in hand. ` experiments/dip_phase_packet.py `
157- (the four-step prototype) is kept only as the retired reference.
149+ ## SHIPPED (2026-07-05): the in-place diagonal span walk
150+
151+ The C++ that landed in ` src/detail/bruun_dip_kernel.hpp ` supersedes both the
152+ Python four-step prototype AND the self-sorting variant above. The realization
153+ that unlocked it: writing each cell's two children INTO THE PARENT'S OWN SPAN
154+ makes every span self-contained forever — fully in-place (work = n, down from
155+ 2n; no ping-pong, no scratch, concurrency-safe), depth-first (cache transition
156+ emergent, no block knobs), the Nyquist-promotion copy free, and the SIMD purely
157+ vertical (4/8 contiguous streams, broadcast twiddles, zero permutes; radix-4
158+ fused two-level cells above the boundary granularity, ` norm2_fused ` -shape).
159+
160+ The boundary (the user's dual-polarity insight, validated hard): pay the
161+ long-range disorder as COMB STREAMS at both ends, confine all scramble to L1.
162+ The leaves of any subtree ` (d, E) ` are the bins ` {jE ± d} ` (two combs), and
163+ the tree-order → bin-order permutation within a subtree is UNIVERSAL
164+ (d-independent; leaf value = ` m·E + s·d ` with ` (m,s) ` path-only), so one tiny
165+ shared table ` T_w ` per span size drives a streaming per-subtree egress
166+ (forward) / ingress (inverse). Asymmetries that measurement forced:
167+ - inverse ingress = comb reads + L1 scatter (a separate injection pass and a
168+ fused per-leaf gather both lose);
169+ - forward egress = L1 gather + comb writes, with a radix-2 parity step so the
170+ RFO-paying writes land on the densest combs the L1 span budget allows (the
171+ inverse skips the parity step — reads prefetch at any density);
172+ - seed at level 8, not 16: 16+16 power-of-two-strided streams alias L1 sets
173+ past associativity (measured 9× the 8-stream seed at 1M).
174+
175+ Measured vs DIF (M-series NEON, min-of-5, ` dif_vs_dip_benchmark ` ):
176+
177+ | n | fwd DIP/DIF | inv DIP/DIF |
178+ | ---| ---| ---|
179+ | 1024 | 1.28 | 1.00 |
180+ | 4096 | ~ 1.1–1.5 | ** 0.57–0.89 (wins)** |
181+ | 65536 | 1.56 | 1.10 |
182+ | 262144 | ~ 2.3 | 1.11 |
183+ | 1048576 | 1.89 | 1.17 |
184+ | 4194304 | 2.22 | 1.65 |
185+
186+ Starting point was fwd 2.6×/inv 1.6–2.4× (breadth-first ping-pong). The
187+ inverse is at DIF parity (or wins) through 1M.
188+
189+ ### Forward optimization pass (2026-07-05)
190+
191+ Two wins landed, both grounded by isolation profiling (` headcmp ` /` wcmp `
192+ harnesses, in-process back-to-back to cancel this machine's severe thermal
193+ noise — DIF-ratio benchmarks swung ±30% run-to-run and could not be trusted):
194+ - ** ` phase_table_index ` divide → shift.** ` d*n/(2e) ` was a 64-bit ` sdiv ` at
195+ every node; ` 2e ` is always a power of two and exactly divides ` d*n ` , so it is
196+ ` (d*n) >> (ctz(e)+1) ` . (Index compute was NOT the dominant cost — ` noidx `
197+ ≈ ` nocells ` — but the sdiv still cost real cycles at small/mid n.)
198+ - ** Inline the ` span8 ` leaf codelets** (` BRUUN_ALWAYS_INLINE ` ). They were real
199+ calls; inlining removed the leaf-call overhead. Net: 4096 forward 1.5→1.11×.
200+
201+ What profiling RULED OUT (don't retry):
202+ - ** Egress is cheap** — isolating it (` wcmp ` ) shows 0–11% of the forward,
203+ mostly noise; it is NOT the gap. A split-comb (two monotonic streams) egress
204+ measured a dead wash back-to-back.
205+ - ** The WALK is the whole forward cost** , and the forward walk is ~ 35% slower
206+ than the inverse walk at 64K (both cache-resident, same cell count) yet
207+ converges by 4M — i.e. a COMPUTE/scheduling asymmetry in the forward cell's
208+ dependency chain (` cell4_fwd_ip ` ), not transport. It hides once DRAM-bound.
209+ - The forward radix-2 parity step at ` 2*kEgressW ` is net-neutral (its
210+ egress-density rationale is void now that egress is cheap); kept only because
211+ removing it is within noise and changes span sizing.
212+
213+ Remaining forward levers (larger efforts, uncertain payoff on this noisy box):
214+ flatten the recursion into a DIF-style precomputed op schedule (kills the
215+ residual call overhead), or restructure ` cell4_fwd_ip ` to shorten its two-level
216+ critical path (the 64K compute asymmetry). The inverse needs nothing.
0 commit comments