mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-10-10 08:03:04 -04:00
Cuts realtime Opus decode on the Sansa e200v1 (PP502x, ARM7TDMI) from 55.55 MHz to 52.1 MHz. Two exact changes to celt/kiss_fft.c first: - kf_bfly5 folds the four cosine products into a shift and a single multiply. cos(2*pi/5) + cos(4*pi/5) is exactly -1/2, and the Q15 constants satisfy that identity exactly (10126 - 26510 == -16384), so the substitution gives up no accuracy. - kf_bfly3, kf_bfly4 and kf_bfly5 peel the pass that twiddles by twiddles[0], which is 1, by rotating the loop rather than duplicating the body. In fixed point twiddles[0] is 32767 rather than 32768, so skipping it also drops a small systematic gain error. Then celt/arm/kiss_fft_armv4_asm.S replaces the radix-3, radix-4 and radix-5 bodies, reached through OVERRIDE_kf_bfly3/4/5. The compiled kernels spill their loop-invariant pointers and reload them every pass, and gcc will not form ldm/stm from contiguous C accesses: it reorders the loads while scheduling and does not hand out ascending register pairs. The assembly keeps the bookkeeping resident and sends the transient butterfly values to the frame instead, in bursts. Over 160 ms of stereo music, traced under qemu and costed with an ARM7TDMI model: FFT cycles 1,876,926 -> 1,430,748 -23.8% whole decode 8,142,054 -> 7,695,876 -5.5% loads 769,935 -> 650,157 -15.6% stores 409,999 -> 350,605 -14.5% multiplies 350,909 -> 337,493 -3.8% text 3,368 -> 2,656 bytes The radix-5 fold accounts for the whole multiply reduction. The assembly leaves the count untouched and wins purely on memory traffic. Accuracy improves by up to 2.9 dB rather than degrading, because the assembly keeps all 32 bits of each Q15 product where MULT16_32_Q15_armv4 drops the low bit. Decoded output differs from the C build in 27 of 15,360 samples, each by one LSB. Build with OPUS_ARM_NO_FFT_ASM to select the C butterflies instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Change-Id: I2e8a0904da8a85b654ff648a01234348977a0edc |
||
|---|---|---|
| .. | ||
| arm_support | ||
| fixedpoint | ||
| libsetjmp | ||
| microtar | ||
| mipsunwinder | ||
| rbcodec | ||
| skin_parser | ||
| tlsf | ||
| unwarminder | ||
| utf8proc | ||