【问题标题】:performance in linear algebra with python使用python在线性代数中的表现
【发布时间】:2016-03-11 19:41:52
【问题描述】:

互联网上随处可见不同语言的基准和相关问题。但是,我仍然无法弄清楚我是否应该在我的程序中切换到 C。

基本上,我的程序中最耗时的部分涉及大量的矩阵求逆和矩阵乘法。我有几个计划:

  1. 坚持使用 numpy。
  2. 将 C 与 LAPACK/BLAS 结合使用。
  3. 重写我的python程序,把最耗时的部分改成C,然后用python调用C。

我知道 numpy 只是包裹在 LAPACK/BLAS 上的东西。那么 2 或 3 会比 1 快很多(500%)吗?

【问题讨论】:

  • cython 其实可以看成是另一种语言。这不是我想要的。
  • 您必须向我们展示您在做什么以及如何使用 NumPy。对于线性代数运算,NumPy 只是调用优化的 LAPACK/BLAS 例程(假设它们在你的系统上)——你不可能比那些更快。手写 C 代码可能比调用这些例程慢得多。
  • @ajcr,相应编辑
  • 你可以看看 sagemath 。它基于python,包含很多东西。就我而言,我将它用于 GF(2^8) 中的大矩阵乘法。
  • 分析您当前的代码 - 如果您几乎将所有时间都花在 BLAS/LAPACK 例程中,那么您将看到选项 2 或 3 基本上没有性能优势。一种罕见的情况可能 如果您在许多小矩阵上多次调用 BLAS/LAPACK 例程,那么用 C 重写代码的某些部分是有意义的。在实践中,您可能应该考虑是否可以提高算法的效率,是否与最快的 BLAS/LAPACK 实现相关联,以及是否可以从使用 GPU 中受益。

标签: python c performance numpy blas


【解决方案1】:

当我看到你的问题时,我只是想问一个非常相似的问题。我已经从各个方向测试了这个问题。很长一段时间以来,我都试图通过我的代码来击败 numpy.dot 函数。

我有大型复杂矩阵,它们的乘法是我程序的主要瓶颈。我测试了以下方法

  1. 简单的c代码。
  2. 使用 cblas 进行各种优化的 cython 代码。
  3. python 32位和64位版本,发现64位版本比32位快1.5-2倍。
  4. anaconda 的 MKL 实现,但也没有运气。
  5. 矩阵乘法的einsum
  6. python 3 和 python 2.7 是一样的 python 3 @ 操作符也是一样的
  7. numpy.dot(a,b,c) 略快于 c=numpy.dot(a,b)

到目前为止,numpy.dot 是最好的。它击败了所有其他方法,有时略胜一筹(einsum),但主要是显着。

在我的研究过程中,我遇到了一篇文章,即 Ultrafast matrix multiplication 告诉苹果的 altivec 实现可以在不到一秒的时间内乘以 2500x2500 矩阵。在我的带有英特尔核心 i3 第 4 代 2.3 GHZ 4 gb ram 的 PC 上,使用 numpy.dot 需要 73 秒,因此我仍在寻找在 PC 上更快的实现。

【讨论】:

  • 73 秒对于将两个 2500x2500 浮点矩阵点在一起仍然是相当长的时间。我怀疑您可能正在使用缓慢的单线程 BLAS 实现。当 numpy 与多线程 OpenBLAS 链接时,相同的点积在我的笔记本电脑上需要约 650 毫秒,但在与参考 CBLAS 实现链接时需要约 16 秒。
  • 感谢您的评论,我刚刚再次检查了我的代码,发现上述时间是针对整数矩阵的,对于浮点 64 矩阵,它减少到 270 毫秒(使用 python 3.5 的 anaconda 3 64 位)。在处理矩阵时,我会更加小心数据类型。但仍然 numpy dot 是最好的。
  • BLAS 和 LAPACK 仅支持浮点矩阵。对于与其他 dtype 的矩阵乘法,numpy 将退回到its own C implementation,这会慢得多。
猜你喜欢
  • 1970-01-01
  • 2011-03-05
  • 1970-01-01
  • 2018-04-20
  • 2020-05-24
  • 1970-01-01
  • 2017-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多