022、FFT加速卷积:何时使用?何时不用?

022、FFT加速卷积:何时使用?何时不用? 022、FFT加速卷积:何时使用?何时不用?去年调一个边缘检测模型,在Cortex-M7上跑3x3卷积,帧率死活上不去。同事说“试试FFT加速”,我心想3x3这种小核用FFT不是脱裤子放屁?结果他真改了一版,跑出来比直接卷积还慢三倍。后来查ARM CMSIS-DSP的文档,发现人家明确写了:FFT卷积只推荐核大小超过7x7时使用。这个坑,我替你们踩了。从数学直觉到硬件代价卷积定理说:时域卷积等于频域点乘。这个定理漂亮,但漂亮的东西往往藏着代价。FFT加速卷积的核心流程是:对输入和卷积核分别做FFT,频域相乘,再IFFT回来。看起来三步走,但每一步都在烧钱。先算一笔账。假设输入特征图是HxW,卷积核是KxK,输出也是HxW(padding保持尺寸)。直接卷积的计算量是 HWK*K 次乘加。FFT路线呢?需要做两次FFT(输入和核),一次点乘,一次IFFT。FFT的计算量是 O(N log N),其中N是FFT点数。这里有个关键:FFT的点数必须覆盖卷积后的尺寸,通常是 H+W 量级,而且为了FFT效率,往往要补零到2的幂次。拿128x128输入、3x3卷积核举例。直接卷积:1281289 ≈ 147K次乘加。FFT路线:需要做256点FFT(补零后),一次FFT约 256log2(256)=2048次复数运算,两次FFT加一次IFFT就是6144次,再加上频域点乘的256次复数乘。看起来FFT路线计算量只有直接卷积的4%?别急,这里有个巨大的陷阱——复数运算和实数运算的换算。一次复数乘等于4次实数乘加,一次复数加等于2次实数加。实际折算下来,FFT路线的实数运