Skip to content

dsp: optimize fixed half-band SIMD kernels#246

Merged
arancormonk merged 2 commits into
mainfrom
perf/simd-halfband-decimators
Jul 17, 2026
Merged

dsp: optimize fixed half-band SIMD kernels#246
arancormonk merged 2 commits into
mainfrom
perf/simd-halfband-decimators

Conversation

@arancormonk

Copy link
Copy Markdown
Owner

Summary

  • add fixed 15- and 31-tap complex half-band decimators for AVX2, SSE2, and NEON
  • process the vector interior directly from input with complete load-footprint guards
  • keep scalar boundary handling for history-dependent prefixes, repeated-last suffixes, and vector remainders
  • preserve the scratch-backed generic SIMD path for other odd tap counts, including 23 taps
  • add explicit 15/31-tap benchmarks and a realistic 8192-complex-input, five-stage 32× cascade benchmark
  • expand direct-backend coverage for alignment, short/odd blocks, history continuity, tail extension, invalid inputs, and the 31/15/15/15/15 cascade

Why

The 1.536 MS/s to 48 kHz RTL path uses one 31-tap stage followed by four 15-tap stages. The generic SIMD kernels copied the full interleaved input into scratch storage and scalar-packed decimated complex samples before doing relatively little half-band arithmetic. Fixed-size kernels can instead load alternating complex samples directly and fully unroll the side taps while retaining the existing phase, output sizing, history layout, and edge behavior.

Performance

Five-repeat median comparisons on the x86 host:

Case AVX2 reduction SSE2 reduction
15 tap 65.7% 61.7%
31 tap 61.9% 58.4%
five-stage 32× cascade 63.2% 59.6%

Instruction counts fell by roughly 75% for AVX2 and 67–68% for SSE2 in the targeted cases. No unrelated DSP benchmark exceeded the 5% regression threshold. NEON timing is intentionally omitted because emulation is not representative of physical ARM performance.

Validation

  • ctest --preset dev-debug --output-on-failure: 460/460 passed
  • focused ASan/UBSan SIMD FIR suite: passed
  • AArch64 warning-as-error cross-build and full SIMD FIR suite under QEMU: passed
  • tools/preflight_ci.sh: passed
  • exact-sized, aligned, and deliberately unaligned input/output/history buffers
  • canonical and synthetic 15/31-tap coefficient arrays
  • variable multi-block streams, zero-output blocks, last-sample extension, invalid guards, and generic 23-tap fallback
  • stage-by-stage scalar comparison for the five-stage cascade

Physical NEON hardware timing and the live RTL/P25 capture run remain to be confirmed on suitable hardware.

Signed-off-by: arancormonk <180709949+arancormonk@users.noreply.github.com>
Signed-off-by: arancormonk <180709949+arancormonk@users.noreply.github.com>
@arancormonk
arancormonk marked this pull request as ready for review July 17, 2026 03:47
@arancormonk
arancormonk merged commit b3484ee into main Jul 17, 2026
40 checks passed
@arancormonk
arancormonk deleted the perf/simd-halfband-decimators branch July 17, 2026 03:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant