При использовании pyfftw.FFTW в лаборатории jupyter флаг threads
работает хорошо. Код в лаборатории jupyter:
import pyfftw
a = pyfftw.empty_aligned((256, 256), dtype='complex128')
b = pyfftw.empty_aligned((256, 256), dtype='complex128')
fft_object = pyfftw.FFTW(a, b,axes=(0,1))
fft_object_para = pyfftw.FFTW(a, b,axes=(0,1),threads=6)
ar = np.random.randn(256,256)
ai = np.random.randn(256,256)
a[:] = ar + 1j*ai
print('Time cost using 1 thread:')
%timeit fft_object()
print('Time cost using 6 threads:')
%timeit fft_object_para()
Затраты времени:
Time cost using 1 thread:
350 µs ± 5.13 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Time cost using 6 threads:
144 µs ± 10.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Однако, когда он помещен в следующие сценарии, флаг не работает.
import numpy as np
from scipy.fft import fftshift,ifftshift
from pyfftw import empty_aligned
from pyfftw import FFTW
@profile
def test(fft_thread):
N = 256
a = empty_aligned((N, N), dtype='complex128')
b = empty_aligned((N, N), dtype='complex128')
wave = empty_aligned((N, N), dtype='complex128')
fft_obj = FFTW(a,b,axes=(0,1),direction='FFTW_FORWARD',threads=fft_thread)
ifft_obj = FFTW(b,a,axes=(0,1),direction='FFTW_BACKWARD',threads=fft_thread)
for i in range(10):
a[:] = a + np.ones_like(a)
wave[:] = fft_obj()
wave[:] = fftshift(wave)
wave[:] = wave + np.ones_like(a)
b[:] = ifftshift(wave)
wave[:] = ifft_obj()
Профиль test(1)
:
Timer unit: 1e-07 s
Total time: 0.310012 s
File: E:\Scripts\0_Git\ePIE_py_2\fftw_test.py
Function: test at line 12
Line # Hits Time Per Hit % Time Line Contents
==============================================================
12 @profile
13 def test(fft_thread):
14 1 28.0 28.0 0.0 N = 256
15 1 361.0 361.0 0.0 a = empty_aligned((N, N), dtype='complex128')
16 1 135.0 135.0 0.0 b = empty_aligned((N, N), dtype='complex128')
17 1 141.0 141.0 0.0 wave = empty_aligned((N, N), dtype='complex128')
18 1 1506889.0 1506889.0 48.6 fft_obj = FFTW(a,b,axes=(0,1),direction='FFTW_FORWARD',threads=fft_thread)
19 1 1241405.0 1241405.0 40.0 ifft_obj = FFTW(b,a,axes=(0,1),direction='FFTW_BACKWARD',threads=fft_thread)
20
21 11 115.0 10.5 0.0 for i in range(10):
22 10 81668.0 8166.8 2.6 a[:] = a + np.ones_like(a)
23 10 45625.0 4562.5 1.5 wave[:] = fft_obj()
24 10 48291.0 4829.1 1.6 wave[:] = fftshift(wave)
25 10 82206.0 8220.6 2.7 wave[:] = wave + np.ones_like(a)
26 10 48512.0 4851.2 1.6 b[:] = ifftshift(wave)
27 10 44741.0 4474.1 1.4 wave[:] = ifft_obj()
Профиль test(6)
:
Timer unit: 1e-07 s
Total time: 0.408852 s
File: E:\Scripts\0_Git\ePIE_py_2\fftw_test.py
Function: test at line 12
Line # Hits Time Per Hit % Time Line Contents
==============================================================
12 @profile
13 def test(fft_thread):
14 1 30.0 30.0 0.0 N = 256
15 1 318.0 318.0 0.0 a = empty_aligned((N, N), dtype='complex128')
16 1 152.0 152.0 0.0 b = empty_aligned((N, N), dtype='complex128')
17 1 131.0 131.0 0.0 wave = empty_aligned((N, N), dtype='complex128')
18 1 1994737.0 1994737.0 48.8 fft_obj = FFTW(a,b,axes=(0,1),direction='FFTW_FORWARD',threads=fft_thread)
19 1 1695203.0 1695203.0 41.5 ifft_obj = FFTW(b,a,axes=(0,1),direction='FFTW_BACKWARD',threads=fft_thread)
20
21 11 172.0 15.6 0.0 for i in range(10):
22 10 86251.0 8625.1 2.1 a[:] = a + np.ones_like(a)
23 10 59972.0 5997.2 1.5 wave[:] = fft_obj()
24 10 50568.0 5056.8 1.2 wave[:] = fftshift(wave)
25 10 84911.0 8491.1 2.1 wave[:] = wave + np.ones_like(a)
26 10 50158.0 5015.8 1.2 b[:] = ifftshift(wave)
27 10 65915.0 6591.5 1.6 wave[:] = ifft_obj()
Кто-нибудь знает, почему это происходит и как я могу извлечь выгоду из нескольких потоков? Спасибо.