【问题标题】:How does architecture affect numpy array operation performance?架构如何影响 numpy 数组操作性能?
【发布时间】:2015-07-02 14:36:08
【问题描述】:

我的 Ubuntu 14.04 带有“Anaconda”Python 发行版,并安装了英特尔的数学内核库 (MKL)。我的处理器是具有 8 个内核且没有超线程(因此只有 8 个线程)的 Intel Xeon。

对于我来说,numpy tensordot 在大型数组中的表现始终优于 einsum。但是,其他人在两者之间找到了very little difference,甚至发现了einsum may outperform numpy for some operations

对于使用快速库构建的numpy 发行版的人,我想知道为什么会发生这种情况。 MKL 在非英特尔处理器上运行是否更慢?或者einsum 在具有更好线程能力的更现代的英特尔处理器上运行得更快?

这是一个比较我的机器性能的快速示例代码:

In  [27]: a = rand(100,1000,2000)

In  [28]: b = rand(50,1000,2000)

In  [29]: time cten = tensordot(a, b, axes=[(1,2),(1,2)])
CPU times: user 7.85 s, sys: 29.4 ms, total: 7.88 s
Wall time: 1.08 s

In  [30]: "FLOPS TENSORDOT: {}.".format(cten.size * 1000 * 2000 / 1.08)
Out [30]: 'FLOPS TENSORDOT: 9259259259.26.'

In  [31]: time cein = einsum('ijk,ljk->il', a, b)
CPU times: user 42.3 s, sys: 7.58 ms, total: 42.3 s
Wall time: 42.4 s

In  [32]: "FLOPS EINSUM: {}.".format(cein.size * 1000 * 2000 / 42.4)
Out [32]: 'FLOPS EINSUM: 235849056.604.'

使用 tensordot 的张量运算始终在 5-20 GFLOP 范围内运行。我用 einsum 只能得到 0.2 GFLOPS。

【问题讨论】:

  • "einsum 在某些操作上可能优于 numpy。"这种比较是无效的。 einsum 是一个非常通用的函数,可用于许多操作。例如,您无法将简单地复制带有 einsum 的数组与张量积的复杂性进行比较。
  • 是的。我有兴趣比较 einsum 对于张量积的效率,也可以使用 tensordot 完成。该比较确实有一些其他比较,这些比较在这里有点离题。谢谢!

标签: python arrays numpy intel-mkl numpy-einsum


【解决方案1】:

本质上你是在比较两个非常不同的东西:

  • np.einsum 用 C 语言中的for 循环计算张量积。它有一些 SIMD 优化,但不是多线程的,不使用 MLK。

  • np.tensordot,包括对输入数组进行整形/广播,然后调用 BLAS(MKL、OpenBLAS 等)进行矩阵乘法。重塑/广播阶段会产生一些额外的开销,但 matrix multiplication is extremely well optimized 带有 SIMD、一些汇编器和多线程。

因此,tensordotwill be generally faster than einsum 在单核执行中,除非使用小数组大小(然后整形/广播开销变得不可忽略)。更是如此,因为前一种方法是多线程的,而后者不是。

总之,您得到的结果是完全正常的,并且可能通常是正确的(英特尔/非英特尔 CPU、现代与否、多核与否、使用 MKL 或 OpenBLAS 等)。

【讨论】:

    猜你喜欢
    • 2012-10-21
    • 2020-06-01
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 2019-05-01
    • 2020-05-30
    相关资源
    最近更新 更多