python/numpy中的多线程blas

Luc*_*cas 45 python numpy scientific-computing blas

我试图在Python中实现大量的矩阵 - 矩阵乘法.最初,我假设NumPy将自动使用我的线程BLAS库,因为我是针对这些库构建的.但是,当我查看顶部或其他内容时,似乎代码根本不使用线程.

任何想法是什么错误或我可以做些什么来轻松使用BLAS性能?

Ümi*_*mit 106

我已经在另一个帖子中发布了这个,但我认为它在这个方面更合适:

更新(2014年7月30日):

我在新的HPC上重新运行基准测试.硬件和软件堆栈都改变了原始答案中的设置.

我将结果放在谷歌电子表格中(也包含原始答案的结果).

硬件

我们的HPC有两个不同的节点,一个是Intel Sandy Bridge CPU,另一个是新的Iv​​y Bridge CPU:

桑迪(MKL,OpenBLAS,ATLAS):

  • CPU:2 x 16英特尔(R)Xeon(R)E2560 Sandy Bridge @ 2.00GHz(16核)
  • RAM:64 GB

常春藤(MKL,OpenBLAS,ATLAS):

  • CPU:2 x 20英特尔(R)Xeon(R)E2680 V2 Ivy Bridge @ 2.80GHz(20核,HT = 40核)
  • RAM:256 GB

软件

软件堆栈适用于两个节点sam.代替GotoBLAS2,OpenBLAS被使用并且也有一个多线程的ATLAS它被设置为8个线程(硬编码)BLAS.

  • 操作系统:Suse
  • 英特尔编译器:ictce-5.3.0
  • Numpy: 1.8.0
  • OpenBLAS: 0.2.6
  • 阿特拉斯:3.8.4

点 - 产品基准

基准代码与以下相同.然而,对于新机器,我还运行了基质尺寸50008000的基准测试.
下表包括原始答案的基准测试结果(更名为:MKL - > Nehalem MKL,Netlib Blas - > Nehalem Netlib BLAS等)

矩阵乘法(尺寸= [1000,2000,3000,5000,8000])

单线程性能: 单线程性能

多线程性能(8个线程): 多线程(8线程)性能

线程与矩阵大小(Ivy Bridge MKL): 矩阵大小与线程

基准套件

基准套件

单线程性能: 在此输入图像描述

多线程(8线程)性能: 在此输入图像描述

结论

新的基准测试结果与原始答案中的结果类似.OpenBLASMKL在同一级别上执行,但特征值测试除外.在单线程模式下,特征值测试在OpenBLAS上的表现相当不错.在多线程模式下,性能更差.

"矩阵大小VS线程图表"也表明,虽然MKL以及OpenBLAS通常与核/线程的数量很好地扩展,这取决于基质的大小.对于小型矩阵,添加更多内核不会极大地提高性能.

Sandy BridgeIvy Bridge的性能提升约为30%,这可能是由于更高的时钟频率(+ 0.8 Ghz)和/或更好的架构.


原答案(04.10.2011):

前段时间我不得不优化一些使用numpy和BLAS用python编写的线性代数计算/算法,所以我对不同的numpy/BLAS配置进行了基准测试.

特别是我测试过:

  • Numpy与ATLAS
  • Numpy与GotoBlas2(1.13)
  • Numpy with MKL(11.1/073)
  • Numpy with Accelerate Framework(Mac OS X)

我确实运行了两个不同的基准测试:

  1. 不同大小的矩阵的简单点积
  2. 基准套房,可在这里找到.

这是我的结果:

Linux(MKL,ATLAS,No-MKL,GotoBlas2):

  • 操作系统:Ubuntu Lucid 10.4 64位.
  • CPU:2 x 4英特尔(R)Xeon(R)E5504 @ 2.00GHz(8核)
  • RAM:24 GB
  • 英特尔编译器:11.1/073
  • Scipy:0.8
  • Numpy:1.5

Mac Book Pro(加速框架):

  • 操作系统:Mac OS X Snow Leopard(10.6)
  • CPU:1 Intel Core 2 Duo 2.93 Ghz(2核心)
  • RAM:4 GB
  • Scipy:0.7
  • Numpy:1.3

Mac服务器(加速框架):

  • 操作系统:Mac OS X Snow Leopard Server(10.6)
  • CPU:4 X Intel(R)Xeon(R)E5520 @ 2.26 Ghz(8核)
  • RAM:4 GB
  • Scipy:0.8
  • Numpy:1.5.1

点产品基准

代码:

import numpy as np
a = np.random.random_sample((size,size))
b = np.random.random_sample((size,size))
%timeit np.dot(a,b)
Run Code Online (Sandbox Code Playgroud)

结果:

    System        |  size = 1000  | size = 2000 | size = 3000 |
