【问题标题】:How to optimize NumPy array algebra for speed?如何优化 NumPy 数组代数的速度?
【发布时间】:2017-01-21 15:05:26
【问题描述】:

当我将 GNU Octave 代码翻译成 Python 代码时,我意识到 NumPy 数组代数比 Octave 慢得多。

存在巨大的性能差异,尤其是在 cumprod 方法中。 (对于以下代码,NumPy 比 Octave 慢 80% 左右,(Octave:0.4 sec, NumPy: 2.0 sec))

蟒蛇

import numpy as np
from timer import Timer

n=1400000
k=30
matrix = np.eye(n, 2*k)
with Timer('speed test'):
    cumprodMatrix = np.cumprod(matrix, axis=0)

八度

n=1400000;
k=30;
matrix = eye(n, 2*k);
tic;cumprodMatrix = cumprod(matrix);toc

我想让我的 Python 代码与 Octave 代码一样高效。有什么方法可以使用 NumPy 更快地计算沿列的累积乘积?

【问题讨论】:

  • 第二个问题完全是题外话,因为它要求建议一个场外资源。
  • 不确定比较是否完全公平,因为如果我没记错的话,numpy octave 是列专业的。因此,您要求 numpy 沿其“困难”(非连续)轴求和,而 octave 获得“容易”(连续,很可能经过高度优化)轴。如果你使用另一个轴会发生什么?
  • 我自己没有做过基准测试,但julia.org 表明你的结论要么不正确,要么他们没有尝试cumprod
  • @paul-panzer 谢谢你的好信息。我将axis = 0更改为axis = 1并再次尝试了代码。这一次他们的速度几乎相同。但每当我尝试用 rand、0 和 one 而不是 eye 来创建矩阵时,numpy 的速度比 octave 慢 40% 左右。我不知道为什么会这样。
  • 时间差异可能是各种编码差异的结果。 numpy 版本是 ufunc。因此,它可能被编码为符合该类别而不是最佳速度。以我的经验,这不是常见的操作。 cumsum 在一维数组上设置专门的索引更为常见。

标签: python arrays performance numpy octave


【解决方案1】:

如果使用Pythran 编译 NumPy 代码,可以更快,这提供了一些见解:

$ cat r.py
import numpy as np
#pythran export r(float[][])
def r(m):
    return np.cumprod(m, axis=0)

$ python -m perf timeit -s 'import numpy as np; n = 1400000; k = 30; matrix = np.eye(n, 2*k); import r' 'r.r(matrix)'
.....................
Median +- std dev: 1.45 sec +- 0.03 sec
$ python -m pythran.run r.py -DUSE_BOOST_SIMD -march=native
$ python -m perf timeit -s 'import numpy as np; n=1400000; k=30; matrix = np.eye(n, 2*k); import r' 'r.r(matrix)'                          .....................
Median +- std dev: 445 ms +- 11 ms

通过将 NumPy 代码编译为本机代码,这基本上是一个 x3 的加速。

好处来自于使用 AVX 指令,也许 Octave 也在这样做?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 2012-05-17
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 2019-09-22
    • 1970-01-01
    相关资源
    最近更新 更多