实现在实数输入数据上高效的二维FFT?

6
我目前正在使用OpenCL实现一个二维FFT,用于处理真实输入数据(更具体地说是使用FFT进行快速二维卷积,因此我只需要一些类似的函数来应用卷积)。二维FFT是在行上执行一维FFT之后,在列上执行另一个一维FFT来实现的。
为了使这个过程更加高效,我试图利用实数输入的FFT对称性,以便能够计算较小的FFT。我发现可以将两行合并成一行,第一行作为实部,第二行作为虚部,对结果行进行第一次1D FFT,然后使用对称性质从中构造单独行的1D FFT结果。所以我正在做的基本上是以下操作:
设f和g是矩阵中的行。
1. 构造x = f + i * g 2. 进行变换以获得 F(x) = F(f) + i * F(g) 3. 使用对称性从F(x)中提取F(f)和F(g)
但是,我不能直接将结果输入第二个1D FFT,因为在这种情况下,我将不会转换整个矩阵,而是转换两个子矩阵。然而,提取转换之间的数据意味着要么存储更多数据(需要n/2+1个条目来表示实输入上的1D FFT结果),要么将索引0和n/2的元素结合成一个元素(使用相同的技巧进行组合,因为这两个数字保证是实数),并且在我的卷积中需要针对此情况进行特殊处理。
由于我尽量重复利用缓冲区(由于GPU上可用内存有限),因此使用更多存储空间不是一个好的解决方案。此外,我的算法无法处理非2的幂次方/16的倍数大小的矩阵(从内核到内核都有所不同)。我宁愿避免引入特殊情况,因为这些会使我的内核更加复杂,从而损害效率(我已经在试图将每个内核使用的寄存器计数最小化时遇到了麻烦)。
因此,我的问题是是否有一种优雅的方法来解决这个问题,即在不使用更多内存或特殊情况的情况下工作?
理想情况下,我希望能够在不将组合数据分割在FFT的中间的情况下完成整个FFT,但我不确定是否可能。

3
这本书会很快出平装版吗? - 3Dave
你真的需要进行复杂的FFT吗?可能不需要。 - phkahler
好问题,我在进行用于检测隐写术的FFT时几乎遇到了同样的问题。但那时我没有意识到...stackoverflow的存在;/ - dfens
@phkahler:你是什么意思?我的目的是进行实值输入和(显然)复值输出的FFT。因此,我正在尝试将两个实输入组合成一个复数,以避免额外的(冗余)计算。 - Grizzly
1
我猜你已经知道下面这篇论文了,但它做的事情和你一样。也许它会有所帮助。http://www.cs.unm.edu/~kmorel/documents/fftgpu/fftgpu.pdf - MicSim
1个回答

2

嗯...我的两个参考资料是:

http://www.engineeringproductivitytools.com/stuff/T0001/PT10.HTM http://images.apple.com/acg/pdf/FFTapps_20090909.pdf

我认为,采用“厄米”数据结构,将0和n / 2的值打包到第一个元素中,是更好的选择,因为前向/反向和厄米结构会更好地工作。

这样,您就可以使用rUnWrap(FFT(n / 2,Even(x)+ i * Odd(x)))= rFFT(x),而riFFT可以在“厄米”数组上工作,产生一对数组Even和Odd,再次给出原始结构。

还有其他可能的采样方式,其中原始数组被分成4个n / 2xn / 2数组,根据(0,0),(0,1),(1,0),(1,1)进行封装,最后使用最终的基数-4传递...也许这对于GPU内存更好...我不知道。

艾伦


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接