我正在做一些计时比较
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
对每个数组运行三次测试(重复每次测试10次并返回三次最快运行的平均时间):
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_MEASURE
并使用了60秒planning_timelimit
,但效果相同。
我已经倾注了文档,但看起来我要么缺少智慧计划的东西,要么计划实际上并不像我期望的那样有效/重要。
在任何人推荐线程之前,我想首先了解智慧计划的价值!