An exporation in FFT implementation using Rust+WASM+SIMD.
⚠ SIMD does not yet have support in every modern browser. Be sure to use a browser that supports WASM SIMD.
- Get a punchy audio file ready to upload
- Open the webpage
- Click the bubble on the left to select an audio file to play
- Click Play ▶ on the audio widget
The calculation time of each algorithm is shown in the upper left with matching color to its plot. The white plot is the FFT plot given by the browser's audio AnalyzerNode as reference.
In this project, I implement a basic FFT algorithm using WASM SIMD instructions (std::arch::wasm32
).
For example, here is the function for multiplying 2 pairs of complex numbers in parallel using f32x4
vectors:
wasm-simd-audio/wasm-audio/src/simd_cooley_tukey2.rs
Lines 47 to 90 in 76f824d
Although SIMD instructions do allow much faster computation throughput, they do require extra instructions for loading values in and out of the vectors. In my case, one of my SIMD implementations barely matches my naive implementation, and is still 2x slower than the rustfft
crate:
It seems that, at least with the basic Cooley-Tukey algorithm, using SIMD for just inside the body of the loop introduces too much overhead to see much improvement, especially compared to normal optimization. I tried keeping the intermediate values as v128
vectors to save some conversion (see simd_cooley_tukey3.rs
), but it didn't seem to have much effect.
- Compare generated WASM instructions to see how wasm-pack is optimizing. The
wasm32
instructions might be preventing some compiler optimizations. - Look into SFFT implementation.
- Move WASM code to worker node. Currently the FFTs are evaluated in the main thread. This requires manually sending the WASM binary blob to the worker thread at runtime.
To start:
npm run dev
vscode: in the workspace settings.json
, set the target to wasm32:
"rust-analyzer.cargo.target": "wasm32-unknown-unknown"
wasm-opt issue: If you get an error about wasm not being optimized, then install
latest version of binaryen and put it
in your PATH
. It will work without, but the benchmark will be wrong.
(more info)
⚠ Be sure you don't have any
wasm-opt
errors (see above)!
Github pages:
npm run deploy