Luc*_*cas 45 python numpy scientific-computing blas
我试图在Python中实现大量的矩阵 - 矩阵乘法.最初,我假设NumPy将自动使用我的线程BLAS库,因为我是针对这些库构建的.但是,当我查看顶部或其他内容时,似乎代码根本不使用线程.
任何想法是什么错误或我可以做些什么来轻松使用BLAS性能?
Ümi*_*mit 106
我已经在另一个帖子中发布了这个,但我认为它在这个方面更合适:
我在新的HPC上重新运行基准测试.硬件和软件堆栈都改变了原始答案中的设置.
我将结果放在谷歌电子表格中(也包含原始答案的结果).
我们的HPC有两个不同的节点,一个是Intel Sandy Bridge CPU,另一个是新的Ivy Bridge CPU:
桑迪(MKL,OpenBLAS,ATLAS):
常春藤(MKL,OpenBLAS,ATLAS):
软件堆栈适用于两个节点sam.代替GotoBLAS2,OpenBLAS被使用并且也有一个多线程的ATLAS它被设置为8个线程(硬编码)BLAS.
基准代码与以下相同.然而,对于新机器,我还运行了基质尺寸5000和8000的基准测试.
下表包括原始答案的基准测试结果(更名为:MKL - > Nehalem MKL,Netlib Blas - > Nehalem Netlib BLAS等)
![矩阵乘法(尺寸= [1000,2000,3000,5000,8000])](https://i.stack.imgur.com/ZU7u4.png)
单线程性能:

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

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


单线程性能:

多线程(8线程)性能:

新的基准测试结果与原始答案中的结果类似.OpenBLAS和MKL在同一级别上执行,但特征值测试除外.在单线程模式下,特征值测试在OpenBLAS上的表现相当不错.在多线程模式下,性能更差.
的"矩阵大小VS线程图表"也表明,虽然MKL以及OpenBLAS通常与核/线程的数量很好地扩展,这取决于基质的大小.对于小型矩阵,添加更多内核不会极大地提高性能.
从Sandy Bridge到Ivy Bridge的性能提升约为30%,这可能是由于更高的时钟频率(+ 0.8 Ghz)和/或更好的架构.
前段时间我不得不优化一些使用numpy和BLAS用python编写的线性代数计算/算法,所以我对不同的numpy/BLAS配置进行了基准测试.
特别是我测试过:
我确实运行了两个不同的基准测试:
这是我的结果:
Linux(MKL,ATLAS,No-MKL,GotoBlas2):
Mac Book Pro(加速框架):
Mac服务器(加速框架):
代码:
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等).
如果您在具有Fink或Mac端口的Mac OS X计算机上安装numpy,它将配置numpy以使用ATLAS或Apple的Accelerate Framework.您可以通过在numpy.core._dotblas文件上运行ldd 或调用numpy.show_config()来进行检查.
MKL表现最好,其次是GotoBlas2.
在特征值测试中,GotoBlas2的表现出乎意料地差于预期.不知道为什么会这样.
Apple的Accelerate Framework在单线程模式下表现非常好(与其他BLAS实现相比).
GotoBlas2和MKL都可以很好地扩展线程数.因此,如果你必须处理在多个线程上运行它的大矩阵将有很大帮助.
在任何情况下都不要使用默认的netlib blas实现,因为对于任何严肃的计算工作来说它太慢了.
在我们的集群上,我还安装了AMD的ACML,其性能类似于MKL和GotoBlas2.我没有任何强硬的数字.
我个人会建议使用GotoBlas2,因为它更容易安装,而且是免费的.
如果你想在C++/C中编码也可以查看Eigen3,它在某些情况下应该胜过MKL/GotoBlas2,并且也很容易使用.
Sve*_*ach 17
并非所有的NumPy都使用BLAS,只有一些功能 - 特别dot()是vdot(),和模块中的innerproduct()几个功能numpy.linalg.另请注意,许多NumPy操作受大型阵列的内存带宽限制,因此优化的实现不太可能带来任何改进.如果受内存带宽限制,多线程是否可以提供更好的性能在很大程度上取决于您的硬件.