Noncubic网格上的FFT速度

时间:2016-09-29 15:57:11

标签: python performance fft fftw pyfftw

我需要重复进行三维函数的傅立叶变换/逆傅里叶变换以求解微分方程。类似的东西:

import pyfftw.interfaces.numpy_fft as fftw
for i in range(largeNumber):
    fFS = fftw.rfftn(f)
    # Do stuff
    f = fftw.irfftn(fFS)

f的形状是高度非立方的。是否存在基于尺寸顺序的性能差异,例如(512,32,128)vs(512,128,32)等?

我正在寻找任何可用的加速。我已经尝试过玩弄智慧。我认为如果最大尺寸最后一次(例如32,128,512)可能是最快的,那么fFS.shape =(32,128,257),但这似乎并非如此。

1 个答案:

答案 0 :(得分:0)

如果您真的希望尽可能地挤出所有性能,请直接使用FFTW对象(最容易通过pyfftw.builders访问)。通过这种方式,您可以仔细控制发生的副本以及是否对反向执行标准化。

您的代码原样可能会受益于使用缓存(通过调用pyfftw.interfaces.cache.enable()启用),这可以最大限度地减少一般安全案例的设置时间,但不会消除它。

关于尺寸的最佳排列,你必须吮吸它并看到。尝试所有各种选项,看看最快的是什么(timeit)。确保在进行测试时,您实际上正在按预期使用内存中排列的数据,而不仅仅是在内存中查看相同的数组(pyfftw可以很好地处理没有副本的数据 - 尽管有调整这种事情的参数。)

FFTW尝试了许多不同的选项(不同的FFT表示上的不同算法)并且选择速度最快,因此最终会得到非显而易见的实现,这些实现可能会因表面上非常相似的不同数据集而发生变化。

一般提示:

  • 启用多线程以获得最佳性能(在适当的位置设置threads=N。)
  • 确保您的阵列具有适当的字节对齐 - 这比现代硬件的影响要小,但可能会有所不同(特别是如果所有较高的尺寸大小都将字节对齐作为一个因素)。
  • 阅读tutorialapi docs