2

我运行测试 sqript。它使用基于 FFTW 的 numpy.fft.fft()、anfft.fft() 和基于 FFTW 的 pyfftw.interfaces.numpy_fft.fft()。

这是我的测试脚本的来源:

import numpy as np
import anfft
import pyfftw
import time

a = pyfftw.n_byte_align_empty(128, 16, 'complex128')
a[:] = np.random.randn(128) + 1j*np.random.randn(128)

time0 = time.clock()
res1 = np.fft.fft(a)
time1 = time.clock()
res2 = anfft.fft(a)
time2 = time.clock()
res3 = pyfftw.interfaces.numpy_fft.fft(a,threads=50)
time3 = time.clock()

print 'Time numpy: %s' % (time1 - time0)
print 'Time anfft: %s' % (time2 - time1)
print 'Time pyfftw: %s' % (time3 - time2)

我得到了这些结果:

Time numpy: 0.00154248116307
Time anfft: 0.0139805208195
Time pyfftw: 0.137729374893

anfft 库在海量数据上产生更快的 fft,但是 pyfftw 呢?为什么这么慢?

4

3 回答 3

5

在这种情况下,产生比 CPU 内核更多的线程不会提高性能,并且可能会由于切换线程的开销而使程序变慢。50个线程完全是矫枉过正。

尝试用一个线程进行基准测试。

于 2013-09-16T02:01:50.153 回答
4

这里的问题是使用numpy_fft接口的开销。首先,您应该使用 启用缓存pyfftw.interfaces.cache.enable(),然后使用 测试结果timeit。即使使用缓存,使用原始接口时不存在的接口也会产生固定开销。

在我的机器上,在一个 128 长度的数组上,接口的开销仍然比numpy.fft. 随着长度的增加,这种开销变得不那么重要了,所以说一个 16000 长度的数组,numpy_fft接口更快。

您可以调用一些调整来加快接口端的速度,但这些不太可能对您的情况产生太大影响。

在所有情况下获得尽可能快的转换的最佳方法是直接使用FFTW对象,而最简单的方法是使用构建器函数。在你的情况下:

t = pyfftw.builders.fft(a)
timeit t()

有了这个,我得到 pyfftw 比np.fft128 长度数组快 15 倍。

于 2014-07-09T08:00:47.597 回答
2

可能是 pyFFTW 实际上花费了大部分时间来规划转换。尝试将例如包含planner_effort='FFTW_ESTIMATE'在 pyfftw fft 调用中,看看它如何影响性能。

于 2014-02-10T16:28:49.223 回答