你手机收到的每一个 5G 符号,都是 2048 个子载波叠在一起的一团噪声,接收端要靠一次傅里叶变换把它们拆开——而且必须在 71.4 微秒内做完,因为下一个符号已经在路上了。下面这个开关把 FFT 换成按定义写的 DFT。
把 fft(x) 换成按定义写的双重和 dft(x)。不是稻草人:这份 DFT 的旋转因子是预先算好放进表里的,内层只有乘加,和 FFT 一样公平。
两条路算出来的是同一个答案——n = 256 上最大差 8×10⁻¹⁴,纯粹是浮点舍入。DFT 没有算错,它只是慢。
5G 的一个 OFDM 符号是 1/15 kHz = 66.7 μs,加上循环前缀约 71.4 μs,每秒 14006 个。变换做不完,下一个符号已经来了——这不是等一会儿的事,是数据直接丢掉。
2048 点:FFT 要 11 264 次复乘,DFT 要 4 194 304 次。要卡进 71.4 μs,FFT 只需一颗 0.16 G 复乘/秒的芯片,DFT 需要 58.7 G。⇒ OFDM 这种调制方式本身就建立在「FFT 很便宜」这个前提上。
① 我原以为「二维图像上比值是 4096 倍」——两层都错。拿不可分离的 N⁴ 双重和比是 8192 倍,可那种实现没人会写;两边都用可分离算法(先按行再按列)才是公平的,256×256 上是 64 倍。
② 我原以为「小 n 时 DFT 更快,交叉点在 16~64」——没有交叉点,FFT 从 n = 4 就赢。真实的情况见右边那张卡。
看那张双尺子图:秒表比一直低于次数比。n = 2048 该赢 372 倍,实测只赢 109 倍;n = 4 该赢 4 倍,实测只赢 1.22 倍——位反转和循环开销把 FFT 的优势吃掉了大半。这正是 FFTW 对小 n 用硬编码直接算法、而不是递归的原因。
另外基-2 的 Cooley–Tukey 要求 n 是 2 的幂。n 是质数时它压根不适用,得换 Rader 或 Bluestein。⚠ 还有一条自己踩的:我第一版的 DFT 内层在调 Math.cos,把秒表比夸大成 1194 倍——对照版本不干净,量出来的就是假的。