前言
本文是个人学习心得的分享,希望大家在阅读文章后能在评论中一起学习交流!另外还可以访问我的HelloCUDA仓库查看我在学习CUDA中写的一些demo程序。
内容概要
- 复数的CUDA C++实现
- 从DFT到FFT
- FFT蝴蝶操作
- CUDA中的分治
- FFT的并行化
前置知识
- 算法基础知识
- 并行计算基础知识
- C++基础知识
- CUDA编程基础
- 离散傅里叶变换的原理
从DFT到FFT
离散傅里叶变化(Discrete Fourier Transform)是傅里叶变换的简化版本,计算机科学家发明出离散傅里叶变换目的就是要让具有连续性质的傅里叶变换能在具有离散性质的计算机中被应用。而离散傅里叶变换算法时间复杂度高( O ( n 2 ) O(n^2) O(n2)),使其在大规模场景中的应用受到限制,从而诞生了快速傅里叶变换(Fast Fourier Transform).
快速傅里叶变换的实现采用的是分治的思想。利用DFT的数学性质可以将一个DFT分解为多个DFT。数列 a 0 , a 1 , a 2 , . . . , a n a_0, a_1, a_2, ..., a_n a0,a1,a2,...,an的离散傅里叶变换的本质是求多项式 A ( x ) = a 0 + a 1 x + a 2 x 2 + . . . + a n x n − 1 A(x) = a_0 + a_1x + a_2x^2 + ... + a_nx^{n-1} A(x)=a0+a1x+a2x2+...+anxn−1在 n n n次单位复根处的取值,变换后的数列为 A ( w n 0 ) , A ( w n 1 ) , A ( w n 2 ) , . . . , A ( w n n − 1 ) A(w_n^0), A(w_n^1), A(w_n^2), ..., A(w_n^{n-1}) A(wn0),A(wn1),A(wn2),...,A(wnn−1)。其中 w n i , i = 0 , 1 , . . . , n − 1 w_n^i, i=0, 1, ..., n-1 wni,i=0,1,...,n−1是方程 w n = 1 w^n = 1 wn=1的 n n n个根 (此处有疑惑请参考离散傅里叶变换的原理). 因此,对于长度为 n n n的数列进行DFT共需要进行 n n n次多项式求值,每次求值的复杂度为 O ( n ) O(n) O(n),因此总体时间复杂度为 O ( n 2 ) O(n^2) O(n2).
了解从DFT到FFT原理的读者可以跳过以下三段内容。将上述多项式 A ( x ) A(x) A(x)按照下标为奇数或偶数分解为两个多项式 A 0 ( x ) = a 0 + a 2 x + a 4 x 2 + a 6 x 4 + . . . A_0(x)=a_0 + a_2x + a_4x^2 + a_6x^4 + ... A0(x)=a0+a