2014-08-27 16 views
2

다음과 같은 다양한 인터페이스를 사용하여 2D FFT를 수행하는 매우 기본적인 예가 있습니다. pyfftw.FFTW 인터페이스는 가장 빠르고, 분명히FFT를 수행하는 가장 빠른 방법

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. 

하지만 (내가 잘못하고있는 무슨 확실하지 않다) 작동하지 않습니다

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) 

이 다음과 같은 결과를 생성합니다.

pyfftw.interfaces.scipy_fftpack.fft2pyfftw.interfaces.numpy_fft.fft2은 상당한 시간이 걸리지 만, 그 시간은 대부분 처음 계획 단계에있는 것으로 결정했습니다. 필자의 경우, 하나의 FFT2와 하나의 IFFT2만이 (프로세스 당) 수행 될 것이므로 계획이 나를 죽이고있다. 지혜를 잊지 않고 두 번 실행하면 약 0.33 초 후에 실행됩니다 (그러나 내 경우에는 발생하지 않음).

따라서 질문은 입니다. pyfftw.FFTW에서 데이터가 잘못되어 무엇이 잘못 되었습니까? - 또는 - 2. pyfftw.interfaces.scipy_fftpack.fft2 또는 pyfftw.interfaces.numpy_fft.fft2에 대한 계획 수립 및 제한 시간을 어떻게 변경합니까?

+0

http://hgomersall.github.io/pyFFTW/pyfftw/pyfftw.html에서 : "이 어레이의 내용은 계획 프로세스에 의해 파괴됩니다. 초기화. " – SleuthEye

답변

1

내가 찾은 해결책이 빌더 인터페이스를 사용하는 것이 었습니다 :

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

올바르게 가장 효율적인을 만드는 pyfftw.FFTW 클래스를 사용하는 코드를 수정하고 2 배에 의해 실행 시간을 감소 "빌더"클래스. 제 4 코어 i5의 CPU에

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) 

출력 예 배, 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

코드 복사 붙여 넣기를했는데 어떤 이유로 든 결과가 크게 다릅니다 .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 코어를 사용하고 있습니다. 파이썬 3.5 (아나콘다), Windows 10. 왜 다른가? 어떤 이유인지는 모르겠다. 수동으로 2와 4 개의 코어를 입력하면 더 나 빠졌다. – bltpyro

+0

업데이트로, 나는 우분투에서 가상 박스를 시도하고 예상대로 수행했다. 그래서 천천히 일으키는 창문이있는 것처럼 보입니다. – bltpyro