Повышение производительности FFT в Python

Какова самая быстрая реализация FFT в Python?

Это кажется numpy.БПФ и сципи.fftpack оба основаны на fftpack, а не FFTW. Fftpack так же быстро, как FFTW? Как насчет использования многопоточного БПФ или использования распределенного (MPI) БПФ?

6 ответов


вы, безусловно, можете обернуть любую реализацию FFT, которую вы хотите протестировать с помощью Cython или других подобных инструментов, которые позволяют получить доступ к внешним библиотекам.

GPU-based

Если вы собираетесь протестировать реализации FFT, вы также можете взглянуть на коды на основе GPU (если у вас есть доступ к соответствующему оборудованию). Их несколько:reikna.БПФ, scikits.технология CUDA.

CPU-based

там же процессора python FFTW обертка pyFFTW.

(здесь pyFFTW3 также, но он не так активно поддерживается, как pyFFTW, и он не работает с Python3. (источник))

У меня нет опыта ни с одним из них. Вероятно, вам придется немного покопаться и проверить различные коды для вашего конкретного приложения, если скорость важна для вас.


для теста подробно на https://gist.github.com/fnielsen/99b981b9da34ae3d5035 я нахожу, что scipy.fftpack отлично работает по сравнению с моим простым приложением pyfftw через pyfftw.interfaces.scipy_fftpack, за исключением данных с длиной, соответствующей простое число.

Кажется, что существует некоторая стоимость настройки, связанная с вызовом pyfftw.межфазные границы.scipy_fftpack.БПФ в первый раз. Во второй раз быстрее. Библиотеки numpy и fftpack составляющей с простым числом выполняет страшно для размер данных я пробовал. CZT в этом случае быстрее. Несколько месяцев назад в Github Scipy's был поднят вопрос о проблеме, см. 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
------------------------------------------------------------

пакет pyFFTW3 уступает по сравнению с библиотекой pyFFTW, по крайней мере, в реализации. Поскольку они оба обертывают библиотеку FFTW3, я думаю, что скорость должна быть одинаковой.

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


где я работаю, некоторые исследователи собрали эту библиотеку Fortran, которая настраивает и вызывает FFTW для конкретной проблемы. Эта библиотека Fortran (модуль с некоторыми подпрограммами) ожидает некоторые входные данные (2D-списки) из моей программы Python.

то, что я сделал, это создать небольшое расширение C для Python, обернув библиотеку Fortran, где я в основном вызывает "init" для настройки планировщика FFTW, а также другую функцию для подачи моих 2D-списков (массивов) и " вычислить" функция.

создание c-расширений-небольшая задача, и для этой конкретной задачи есть много хороших учебников.

к хорошей вещи об этом подходе является то, что мы получаем скорость .. много скорости. Единственным недостатком является расширение C, где мы должны перебирать список Python и извлекать все данные Python в буфер памяти.


на сайт FFTW показывает fftpack работает примерно на 1/3 так же быстро, как FFTW, но это с механически переведенным шагом Fortran-to-C, за которым следует компиляция C, и я не знаю, использует ли numpy/scipy более прямую компиляцию Fortran. Если производительность важна для вас, вы можете рассмотреть возможность компиляции FFTW в DLL/общую библиотеку и использования ctypes для доступа к ней или создания пользовательского расширения C.


FFTW3 кажется самой быстрой доступной реализацией, которая хорошо завернута. Привязки PyFFTW в первом ответе. Вот код, который сравнивает время выполнения:test_ffts.py