Repository navigation
v0.7.0 — the movement was the cost, not the arithmetic
Two passes folded away, bit for bit
Synthesize2D_97_WithDims is 48% of the heaviest page in the corpus, and the
arithmetic is the small part of it:
1.12 s flat in Synthesize2D_97_WithDims |
the gather and scatter |
0.45 s liftstep97_c_f64_neon |
the lifting, NEON assembly |
0.40 s BaseInterleave_fallback_Float64 |
the interleave, pure Go |
0.30 s runtime.memmove |
the two copies |
0.23 s scaleslice_c_f64_neon |
the scaling, NEON assembly |
1.82 s of moving data against 0.68 s of computing it. Two passes carry no
arithmetic of their own and are now folded into the passes either side: the
scaling into the read-out of each subband (a copy then *= K is the same
single multiply as = data[i] * K), and the interleave, in the vertical pass,
into the scatter.
Measured
min-of-5, two interleaved rounds, on the three heaviest JPEG 2000 pages, against
a ±1% noise floor:
| document | before | after | |
|---|---|---|---|
b31820797.pdf |
786.3 ms | 721.2 ms | −7.7% |
bulletinchicagov48nchicg.pdf |
657.7 ms | 636.7 ms | −4.4% |
irrigationrequir1340fort.pdf |
404.7 ms | 388.5 ms | −3.4% |
Unchanged output
All 3 215 corpus documents render byte-identical. TestFewerPassesIsBitIdentical
compares the new synthesis against the shape it had before in exact float64
bits, over twelve geometries including odd sizes and both parities — and it runs
on all six architectures, so the fold is exact on big-endian s390x and on 32-bit
too, where the lifting has no assembly path at all.
Two things measured and NOT done
- A fused kernel in scalar Go (one call over six passes instead of seven calls
over nine) is 1.5× to 1.8× slower. The library's lifting is NEON assembly
with FMA and losing it costs more than the passes save. The same FMA makes that
path unreproducible in Go: the identical expressions differ by 1 to 16 ulp. BaseInterleaveruns the pure-Go fallback on arm64 — the generated NEON
variant exists and is never assigned. Benchmarked head to head, it makes no
difference: both run at 25–28 GB/s, which is memory bandwidth. An interleave is
pure movement; the answer is to remove the pass, not vectorise it.
Also takes go-highway v0.0.12, eight versions newer than what this package was
pinned to. Nothing was updating it.