netlib BLAS       |  1350 ms      |   10900 ms  |  39200 ms   |    
ATLAS (1 CPU)     |   314 ms      |    2560 ms  |   8700 ms   |     
MKL (1 CPUs)      |   268 ms      |    2110 ms  |   7120 ms   |
MKL (2 CPUs)      |    -          |       -     |   3660 ms   |
MKL (8 CPUs)      |    39 ms      |     319 ms  |   1000 ms   |
GotoBlas2 (1 CPU) |   266 ms      |    2100 ms  |   7280 ms   |
GotoBlas2 (2 CPUs)|   139 ms      |    1009 ms  |   3690 ms   |
GotoBlas2 (8 CPUs)|    54 ms      |     389 ms  |   1250 ms   |
Mac OS X (1 CPU)  |   143 ms      |    1060 ms  |   3605 ms   |
Mac Server (1 CPU)|    92 ms      |     714 ms  |   2130 ms   |

点产品基准 - 图表

基准套件

代码:
有关基准套件的其他信息,请参见此处.

结果:

    System        | eigenvalues   |    svd   |   det  |   inv   |   dot   |
netlib BLAS       |  1688 ms      | 13102 ms | 438 ms | 2155 ms | 3522 ms |
ATLAS (1 CPU)     |   1210 ms     |  5897 ms | 170 ms |  560 ms |  893 ms |
MKL (1 CPUs)      |   691 ms      |  4475 ms | 141 ms |  450 ms |  736 ms |
MKL (2 CPUs)      |   552 ms      |  2718 ms |  96 ms |  267 ms |  423 ms |
MKL (8 CPUs)      |   525 ms      |  1679 ms |  60 ms |  137 ms |  197 ms |  
GotoBlas2 (1 CPU) |  2124 ms      |  4636 ms | 147 ms |  456 ms |  743 ms |
GotoBlas2 (2 CPUs)|  1560 ms      |  3278 ms | 116 ms |  295 ms |  460 ms |
GotoBlas2 (8 CPUs)|   741 ms      |  2914 ms |  82 ms |  262 ms |  192 ms |
Mac OS X (1 CPU)  |   948 ms      |  4339 ms | 151 ms |  318 ms |  566 ms |
Mac Server (1 CPU)|  1033 ms      |  3645 ms |  99 ms |  232 ms |  342 ms |

基准套件 - 图表

安装

安装MKL包括安装完整的英特尔编译器套件,这非常简单.然而,由于一些错误/问题配置和编译与MKL支持numpy是一个麻烦.

GotoBlas2是一个小包,可以很容易地编译为共享库.但是,由于存在错误,您必须在构建共享库后重新创建共享库,以便将其与numpy一起使用.
除了这个建筑之外,它还有多个目标平台因某些原因无效.所以我不得不为每个平台创建一个.so文件,我希望有一个优化的libgoto2.so文件.

如果从Ubuntu的存储库安装numpy,它将自动安装和配置numpy以使用ATLAS.从源代码安装ATLAS可能需要一些时间,需要一些额外的步骤(fortran等).

如果您在具有FinkMac端口的Mac OS X计算机上安装numpy,它将配置numpy以使用ATLASApple的Accelerate Framework.您可以通过在numpy.core._dotblas文件上运行ldd 或调用numpy.show_config()来进行检查.

结论

MKL表现最好,其次是GotoBlas2.
特征值测试中,GotoBlas2的表现出乎意料地差于预期.不知道为什么会这样.
Apple的Accelerate Framework在单线程模式下表现非常好(与其他BLAS实现相比).

GotoBlas2MKL都可以很好地扩展线程数.因此,如果你必须处理在多个线程上运行它的大矩阵将有很大帮助.

在任何情况下都不要使用默认的netlib blas实现,因为对于任何严肃的计算工作来说它太慢了.

在我们的集群上,我还安装了AMD的ACML,其性能类似于MKLGotoBlas2.我没有任何强硬的数字.

我个人会建议使用GotoBlas2,因为它更容易安装,而且是免费的.

如果你想在C++/C中编码也可以查看Eigen3,它在某些情况下应该胜过MKL/GotoBlas2,并且也很容易使用.


Sve*_*ach 17

并非所有的Nu​​mPy都使用BLAS,只有一些功能 - 特别dot()vdot(),和模块中的innerproduct()几个功能numpy.linalg.另请注意,许多NumPy操作受大型阵列的内存带宽限制,因此优化的实现不太可能带来任何改进.如果受内存带宽限制,多线程是否可以提供更好的性能在很大程度上取决于您的硬件.

  • @Lucas:NumPy中的矩阵乘法应该由`numpy.dot()`完成,也在内部.但是,如果不知道你在做什么,几乎不可能给出进一步的建议.也许你想开一个新的uqestion. (2认同)