【问题标题】:Memory usage of scipy.fftpackscipy.fftpack 的内存使用情况
【发布时间】:2017-07-28 00:58:00
【问题描述】:

在使用 scipy 的 fftpack 执行 fft 时,我遇到了内存使用率高的问题。使用模块 memory_profiler 获得的示例:

Line #    Mem usage    Increment   Line Contents
================================================
 4   50.555 MiB    0.000 MiB   @profile
 5                             def test():
 6  127.012 MiB   76.457 MiB       a = np.random.random(int(1e7))
 7  432.840 MiB  305.828 MiB       b = fftpack.fft(a)
 8  891.512 MiB  458.672 MiB       c = fftpack.ifft(b)
 9  585.742 MiB -305.770 MiB       del b, c
10  738.629 MiB  152.887 MiB       b = fftpack.fft(a)
11  891.512 MiB  152.883 MiB       c = fftpack.ifft(b)
12  509.293 MiB -382.219 MiB       del a, b, c
13  547.520 MiB   38.227 MiB       a = np.random.random(int(5e6))
14  700.410 MiB  152.891 MiB       b = fftpack.fft(a)
15  929.738 MiB  229.328 MiB       c = fftpack.ifft(b)
16  738.625 MiB -191.113 MiB       del a, b, c
17  784.492 MiB   45.867 MiB       a = np.random.random(int(6e6))
18  967.961 MiB  183.469 MiB       b = fftpack.fft(a)
19 1243.160 MiB  275.199 MiB       c = fftpack.ifft(b)

我试图理解这里发生了什么:

  1. fft 和 ifft 在第 7 行和第 8 行分配的内存量超过了它们返回结果所需分配的内存量。对于调用 b = fftpack.fft(a),分配了 305 MiB。 b 数组所需的内存量为 16 B/value * 1e7 values = 160 MiB(每个值 16 B,因为代码返回 complex128)。似乎 fftpack 正在分配某种类型的工作空间,并且工作空间的大小与输出数组 (?) 相同。

  2. 在第 10 行和第 11 行再次运行相同的过程,但这次内存使用量更少,更符合我的预期。因此,fftpack 似乎能够重用工作空间。

  3. 在第 13-15 行和第 17-19 行,使用不同的较小输入大小执行 fft。在这两种情况下,分配的内存都比需要的多,而且内存似乎没有被重用。

上面报告的内存使用情况与 Windows 任务管理器报告的一致(我能够阅读这些图表的准确性)。如果我编写这样一个输入大小较大的脚本,我可以让我的(windows)计算机变得非常慢,表明它正在交换。

第二个例子来说明分配给工作空间的内存问题:

factor = 4.5
a = np.random.random(int(factor * 3e7))
start = time()
b = fftpack.fft(a)
c = fftpack.ifft(b)
end = time()
print("Elapsed: {:.4g}".format(end - start))
del a, b, c
print("Finished first fft")

a = np.random.random(int(factor * 2e7))
start = time()
b = fftpack.fft(a)
c = fftpack.ifft(b)
end = time()
print("Elapsed: {:.4g}".format(end - start))
del a, b, c
print("Finished first fft")

代码打印如下:

Elapsed: 17.62
Finished first fft
Elapsed: 38.41
Finished first fft
Filename: ffttest.py

请注意第二个 fft,它具有 较小的输入大小,计算时间是其两倍以上。我注意到在执行此脚本期间我的计算机速度非常慢(可能正在交换)。

问题:

  • 可以就地计算 fft 是否正确,而不需要额外的工作空间?如果是这样,为什么 fftpack 不这样做?

  • 这里的fftpack有问题吗?即使它需要额外的工作空间,为什么当 fft 以不同的输入大小重新运行时它不重用其工作空间?

编辑:

【问题讨论】:

  • 您也可以使用 FFTW (pyfftw.github.io/pyFFTW) - 它比 fftpack 更快,并且可以让您更好地控制内存。
  • @Dietrich 是的,我知道 pyFFTW。我的主要问题是我在 Windows 上,我没有找到 win64 的 conda 包。这意味着我可能需要解决很多链接问题,而我没有心情解决这些问题……此外,FFTW 受 GPL 约束,这在某些情况下是不可接受的。

标签: python numpy memory scipy fft


【解决方案1】:

这是一个已知问题,由 fftpack 缓存其计算给定大小的 fft 的策略引起。该缓存大约与计算的输出一样大,因此如果使用不同输入大小的内存执行大型 fft,则内存消耗可能会变得很大。

这里详细描述了问题:

https://github.com/scipy/scipy/issues/5986

Numpy 也有类似的问题,正在处理中:

https://github.com/numpy/numpy/pull/7686

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-20
    • 2015-02-03
    • 2012-05-30
    • 2021-02-26
    • 2010-10-24
    • 2015-06-14
    相关资源
    最近更新 更多