|
| 1 | +# FFTW |
| 2 | + |
| 3 | +[FFTW](https://www.fftw.org/) 3.3.10 with the **RISC-V Vector (`r5v`) SIMD backend** — a clean A/B against a scalar build of the *same source* with identical compiler and flags. The only variable is `--enable-r5v` (from [rdolbeau's `r5v-test-release-005`](https://github.com/rdolbeau)). |
| 4 | + |
| 5 | +Benchmark source: [opensolvers/benchmarks/fftw](https://github.com/opensolvers/benchmarks/tree/main/fftw) — `build-fftw-r5v.sh` and `bench-fftw-ab.sh`. |
| 6 | + |
| 7 | +Relevant to [Quantum ESPRESSO](../apps/qe.html): plane-wave DFT spends a large fraction on FFT (`vloc_psi`, `fftw` timers). A FlexiBLAS swap does not touch FFT — tuning FFTW separately is how that half of the run moves. |
| 8 | + |
| 9 | +## Orange Pi RV2 (SpaceMiT X60, 1 thread) |
| 10 | + |
| 11 | +EESSI `2025.06-001`, GCC 14.3.0, `-O3 -march=rv64imafdcv_zvl256b`. 1D complex-to-complex via FFTW's own `tests/bench`, `-t 1.0`. |
| 12 | + |
| 13 | +### The RVV backend is real |
| 14 | + |
| 15 | +| Build | Library size | RVV instr count | Codelets in plan | |
| 16 | +| ----- | -----------: | --------------: | ---------------- | |
| 17 | +| **r5v** (`--enable-r5v`) | 11 MB | **224,354** | `n1fv_16_r5v256`, `t3fv_4_r5v256`, … | |
| 18 | +| **scalar** (control) | 924 KB | 734 | (none) | |
| 19 | + |
| 20 | +The r5v library emits **~305×** more vector instructions than scalar, and FFTW's planner actually selects `*_r5v256` codelets (confirmed via `bench -v2`). |
| 21 | + |
| 22 | +### Performance — `FFTW_MEASURE` default |
| 23 | + |
| 24 | +Median MFLOPS; higher = faster. Under the **`FFTW_MEASURE`** planner (the default when no `-o` is passed), r5v beats scalar at every size: |
| 25 | + |
| 26 | +| size | estimate r5v / scalar | **MEASURE r5v / scalar** | **r5v speedup** | |
| 27 | +| ---: | --------------------: | -----------------------: | --------------: | |
| 28 | +| 256 | 2228 / 1388 | **2520 / 1579** | **1.60×** | |
| 29 | +| 1024 | 717 / 747 | **1642 / 1265** | **1.30×** | |
| 30 | +| 4096 | 303 / 360 | **1283 / 978** | **1.31×** | |
| 31 | +| 16384 | 381 / 276 | **964 / 797** | **1.21×** | |
| 32 | +| 65536 | 148 / 142 | **797 / 752** | **1.06×** | |
| 33 | +| 262144 | 171 / 138 | **717 / 664** | **1.08×** | |
| 34 | + |
| 35 | +Largest gain on cache-resident transforms (**1.60×** @ N=256); tapers to **~1.06×** as transforms become memory-bandwidth-bound (≥64K). |
| 36 | + |
| 37 | +## Planner choice matters more than codelets |
| 38 | + |
| 39 | +The biggest lever on this hardware is **planner choice** — worth **3–5×**, independent of RVV. `FFTW_ESTIMATE` grossly under-plans large transforms: |
| 40 | + |
| 41 | +| size | estimate → MEASURE (r5v) | gain | |
| 42 | +| ---: | -----------------------: | ---: | |
| 43 | +| 4096 | 303 → 1283 | **4.2×** | |
| 44 | +| 16384 | 381 → 964 | **2.5×** | |
| 45 | +| 65536 | 148 → 797 | **5.4×** | |
| 46 | +| 262144 | 171 → 717 | **4.2×** | |
| 47 | + |
| 48 | +`patient` was within noise of `MEASURE` where it completed, but planning time blows up at large N (>35 min at N=262144). **`FFTW_MEASURE`** (or cached wisdom) is the sweet spot — never `FFTW_ESTIMATE` on the X60/K1. |
| 49 | + |
| 50 | +### Methodology trap |
| 51 | + |
| 52 | +A first pass with `estimate` and `-t 0.3` appeared to show a **2× RVV regression** at N=262144. With honest timing, r5v is faster under both planners (717 vs 664 MFLOPS under MEASURE). Pin the planner and use **≥1 s** timing before trusting any single FFT A/B point. |
| 53 | + |
| 54 | +## Reproduce |
| 55 | + |
| 56 | +```bash |
| 57 | +./build-fftw-r5v.sh # needs $HOME/fftw-r5v.tar.gz on the board |
| 58 | +./bench-fftw-ab.sh # writes fftw-proper.log |
| 59 | +``` |
| 60 | + |
| 61 | +**Gotcha (Orange Pi RV2):** `module load GCCcore/14.3.0` does not repath `gcc` — EESSI's compat GCC 13.4.0 keeps winning. Prepend the real GCC 14 bindir explicitly (see `build-fftw-r5v.sh`). On [Banana Pi F3](../boards/F3.html) the plain `module load GCC/14.3.0` repaths correctly. |
0 commit comments