python - 使用 atlas 和 openblas 对 numpy 进行基准测试时出现奇怪的结果

标签 python numpy benchmarking blas atlas

我尝试评估链接到 ATLAS 的 numpy 与链接到 OpenBLAS 的 numpy 的性能。我在下面描述的 ATLAS 得到了一些奇怪的结果。

评估矩阵-矩阵乘法(又名 sgemm)的 Python 代码如下所示:

import sys
sys.path.insert(0, "numpy-1.8.1")

import numpy
import timeit

for i in range(100, 501, 100):
    setup = "import numpy; m1 = numpy.random.rand(%d, %d).astype(numpy.float32)" % (i, i)
    timer = timeit.Timer("numpy.dot(m1, m1)", setup)
    times = timer.repeat(100, 1)
    print "%3d" % i,
    print "%7.4f" % numpy.mean(times),
    print "%7.4f" % numpy.min(times),
    print "%7.4f" % numpy.max(times)

如果我使用链接到 ATLAS 的 numpy 运行此脚本,我会得到测量时间的很大变化。您会在第一列中看到矩阵大小,然后是通过运行矩阵矩阵乘法 100 倍获得的执行时间的平均值、最小值和最大值:

100  0.0003  0.0003  0.0004
200  0.0023  0.0010  0.0073
300  0.0052  0.0026  0.0178
400  0.0148  0.0066  0.0283
500  0.0295  0.0169  0.0531

如果我使用一个线程使用链接到 OpenBLAS 的 numpy 重复此过程,运行时间会更加稳定:

100  0.0002  0.0002  0.0003
200  0.0014  0.0014  0.0015
300  0.0044  0.0044  0.0047
400  0.0102  0.0101  0.0105
500  0.0169  0.0168  0.0177

谁能解释这个观察结果?

编辑:附加信息:

观察到的 ATLAS 最小值和最大值没有异常值,时间分布在给定范围内。

我在 https://gist.github.com/uweschmitt/768bd165477d7c14095e 上传了 i=500 的 ATALS 时间

给定时间来自不同的运行,因此平均值、最小值和最大值略有不同。

编辑:附加发现:

CPU 节流 (http://www.scipy.org/scipylib/building/linux.html#step-1-disable-cpu-throttling) 可能是原因吗?我对 CPU 节流知之甚少,无法判断它对我的测量的影响。遗憾的是,我无法在我的目标机器上设置/取消设置它。

最佳答案

我无法重现,但我想我知道原因。我在 Linux 64 机器上使用 Numpy 1.8.1。

首先,我使用 ATLAS 的结果(我在最后一列中添加了标准偏差):

100  0.0003  0.0002  0.0025  0.0003
200  0.0012  0.0010  0.0067  0.0006
300  0.0028  0.0026  0.0047  0.0004
400  0.0070  0.0059  0.0089  0.0004
500  0.0122  0.0109  0.0149  0.0009

现在,Anaconda 提供的 MKL 结果:

100  0.0003  0.0001  0.0155  0.0015
200  0.0005  0.0005  0.0006  0.0000
300  0.0018  0.0017  0.0021  0.0001
400  0.0039  0.0038  0.0042  0.0001
500  0.0079  0.0077  0.0084  0.0002

MKL 速度更快,但点差一致。

ATLAS 在编译时进行调整,它会尝试不同的配置和算法,并为您的特定硬件集保持最快。如果您安装预编译版本,那么您使用的是构建机器的最佳配置,而不是您自己的。这种错误配置是传播的可能原因。就我而言,我自己编译了 ATLAS。

相反,OpenBLAS 是针对特定架构手动调整的,因此任何二进制安装都是等效的。 MKL 动态决定。

如果我在从存储库安装的 Numpy 上运行脚本并与预编译的 ATLAS 链接(SSE3 未激活),则会发生这种情况:

100  0.0007  0.0003  0.0064  0.0007
200  0.0021  0.0015  0.0090  0.0009
300  0.0050  0.0040  0.0114  0.0010
400  0.0113  0.0101  0.0186  0.0011
500  0.0217  0.0192  0.0329  0.0020

这些数字与您的数据更相似。

为了完整起见,我让一位 friend 在她的机器上运行该片段,该机器从 Ubuntu 存储库安装了 numpy,但没有 ATLAS,因此 Numpy 正在退回到其蹩脚的默认值:

100  0.0007  0.0007  0.0008  0.0000
200  0.0058  0.0053  0.0107  0.0014
300  0.0178  0.0175  0.0188  0.0003
400  0.0418  0.0401  0.0528  0.0014
500  0.0803  0.0797  0.0818  0.0004

那么,可能发生了什么?

您的 ATLAS 安装不是最佳的,这就是为什么您会如此分散的原因。我的数字是在笔记本电脑的 Intel i5 CPU @ 1.7 GHz 上运行的。我不知道你有哪台机器,但我怀疑它比我的慢了将近三倍。这表明 ATLAS 并未完全优化。

我怎么确定?

运行 numpy.show_config() 将告诉您它链接到哪些库,以及它们在哪里。输出是这样的:

atlas_threads_info:
    libraries = ['lapack', 'ptf77blas', 'ptcblas', 'atlas']
    library_dirs = ['/usr/lib64/atlas-sse3']
    define_macros = [('ATLAS_INFO', '"\\"3.8.4\\""')]
    language = f77
    include_dirs = ['/usr/include']
blas_opt_info:

如果这是真的,如何解决?

你可能有一个陈旧的预编译二进制图集(它是某些包的依赖项),或者你用来编译它的标志是错误的。最顺利的解决方案是从源代码构建 RMPS。 Here are CentOS 的说明。

请注意,OpenBLAS 与 multiprocessing 不兼容(目前),因此请注意这些限制。如果你对线性代数很感兴趣,MKL 是最好的选择,但它很昂贵。学术界可以从 Continuum Anaconda Python 发行版中免费获得它,许多大学都拥有校园范围内的许可证。

关于python - 使用 atlas 和 openblas 对 numpy 进行基准测试时出现奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24201683/

相关文章:

python - 对字符串进行分区并每 n 个字符拆分一次

python - numpy:将标量函数应用于不同矩阵的相应元素

android - 如何测试android中代码的执行速度?

c++ - 基准测试 : get algorithm user time

python - 在 Python 中打印列表时出现脏打印

python - 使用rpy2,如何调用变量名中包含 "."的函数?

python - AttributeError: 模块 'tensorflow' 没有属性 'python'

python - 如何在 matlab 和 python 中重现相同的随机整数数组?

python - 如何在Python中非连续地切片二维数组

mysql - 适用于 MySQL (InnoDB) 的最佳 Linux 文件系统是什么?