简体   繁体   English

提高 Python 中的 FFT 性能

[英]Improving FFT performance in Python

What is the fastest FFT implementation in Python? Python 中最快的 FFT 实现是什么?

It seems numpy.fft and scipy.fftpack both are based on fftpack, and not FFTW.似乎 numpy.fft 和 scipy.fftpack 都是基于 fftpack,而不是 FFTW。 Is fftpack as fast as FFTW? fftpack 和 FFTW 一样快吗? What about using multithreaded FFT, or using distributed (MPI) FFT?使用多线程 FFT 或使用分布式 (MPI) FFT 怎么样?

You could certainly wrap whatever FFT implementation that you wanted to test using Cython or other like-minded tools that allow you to access external libraries.您当然可以使用 Cython 或其他允许您访问外部库的类似工具来包装您想要测试的任何 FFT 实现。

GPU-based基于GPU

If you're going to test FFT implementations, you might also take a look at GPU-based codes (if you have access to the proper hardware).如果您要测试 FFT 实现,您还可以查看基于 GPU 的代码(如果您可以访问适当的硬件)。 There are several: reikna.fft , scikits.cuda .有几个: reikna.fftscikits.cuda

CPU-based基于CPU

There's also a CPU based python FFTW wrapper pyFFTW .还有一个基于 CPU 的 python FFTW 包装器pyFFTW

(There is pyFFTW3 as well, but it is not so actively maintained as pyFFTW, and it does not work with Python3. ( source )) (也有pyFFTW3 ,但它不像 pyFFTW 那样积极维护,而且它不适用于 Python3。(来源))

I don't have experience with any of these.我对这些都没有经验。 It's probably going to fall to you to do some digging around and benchmark different codes for your particular application if speed is important to you.如果速度对您很重要,您可能需要为您的特定应用程序进行一些挖掘和基准测试不同的代码。

For a test detailed at https://gist.github.com/fnielsen/99b981b9da34ae3d5035 I find that scipy.fftpack performs fine compared to my simple application of pyfftw via pyfftw.interfaces.scipy_fftpack , except for data with a length corresponding to a prime number.对于https://gist.github.com/fnielsen/99b981b9da34ae3d5035的详细测试,我发现 scipy.fftpack 与我通过pyfftw.interfaces.scipy_fftpack简单应用 pyfftw 相比表现良好,除了具有对应于长度的素数的数据数字。

There seems to be some setup cost associated with evoking pyfftw.interfaces.scipy_fftpack.fft the first time.似乎有一些与第一次调用 pyfftw.interfaces.scipy_fftpack.fft 相关的设置成本。 The second time it is faster.第二次速度更快。 Numpy's and scipy's fftpack with a prime number performs terribly for the size of data I tried. Numpy 和 scipy 的带有质数的 fftpack 对于我尝试的数据大小表现非常糟糕。 CZT is faster in that case.在这种情况下,CZT 更快。 Some months ago an issue was put up at Scipy's Github about the problem, see https://github.com/scipy/scipy/issues/4288几个月前在 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
------------------------------------------------------------

The pyFFTW3 package is inferior compared to the pyFFTW library, at least implementation wise. pyFFTW3 package 比 pyFFTW 库差,至少在实现方面是这样。 Since they both wrap the FFTW3 library I guess speed should be the same.因为它们都包装了 FFTW3 库,所以我猜速度应该是一样的。

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

Where I work some researchers have compiled this Fortran library which setups and calls the FFTW for a particular problem.在我工作的地方,一些研究人员编译了这个 Fortran 库,它针对特定问题设置和调用 FFTW。 This Fortran library (module with some subroutines) expect some input data (2D lists) from my Python program.这个 Fortran 库(带有一些子程序的模块)需要来自我的 Python 程序的一些输入数据(二维列表)。

What I did was to create a little C-extension for Python wrapping the Fortran library, where I basically calls "init" to setup a FFTW planner, and another function to feed my 2D lists (arrays), and a "compute" function.我所做的是为 Python 创建一个小的 C 扩展,包装 Fortran 库,我基本上调用“init”来设置 FFTW 规划器,另一个 function 来提供我的二维列表(数组),以及一个“计算”function。

Creating a C-extensions is a small task, and there a lot of good tutorials out there for that particular task.创建 C 扩展是一项小任务,并且有很多针对该特定任务的优秀教程。

To good thing about this approach is that we get speed.. a lot of speed.这种方法的好处是我们获得了速度……很多速度。 The only drawback is in the C-extension where we must iterate over the Python list, and extract all the Python data into a memory buffer.唯一的缺点是在 C 扩展中,我们必须迭代 Python 列表,并将所有 Python 数据提取到 memory 缓冲区中。

The FFTW site shows fftpack running about 1/3 as fast as FFTW, but that's with a mechanically translated Fortran-to-C step followed by C compilation, and I don't know if numpy/scipy uses a more direct Fortran compilation. FFTW 站点显示 fftpack 的运行速度大约是 FFTW 的 1/3,但这是机械翻译的 Fortran-to-C 步骤,然后是 C 编译,我不知道 numpy/scipy 是否使用更直接的 Fortran 编译。 If performance is critical to you, you might consider compiling FFTW into a DLL/shared library and using ctypes to access it, or building a custom C extension.如果性能对您至关重要,您可以考虑将 FFTW 编译成 DLL/共享库并使用 ctypes 访问它,或者构建自定义 C 扩展。

FFTW3 seems to be the fastest implementation available that's nicely wrapped. FFTW3 似乎是最快的可用实现,并且包装得很好。 The PyFFTW bindings in the first answer work.第一个答案中的 PyFFTW 绑定有效。 Here's some code that compares execution times: test_ffts.py下面是一些比较执行时间的代码: test_ffts.py

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM