Повышение производительности 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, я думаю, что скорость должна быть одинаковой.
где я работаю, некоторые исследователи собрали эту библиотеку 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