0

我正在做一些时间计算比较

Method     Wisdom   Planning Effort
builder    None     FFTW_Estimate
FFTW core  None     FFTW_Estimate
FFTW core  Planned  FFTW_Estimate

我导入必要的包:

import numpy as np
import timeit
import pyfftw
from collections import OrderedDict

为上述三个测试场景定义单独的函数:

def builder_test(input_data, a):
    pyfftw.forget_wisdom()
    a[:] = input_data  # Assume input_data will always be new data
    fft_obj = pyfftw.builders.rfft(a, planner_effort='FFTW_ESTIMATE')
    return fft_obj()

def fftw_test(input_data, a):
    pyfftw.forget_wisdom()                  
    outLength = len(input_data)//2 + 1     
    outData = pyfftw.empty_aligned(outLength, dtype='complex64')
    fft_obj = pyfftw.FFTW(a, outData, flags=('FFTW_ESTIMATE',))
    a[:] = input_data  # Assume input_data will always be new data
    return fft_obj()

def fftw_test_planned(input_data, a, fft_obj):
    #a[:] = input_data  # Assume input_data will always be new data
    return fft_obj.__call__(input_array=input_data)

def wrapper(func, *args, **kwargs):
    """
    Wrapper to call each function with timeit
    """
    def wrapped():
        return func(*args, **kwargs)
    return wrapped

然后遍历不同长度N的数组timeit

test_functions = OrderedDict([("FFTW", fftw_test), 
                              ("Builder", builder_test), 
                              ("FFTW-Planned", fftw_test_planned),
                             ])

N = [22829, 300013, 1124434, 1200048, 2465342, 3068583, 11553414, 17279800]

print("N  \tMin 3 Avg Time  \tFunction")  # Table header
for n in N:
    # Set up some byte aligned arrays for reuse 
    x = pyfftw.empty_aligned(n, dtype='float32', n=16)
    x[:] = np.random.uniform(-1000, 1000, [n])
    a = pyfftw.empty_aligned(n, dtype='float32', n=16)
    a[:] = x  # In the future, assume x would be constantly changing, may be shorter in length, etc
    outLength = len(a)//2 + 1
    outData = pyfftw.empty_aligned(outLength, dtype='complex64')

    for func_name in test_functions:
        # Wrap functions for timeit
        if 'Planned' in func_name:
            pyfftw.forget_wisdom()  # Forget wisdom before plan
            # For planned tests, create fftw_obj once before running repeated tests    
            #fft_obj = pyfftw.FFTW(a, outData, flags=('FFTW_MEASURE',), planning_timelimit=60.0)
            fft_obj = pyfftw.FFTW(a, outData, flags=('FFTW_ESTIMATE',))
            wrapped = wrapper(test_functions[func_name], x, a, fft_obj)
        else:
            # Wisdom is forgotten as first step within each unplanned function (see above)
            wrapped = wrapper(test_functions[func_name], x, a)

        # Timeit
        sorted_t = sorted(timeit.repeat(wrapped, number=1, repeat=10))  #Repeat timeit 10 times and sort
        min_3_t_avg = np.mean(sorted_t[:3])  # Average fastest three runs
        print("{}  \t{}  \t{}".format(n, min_3_t_avg, func_name))
    print("")

结果如下:

N        Min 3 Avg Time     Function
22829    0.00937143961589   FFTW
22829    0.00834314028422   Builder
22829    0.00342512130737   FFTW-Planned

300013   0.342160304387     FFTW
300013   0.333618402481     Builder
300013   0.0695606867472    FFTW-Planned

1124434  0.361418326696     FFTW
1124434  0.37025197347      Builder
1124434  0.306508302689     FFTW-Planned

1200048  0.506390889486     FFTW
1200048  0.507919232051     Builder
1200048  0.315515041351     FFTW-Planned

2465342  0.828966299693     FFTW
2465342  0.660408655802     Builder
2465342  0.637949228287     FFTW-Planned

3068583  0.936786015828     FFTW
3068583  0.942013422648     Builder
3068583  0.8645576636       FFTW-Planned

11553414 4.61405666669      FFTW
11553414 4.63671763738      Builder
11553414 4.39226007462      FFTW-Planned

17279800 4.76136477788      FFTW
17279800 4.8280433019       Builder
17279800 4.39278205236      FFTW-Planned

最初,对于较短的阵列,计划中的智慧似乎正在发挥作用。但是,随着数组长度变长,结果几乎没有差异。我什至尝试过使用FFTW_MEASURE60 秒planning_timelimit,但结果是一样的。

我已经翻阅了文档,但看起来要么我错过了明智的计划,要么计划实际上并不像我预期的那样有效/重要。

在有人推荐线程之前,我想先了解智慧规划的价值!

4

0 回答 0