2014-08-27 91 views
2

我有以下使用各種接口進行二維FFT的基本示例。最快的方法來做一個FFT

import time 
import numpy 
import pyfftw 
import multiprocessing 

a = numpy.random.rand(2364,2756).astype('complex128') 

start = time.time() 
b1 = numpy.fft.fft2(a) 
end1 = time.time() - start 

start = time.time() 
b2 = pyfftw.interfaces.scipy_fftpack.fft2(a, threads=multiprocessing.cpu_count()) 
end2 = time.time() - start 

pyfftw.forget_wisdom() 
start = time.time() 
b3 = pyfftw.interfaces.numpy_fft.fft2(a, threads=multiprocessing.cpu_count()) 
end3 = time.time() - start 

pyfftw.forget_wisdom() 
start = time.time() 
b4 = numpy.zeros_like(a) 
fft = pyfftw.FFTW(a, b4, axes=(0,1), flags=('FFTW_ESTIMATE',),planning_timelimit=1.0) 
fft() 
end4 = time.time() - start 

print('numpy.fft.fft2:      %.3f secs.' % end1) 
print('pyfftw.interfaces.scipy_fftpack.fft2: %.3f secs.' % end2) 
print('pyfftw.interfaces.numpy_fft.fft2:  %.3f secs.' % end3) 
print('pyfftw.FFTW:       %.3f secs.' % end4) 

這會產生以下結果:

numpy.fft.fft2:      1.878 secs. 
pyfftw.interfaces.scipy_fftpack.fft2: 50.133 secs. 
pyfftw.interfaces.numpy_fft.fft2:  52.136 secs. 
pyfftw.FFTW:       0.331 secs. 

顯然,pyfftw.FFTW接口是最快的,但不工作(我不知道我做錯了)。

pyfftw.interfaces.scipy_fftpack.fft2pyfftw.interfaces.numpy_fft.fft2需要相當長的時間,但我已經確定時間很大程度上處於計劃階段,這隻發生在第一次。在我的情況下,只有一個FFT2和一個IFFT2將被執行(每個進程),所以計劃正在讓我失望。如果兩者中的任何一個都不會忘記智慧,他們也會在大約0.33秒內運行(但這不會發生在我的情況中)。

所以,問題是: 1.我在做什麼錯在pyfftw.FFTW導致數據錯誤? - 或 - 2.如何更改pyfftw.interfaces.scipy_fftpack.fft2pyfftw.interfaces.numpy_fft.fft2的計劃方案和時間限制?

+0

來自http://hgomersall.github.io/pyFFTW/pyfftw/pyfftw.html:「這些數組的內容將在計劃過程中被銷燬初始化「。 – SleuthEye 2014-08-27 14:28:43

回答

1

我發現的解決方案是使用助洗劑接口:

fft = pyfftw.builders.fft2(a, overwrite_input=True, planner_effort='FFTW_ESTIMATE', threads=multiprocessing.cpu_count()) 
b = fft() 
3

修改爲使用pyfftw.FFTW類的代碼正確地使其成爲最有效的,並已通過兩個以因子減少的執行時間「建造者」班。

import time 
import numpy 
import pyfftw 
import multiprocessing 
nthread = multiprocessing.cpu_count() 
a = numpy.random.rand(2364,2756).astype('complex128') 
""" 
Uncomment below to use 32 bit floats, 
increasing the speed by a factor of 4 
and remove the difference between the "builders" and "FFTW" methods 
""" 
#a = numpy.random.rand(2364,2756).astype('complex64') 

start = time.time() 
b1 = numpy.fft.fft2(a) 
end1 = time.time() - start 

start = time.time() 
b2 = pyfftw.interfaces.scipy_fftpack.fft2(a, threads=nthread) 
end2 = time.time() - start 

pyfftw.forget_wisdom() 
start = time.time() 
b3 = pyfftw.interfaces.numpy_fft.fft2(a, threads=nthread) 
end3 = time.time() - start 

""" By far the most efficient method """ 
pyfftw.forget_wisdom() 
start = time.time() 
b4 = numpy.zeros_like(a) 
fft = pyfftw.FFTW(a, b4, axes=(0,1), direction='FFTW_FORWARD', flags=('FFTW_MEASURE',), threads=nthread, planning_timelimit=None) 
fft() 
end4 = time.time() - start 

""" 
For large arrays avoiding the copy is very important, 
doing this I get a speedup of 2x compared to not using it 
""" 
pyfftw.forget_wisdom() 
start = time.time() 
b5 = numpy.zeros_like(a) 
fft = pyfftw.builders.fft2(a, s=None, axes=(-2, -1), overwrite_input=False, planner_effort='FFTW_MEASURE', threads=nthread, auto_align_input=False, auto_contiguous=False, avoid_copy=True) 
b5 = fft() 
end5 = time.time() - start 



print('numpy.fft.fft2:      %.3f secs.' % end1) 
print('pyfftw.interfaces.scipy_fftpack.fft2: %.3f secs.' % end2) 
print('pyfftw.interfaces.numpy_fft.fft2:  %.3f secs.' % end3) 
print('pyfftw.FFTW:       %.3f secs.' % end4) 
print('pyfftw.builders:      %.3f secs.' % end5) 

我的4核i5 CPU上實施例的輸出時間,使用64位的浮動:我的4核i5 CPU上

numpy.fft.fft2:      1.537 secs. 
pyfftw.interfaces.scipy_fftpack.fft2: 0.248 secs. 
pyfftw.interfaces.numpy_fft.fft2:  0.248 secs. 
pyfftw.FFTW:       0.084 secs. 
pyfftw.builders:      0.143 secs. 

實施例的輸出時間,使用32位的浮動:

numpy.fft.fft2:      1.414 secs. 
pyfftw.interfaces.scipy_fftpack.fft2: 0.066 secs. 
pyfftw.interfaces.numpy_fft.fft2:  0.066 secs. 
pyfftw.FFTW:       0.043 secs. 
pyfftw.builders:      0.043 secs. 
+0

我做了一個代碼複製粘貼,出於某種原因,我得到了截然不同的results.numpy.fft.fft2:1.288秒。 pyfftw.interfaces.scipy_fftpack.fft2:62.861秒。 pyfftw.interfaces.numpy_fft.fft2:61.455秒。 pyfftw.FFTW:65.393秒。 pyfftw.builders:51.156秒。它使用8個內核。 Python 3.5(anaconda),Windows 10.任何想法爲什麼它不同?嘗試手動輸入2和4核心,它變得更糟。 – bltpyro 2016-07-11 19:55:32

+0

作爲更新,我在Ubuntu中嘗試了一個virtualbox,並按預期執行。所以看起來像是一些使窗口變慢的窗口。 – bltpyro 2016-07-12 21:02:51

相關問題