code wiki / (root) / _fft256_q15_throughput_bench.nx

_fft256_q15_throughput_bench.nx

buildroot/runtime/_fft256_q15_throughput_bench.nx

8153 B210 linesdepth 2pulls 2 transitivereach 0 importersview sourcekind bench
docsdependenciesstructsconstsfunctions

about

_fft256_q15_throughput_bench.nx -- 256-point Q15 FFT throughput. THE primary W1 (automotive sensor / leak detection) workload baseline per WORKLOAD_TARGETS.md. Acoustic leak detection, brake pressure analysis, battery thermal classification, motor vibration FFT-fingerprinting -- every one of these starts with a real-input FFT in the 256..2048-point range. Q15 fixed-point (16-bit signed in -1.0..+1.0 range): the industry default for low-power DSP per ARM CMSIS-DSP, TI C5000, and every automotive sensor MCU. NishiLang has no native fp, so Q15 is also a natural fit for the substrate. Algorithm: Cooley-Tukey radix-2 decimation-in-time (DIT). In-place 256-point complex FFT. Twiddle factors generated iteratively at startup via the angle-addition formula: cos(t+dt) = cos(t)*cos(dt) - sin(t)*sin(dt) sin(t+dt) = sin(t)*cos(dt) + cos(t)*sin(dt) so we hard-code ONE step (cos/sin of 2*pi/256) and grow the table. Bench: 1000 iterations of 256-point FFT. Reports FFTs/sec + per-FFT latency in microseconds. Reference targets: ARM CMSIS-DSP (Cortex-M4 @ 100 MHz, SIMD) ~50K FFTs/sec FFTW double precision (modern x86_64) ~100K FFTs/sec Pure-software (this bench) ~1-10K FFTs/sec est CUDA cuFFT batched ~10M FFTs/sec Silicon-feedback consumption: rv64im_min_hot_report.nx attribution over this bench identifies which functions dominate (likely the butterfly inner loop's multiply + accumulate). PROP_MAC_FUSED silicon candidate from rv64im_min_hot_report.nx (3000 gates, 2x speedup) is the prime addition target -- THIS bench is the evidence base for that decision. Status: SEED. 2026-05-26. Single-stage radix-2; future commits add split-radix (~40% fewer multiplies) + the SIMD-vector emit variant when V-ext silicon candidate lands.

dependencies 1 imports · 0 importers

nx_syscalls.nx _fft256_q15_throughput_bench.n

imports: nx_syscalls.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main sys_mmap nx_fft_gen_twiddles nx_fft_sar15 nx_fft_radix2 nx_fft_bit_reverse_permute nx_fft_bit_reverse_8 nx_fft_sar15 ↻

structs

none

consts

41const NX_FFT_N: i64 = 256
42const NX_FFT_LOG2_N: i64 = 8
43const NX_FFT_Q15_ONE: i64 = 32767
44const NX_FFT_ITERS: i64 = 1000
47const NX_FFT_COS_STEP: i64 = 32757
48const NX_FFT_SIN_STEP: i64 = 804

functions

56func nx_fft_sar15(v: i64) -> i64
69func nx_fft_gen_twiddles(cos_tab: *i64, sin_tab: *i64) -> i64
called by 1: main calls 1: nx_fft_sar15
89func nx_fft_bit_reverse_8(x: i64) -> i64
103func nx_fft_bit_reverse_permute(re: *i64, im: *i64) -> i64
called by 1: nx_fft_radix2 calls 1: nx_fft_bit_reverse_8
126func nx_fft_radix2(re: *i64, im: *i64, cos_tab: *i64, sin_tab: *i64) -> i64
163func main() -> i64