在Python中提高FFT性能

31

什么是Python中最快的FFT实现?

看起来numpy.fft和scipy.fftpack都基于fftpack,而不是FFTW。fftpack和FFTW一样快吗?使用多线程FFT或使用分布式(MPI)FFT呢?

6个回答

23

您可以使用Cython或其他类似的工具来封装您想要测试的任何FFT实现,以便访问外部库。

基于GPU

如果您要测试FFT实现,还可以查看基于GPU的代码(如果您有适当的硬件)。 有几个选择:reikna.fftscikits.cuda

基于CPU

还有一个基于CPU的Python FFTW包装器pyFFTW

(也有pyFFTW3,但它没有pyFFTW那么活跃的维护,并且不支持Python3. (来源))

我没有使用过其中任何一个。 如果速度对您很重要,可能需要挖掘和基准测试不同代码以找到特定应用程序的最佳选择。


11
这个回答有点过时,但在谷歌上排名很高。我的FFTW包装器比pyFFTW3更活跃地维护,并且我认为在提供的功能上更加完整。 - Henry Gomersall

12

在一个详细的测试中(https://gist.github.com/fnielsen/99b981b9da34ae3d5035),我发现scipy.fftpack表现良好,与我的简单应用程序pyfftw通过pyfftw.interfaces.scipy_fftpack相比,除了数据长度对应素数之外。

似乎有一些设置成本与第一次调用pyfftw.interfaces.scipy_fftpack.fft相关联。第二次会更快。对于我尝试的数据大小,NumPy和SciPy的fftpack与素数表现非常糟糕。在那种情况下,CZT更快。几个月前,在Scipy的Github上提出了一个与问题有关的问题,请参见(https://github.com/scipy/scipy/issues/4288)

20000 prime=False
  padded_fft : 0.003116
   numpy_fft : 0.003502
   scipy_fft : 0.001538
         czt : 0.035041
    fftw_fft : 0.004007
------------------------------------------------------------
20011 prime=True
  padded_fft : 0.001070
   numpy_fft : 1.263672
   scipy_fft : 0.875641
         czt : 0.033139
    fftw_fft : 0.009980
------------------------------------------------------------
21803 prime=True
  padded_fft : 0.001076
   numpy_fft : 1.510341
   scipy_fft : 1.043572
         czt : 0.035129
    fftw_fft : 0.011463
------------------------------------------------------------
21804 prime=False
  padded_fft : 0.001108
   numpy_fft : 0.004672
   scipy_fft : 0.001620
         czt : 0.033854
    fftw_fft : 0.005075
------------------------------------------------------------
21997 prime=True
  padded_fft : 0.000940
   numpy_fft : 1.534876
   scipy_fft : 1.058001
         czt : 0.034321
    fftw_fft : 0.012839
------------------------------------------------------------
32768 prime=False
  padded_fft : 0.001222
   numpy_fft : 0.002410
   scipy_fft : 0.000925
         czt : 0.039275
    fftw_fft : 0.005714
------------------------------------------------------------

3

相比于pyFFTW3包,pyFFTW库在实现方面要更优秀。由于它们都是对FFTW3库进行的封装,所以速度应该是相同的。

https://pypi.python.org/pypi/pyFFTW


2
在我工作的地方,一些研究人员编写了一个Fortran库,用于为特定问题设置和调用FFTW。这个Fortran库(带有一些子程序的模块)期望从我的Python程序中获取一些输入数据(2D列表)。
我的做法是创建一个小型的C扩展程序,将Fortran库包装到Python中,其中我基本上调用“init”来设置FFTW计划器,并使用另一个函数来提供我的2D列表(数组),以及一个“compute”函数。
创建C扩展程序是一个小任务,在那个特定任务上有很多好的教程。
这种方法的好处是我们获得了速度..很快的速度。唯一的缺点在于C扩展程序,我们必须遍历Python列表,并将所有Python数据提取到内存缓冲区中。

使用Cython,您可以直接访问内存中的数据,而无需复制它。 - Charles Brunet

1

FFTW网站显示fftpack运行速度约为FFTW的1/3,但这是通过机械翻译Fortran到C步骤后跟随C编译完成的,我不知道numpy/scipy是否使用更直接的Fortran编译。如果性能对您至关重要,您可以考虑将FFTW编译成DLL/共享库并使用ctypes访问它,或构建自定义C扩展。


1

FFTW3似乎是可用的最快实现,而且包装得很好。第一个答案中的PyFFTW绑定可行。这是一些比较执行时间的代码:test_ffts.py


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