一个钢琴调音师敲下琴键,只凭耳朵就能分辨出这根弦准不准——他把一个复杂的声波在头脑里拆成了“频率的成分”来判断。人耳的耳蜗做的也是类似的事:不同频率的声波让基底膜不同位置共振,我们才有“音高”的知觉。把信号拆成频率成分来看,是信号处理里最有生产力的一种视角;而把这件事交给计算机去做,靠的是一个1965年之后才真正跑起来的算法——快速傅里叶变换(FFT)。
对通信工程师来说,FFT不只是仪器面板上的一个按钮。你手机里每一次上网、每一通电话,收发两端都要在微秒级的时间里完成一次上千点的FFT。这篇文章要回答三个问题:为什么我们要到“频域”去看信号;为什么直接按定义算频域慢到没法用;以及,FFT到底快在哪里。
先把数学工具摆出来。离散傅里叶变换(DFT)做的事情一句话可以说完:拿信号和一组“标准频率”逐一比对,看每个频率成分占了多少。
$$X[k]=\sum_{n=0}^{N-1}x[n]\,e^{-j2\pi kn/N},\qquad k=0,1,\dots,N-1$$
直观理解:$e^{-j2\pi kn/N}$ 是一根均匀旋转的“探针”,转 $N$ 拍正好转完整数圈,转多快由 $k$ 决定。信号 $x[n]$ 与这根探针逐点相乘再求和,本质是做相关性检验——如果信号里真含这个频率的成分,乘积会“同频共振”,求和出来是个大数;如果不含,正负抵消,结果接近零。把 $k$ 从0取到 $N-1$,就得到信号在 $N$ 个频率格子上的“成分清单”。
定义没有任何玄妙之处。问题在算力账本:每算一个频率点 $X[k]$,需要 $N$ 次复数乘法;$N$ 个频率点全算完,就是 $N^2$ 次。记 $W_N = e^{-j2\pi/N}$(工程上叫旋转因子),账目是这样的:
$$N\ \text{点DFT的代价} = N^2\ \text{次复数乘法}$$
代入实际规模就知道疼在哪里。做一次2048点的DFT,需要约419万次复数乘法,每次复数乘法又是4次实数乘法加2次实数加法。按1960年代计算机每秒几万次运算的速度,这不是“慢”,是“算不完”。频域视角在数学上早就人人会用,但在工程上等于废纸——直到有人发现,这份账本里藏着巨大的浪费。
1965年,IBM的James Cooley和普林斯顿大学的John Tukey在《Mathematics of Computation》上发表了题为“An Algorithm for the Machine Calculation of Complex Fourier Series”的论文,给出了把 $N^2$ 降到约 $N\log_2 N$ 的方法。据Cooley本人晚年回忆,这篇文章的诞生颇有些戏剧性:Tukey在一次总统科学顾问委员会的会议上随口提到“把傅里叶变换折半来算”的想法,同在会场的IBM物理学家Richard Garwin立刻意识到这对处理地震仪数据(当时用于监测核试验)价值巨大,回去就把问题交给了Cooley实现。
更有意思的是后续的历史考据。1984年,Heideman、Johnson和Burrus三位学者查阅档案后发现,高斯早在1805年就为计算行星轨道提出过本质相同的快速算法,只是手稿用拉丁文写成且从未发表——比Cooley-Tukey早了160年。FFT不是“被发明”的,更像是“被重新发明”的:同一块宝石,掉进了两个时代。
对通信行业,这篇论文的意义格外具体。OFDM的思路(把信道切成一堆正交的窄带子载波)早在1960年代就有了,但按老办法,每个子载波都要一套振荡器和调制器,上千个子载波意味着上千套硬件,工程上根本没法做。1971年Weinstein和Ebert指出:OFDM的调制解调可以用一次DFT完成——而DFT有FFT这个加速器。从此“OFDM=IFFT/FFT”成了固定搭配,才有后来的ADSL、Wi-Fi、LTE一路开挂。可以说,没有FFT,就没有现代宽带无线。
FFT的核心思想朴素到令人意外:分而治之。以8点DFT为例,按下标奇偶把样本分成两组,偶数下标(0,2,4,6)一组,奇数下标(1,3,5,7)一组。代入定义稍微整理,会发现原式恰好拆成两个4点DFT的组合:
$$X[k]=E[k]+W_N^{k}\,O[k],\qquad X[k+N/2]=E[k]-W_N^{k}\,O[k]$$
其中 $E[k]$、$O[k]$ 分别是偶数组、奇数组各自的DFT。这个式子是整个FFT的心脏,值得盯着看十秒钟,它背后有三个“便宜”:
第一个便宜:规模减半。 一个8点DFT变成两个4点DFT。直接算是 $64$ 次复数乘法,拆开后是 $2\times 4^2=32$ 次——还没算完,还能继续拆。
第二个便宜:乘一次顶两次。 注意上下两个式子里,旋转因子 $W_N^k$ 是同一个。也就是说 $W_N^k O[k]$ 这个乘法只消做一次,结果加上 $E[k]$ 得到 $X[k]$,减一下得到 $X[k+N/2]$。一次乘法喂饱两个输出,这个“一进一出变两进两出”的计算单元,画在图上像个蝴蝶,于是得名蝶形运算。
第三个便宜:负号白送。 为什么半个周期之后的旋转因子恰好变号?因为旋转因子有周期性和对称性:
$$W_N^{k+N/2}=e^{-j2\pi(k+N/2)/N}=e^{-j\pi}\cdot e^{-j2\pi k/N}=-W_N^{k}$$
乘以 $-1$ 不需要乘法器。数学上的对称性,直接兑换成了硬件上的零成本。
把“拆分—合并”的递归过程画成树,就是FFT的全部结构:
flowchart TD
A["8点DFT<br/>64次复乘"] -->|偶下标样本| B["4点DFT"]
A -->|奇下标样本| C["4点DFT"]
B -->|偶下标样本| D["2点DFT"]
B -->|奇下标样本| E["2点DFT"]
C -->|偶下标样本| F["2点DFT"]
C -->|奇下标样本| G["2点DFT"]
D --> H["蝶形合并<br/>一乘两加"]
E --> H
F --> I["蝶形合并<br/>一乘两加"]
G --> I
拆到底,2点DFT连乘法都不需要——就是一次加法和一次减法。最后逐层用蝶形往回合并。单个蝶形长这样:
flowchart TD
A["输入 a"] --> P["输出一<br/>a+W·b"]
B["输入 b"] --> M["乘旋转因子W"]
M --> P
M --> Q["输出二<br/>a-W·b"]
A --> Q
每个蝶形的代价是1次复数乘法加2次复数加法。$N$ 点FFT共有 $\log_2 N$ 级,每级 $N/2$ 个蝶形,所以总代价是:
$$\frac{N}{2}\log_2 N\ \text{次复数乘法}$$
账本重算一遍,差距是压倒性的:
| 点数 N | 直接DFT复乘 $N^2$ | FFT复乘 $\frac{N}{2}\log_2 N$ | 快了多少倍 |
|---|---|---|---|
| 64 | 4 096 | 192 | 21倍 |
| 256 | 65 536 | 1 024 | 64倍 |
| 1024 | 1 048 576 | 5 120 | 205倍 |
| 2048 | 4 194 304 | 11 264 | 372倍 |
| 4096 | 16 777 216 | 24 576 | 683倍 |
规模越大,省得越狠——省掉的部分是 $N/\log_2 N$,随 $N$ 增长几乎不设上限。这就是为什么FFT被称为二十世纪最重要的数值算法之一:它不是把计算做得更快,而是把“没必要做的计算”识别出来砍掉了。
顺带解释一个工程惯例:为什么设备里FFT点数几乎都是2的整数幂。因为偶奇分家的玩法要求每折一次规模减半,2的幂才能一路整除到底、蝶形排得整整齐齐。非2幂的混合基算法也存在(比如分解成 $2048=32\times64$ 做二维变换),但流水线设计的复杂度都会上升。
FFT家族还有个孪生兄弟IFFT(逆变换),从频域成分清单还原时域波形。收发两端的分工正好是“逆”过来的:
flowchart TD
T1["比特流"] --> T2["编码调制<br/>映射为复数符号"]
T2 --> T3["IFFT<br/>频域分配变时域波形"]
T3 --> T4["加循环前缀<br/>上射频发射"]
T4 --> R1["天线接收<br/>下变频采样"]
R1 --> R2["去除循环前缀"]
R2 --> R3["FFT<br/>波形变回频域"]
R3 --> R4["信道估计<br/>频域均衡"]
R4 --> R5["解调译码<br/>还原比特"]
方向约定其实很自然。OFDM把一段带宽切成上千个子载波,调度器给每个用户的比特分配到“某个子载波、某种幅度相位”上——这是一张频域的座位表。但天线最终要辐射的是随时间变化的电压波形,是时域的。从座位表还原波形,是“从频率到时间”,按傅里叶变换的方向约定就是逆变换,所以发射端挂IFFT;接收端天线收到的是混合波形,要还原出每个子载波上的星座点,是“从时间到频率”,所以挂FFT。
工程实现上还有个偷懒技巧:IFFT不需要单独的电路。对输入取共轭、做FFT、输出再取共轭并除以 $N$,就等价于IFFT。所以一颗基带芯片里往往只有一套FFT硬件,收发共用,靠外围的共轭运算切换身份。
另一个值得点到的细节是循环前缀。FFT处理的数学模型是循环卷积——它默认信号是首尾相接绕圈的。真实的多径信道偏偏是线性卷积,两者对不上,接收端FFT之后符号间就会互相污染。工程上发端每个符号前面复制一段尾巴,硬生生把线性卷积“伪装”成循环卷积,FFT的频域均衡才能干净地工作。这段“伪装术”正是循环前缀存在的第一性原因。
FFT在现网里不是某个孤立的模块,而是一套通用算力,哪里需要“时频两界穿梭”,哪里就有它:
| 岗位 | 用的变换 | 为什么走频域 | 工程师在哪里遇到它 |
|---|---|---|---|
| OFDM调制解调 | 发IFFT/收FFT | 座位表与波形的互相翻译 | 基带芯片的DSP/专用加速器 |
| 信道估计 | FFT/IFFT往返 | 把导频处的频域响应变到时域,脉冲响应稀疏、便于滤波去噪 | 基带算法调参、信道估计器设计 |
| PRACH前导检测 | FFT域做相关 | 上百微秒的长序列相关,时域算不动,频域相乘等价且省算力 | 追查接入失败、虚警/漏检问题 |
| 频谱扫描监测 | FFT频谱分析 | 宽带信号拆成频率格子做占用度统计 | 频谱仪、网优扫频、干扰排查 |
| 发射指标测量 | FFT解调分析 | 从波形还原星座和频谱,算EVM、ACLR | 发信机验收、仪器设置 |
| 频域均衡(SC-FDE) | FFT/IFFT夹均衡器 | 单载波抗高峰均比,但均衡借频域做,卷积定理兜底 | 上行接收机方案对比 |
频域相关值得多说一句,它是卷积定理的直接应用:时域的循环卷积对应频域的逐点相乘。检测一个未知 preamble 何时到达,时域要做滑窗相关、计算量随序列长度爆炸;先做FFT,频域一乘、IFFT回来,相关峰直接立在峰值位置——计算量从“长度乘长度”压到“长度乘对数”。5G基站能在毫秒级分辨出成百上千个随机接入尝试,背后就是这套频域流水线。
FFT的数学是优雅的,工程使用却是暗礁密布。下面这几个坑,几乎每个无线工程师都会踩到至少一个:
坑一:频谱泄漏。 FFT默认你的信号是“无限长周期信号截取了整数个周期”。现实中截一段有限长数据,等价于给信号乘了一个矩形窗,频域上就是信号频谱和窗函数频谱(sinc形状)做卷积——能量从原来的频率格子“泼”进旁边的格子。信号频率如果不是格子间距的整数倍,泄漏必然发生。对付它的办法是换更平滑的窗(汉宁窗、布莱克曼窗等),用主瓣变宽换旁瓣压低。测ACLR、杂散这类靠“旁瓣干净”吃饭的指标,窗函数选错,测量数据直接作废。
坑二:零填充的迷信。 数据不够,后面补零把FFT点数凑大,谱线看起来变密了、变漂亮了——但这是插值,不是分辨率。频率分辨率由实际采集时长决定(约等于 $1/T$),补零只是把同一把尺子的刻度描细,刻度之间的信息从来没被采到。想分辨两个挨得近的频率,唯一正路是采更长时间的数据,而不是补更多零。这是新手在干扰排查里最常见的方法论错误。
坑三:单边谱与双边谱。 实信号的FFT天然共轭对称:正频率和负频率的幅度一样,各携带一半能量。画单边谱时忘掉这层对称、忘记幅度加倍,测出的功率谱就差一倍。仪器读数和自研工具对不上号时,先查这里。
坑四:循环卷积和线性卷积混用。 “FFT→频域相乘→IFFT”这套流水线做的是循环卷积,信号首尾会绕回来互相纠缠。想做普通滤波(线性卷积),要补零到至少两倍长度再变换;想利用循环卷积做通信(OFDM),就要在发端补循环前缀。同一段代码,补零策略错了,现象是结果边缘出现莫名错误——而中间的数据又全对,非常迷惑人。
坑五:定点实现的位增长。 每一级蝶形,最坏情况下数据幅度翻倍,也就是长出1个比特。2048点FFT有11级,不做处理的话字长要凭空多出11比特才不溢出。定点实现必须在各级之间做缩放(每级缩、隔级缩还是最后缩,是信噪比和溢出风险之间的权衡)。用FPGA或DSP手写FFT,溢出截顶的表现是星座图大面积“削顶”失真,EVM莫名其妙恶化。
坑六:位反转序。 按偶奇分家的流程(时域抽取型),输入按自然顺序进去,输出会按“位反转”顺序出来——下标二进制位左右颠倒的位置才是真正的 $X[k]$。它不影响原位运算省内存的美德,但自己写DSP代码时忘了这茬,“FFT算出来的谱是乱序的”就是最经典的踩坑现场。商业库函数都已处理,手写实现时才会撞见。
最后把容易混淆的几个概念放在一张表里对齐:
| 概念 | 一句话定义 | 与FFT的关系 | 通信里的角色 |
|---|---|---|---|
| DFT | 时域N点样本到频域N点成分的变换 | 数学定义本身,直接算需 $N^2$ | 一切频域分析的数学基础 |
| FFT | 计算DFT的快速算法 | 与DFT结果完全相同,只是算得快 | 让频域分析在实时系统里可用 |
| IFFT | DFT的逆变换,频域还原时域 | 与FFT共用硬件,差一次共轭 | 发射端把座位表变成波形 |
| 卷积定理 | 时域卷积等于频域相乘 | FFT让“频域相乘”变得便宜 | 频域均衡、相关检测、滤波的理论根基 |
理解这层关系的最好概括是:DFT是问题,FFT是解法。教科书里讲变换,工程里谈的是算法,两者结果一致、身份完全不同。评审方案或读论文时,说“用FFT实现OFDM”是工程表述,说“OFDM即DFT”才是原理表述。
Q: LTE 20MHz带宽只有1200个有效子载波,为什么IFFT要用2048点? A: IFFT的点数不是由有效子载波数决定的,而是由采样率决定:2048点 × 15kHz子载波间隔 = 30.72MHz,正是20MHz带宽对应的标称采样率。1200个有效子载波装数据,两侧的保护子载波和直流子载波填零即可。反过来说,同一个带宽下子载波间隔翻倍,点数就减半——5G把子载波间隔按2的幂向上翻时,FFT规模相应缩小,这也是可扩展参数化设计的算力红利。
Q: OFDM发射端为什么必须用IFFT,用FFT行不行? A: 在纯数学层面,正逆变换只差共轭和缩放,把它俩对调、再相应调整映射共轭关系,理论上也能构造出可用的系统——历史上确实有文献讨论过这种“反向约定”。工程上一律采用“发IFFT、收FFT”,只是为了让“子载波分配=频域操作”这个直觉与实现严格一致,避免所有公式里都拖着共轭号。约定无对错,统一才有价值。
Q: FFT这么快,直接DFT还有什么存在场景吗? A: 有。当你只需要少数几个频率点的值时,直接按定义算可能反而更省:算 $M$ 个频率点的DFT代价是 $M\times N$,只要 $M < \frac{1}{2}\log_2 N$,直接算就划算。比如只监测某几个特定频点,或者做滑动的Goertzel算法(单频点检测,DTMF检测的经典方案),都比完整FFT更合适。快是相对问题的规模而言的。
Q: 频谱仪上的RBW和FFT是什么关系? A: RBW(分辨率带宽)本质上就是频率分辨率 $1/T$ 的仪器化表达:对采集时长 $T$ 的信号做FFT,相邻谱线的间隔就是RBW。想看清楚两个挨得很近的干扰信号,必须加长采集时间(缩小RBW);RBW设得太宽,小信号会被大信号的泄漏裙边淹没——这就是坑一在仪器上的具体化身。扫频测量时“RBW与VBW怎么配”的背后,是FFT采集时长与窗函数的选择。
Q: 手机芯片里的FFT是一块独立电路吗?有多大? A: 标准允许多种实现,具体以各厂家官方资料为准。常见做法是把FFT做成基带里的加速器(协处理器):蝶形运算规则、数据流规整,非常适合流水线化的专用电路;规模上,一个2048点复数FFT引擎在先进工艺下通常只需数十万门量级,对现代SoC微不足道——这个“便宜到可以随便用”的算力,正是当年Cooley-Tukey那篇论文留给整个通信产业的最大遗产。
本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护,聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。
[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。
