【问题标题】:High performance array mean高性能阵列意味着
【发布时间】:2016-07-20 23:08:45
【问题描述】:

我遇到了性能瓶颈。我正在计算大型数组(250 行和 130 万列)的列平均值,并且在我的应用程序中这样做了超过一百万次。

我在 Python 中的测试用例:

import numpy as np
big_array = np.random.random((250, 1300000))
%timeit mean = big_array.mean(axis = 0) # ~400 milliseconds

Numpy 在我的机器上大约需要 400 毫秒,在单核上运行。我尝试了其他几个跨不同语言(Cython、R、Julia、Torch)的矩阵库,但发现只有 Julia 在 250 毫秒内击败了 Numpy。

任何人都可以提供证据证明这项任务的性能有显着改善吗?也许这是适合 GPU 的任务?

编辑:我的应用程序显然是内存受限的,通过只访问大型数组的元素一次,而不是重复访问,它的性能得到了显着提高。 (请参阅下面的评论。)

【问题讨论】:

  • 这个计算可能更多的是关于内存访问而不是 CPU 工作。我不希望任何系统在此处对 numpy 进行显着改进。我的直觉是,使用多核或 GPU 并没有多大用处。不过,减少到 float32 可能会有所帮助。
  • 测试用例可能太简单了。我的数组类型实际上是布尔值,所以每个元素都用 Numpy 存储为一个字节。矛盾的是,获得布尔数组的均值或求和需要比示例中的浮点数更长的时间。知道如何对 bitpacked 数组执行操作,这会减少约 90% 的内存流量吗?
  • 在我的特定应用程序中,我采用数组的平均值,这些数组是 22,000 行数组的 250 行子集。对于整个计算,仅内存访问总共需要 24 小时以上。但是,如果我对更大的矩阵进行操作,并且只触摸每个元素一次,则内存访问总共不到 10 秒。我得试试看!感谢@MRocklin 指出瓶颈。

标签: python arrays numpy matrix


【解决方案1】:

Julia,如果我没记错的话,它在内存中使用 fortran 排序,而不是默认使用 C 内存布局的 numpy。因此,如果您重新排列事物以遵循相同的布局,以便均值沿着连续内存发生,您将获得更好的性能:

In [1]: import numpy as np

In [2]: big_array = np.random.random((250, 1300000))

In [4]: big_array_f = np.asfortranarray(big_array)

In [5]: %timeit mean = big_array.mean(axis = 0)
1 loop, best of 3: 319 ms per loop

In [6]: %timeit mean = big_array_f.mean(axis = 0)
1 loop, best of 3: 205 ms per loop

或者你可以改变你的尺寸并在另一个轴上取平均值:

In [10]: big_array = np.random.random((1300000, 250))

In [11]: %timeit mean = big_array.mean(axis = 1)
1 loop, best of 3: 205 ms per loop

【讨论】:

  • 在我的电脑上,时间是相反的:在 [56]: %timeit big_array.mean(0) -> 705 ms per loop ;在 [57] 中:%timeit big_arrayf.mean(0) -> 每个循环 1201 毫秒;你有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-13
  • 2016-02-03
  • 2020-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多