Почему флаг "потоки" в pyfftw не работает - PullRequest
0 голосов
/ 16 июня 2020

При использовании 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()

Кто-нибудь знает, почему это происходит и как я могу извлечь выгоду из нескольких потоков? Спасибо.

...