9

与链接到 OpenBLAS 的 numpy 相比,我尝试评估链接到 ATLAS 的 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 时间

给定时间来自不同的运行,因此 avg、min 和 max 值略有不同。

编辑:附加发现:

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

4

1 回答 1

4

我无法复制,但我想我知道原因。我在 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

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

为了完整起见,我请一位朋友在她的机器上运行该片段,该机器已从 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。这是CentOS 的说明。

请注意,OpenBLAS(尚)与 不兼容multiprocessing,因此请注意限制。如果你对线性代数很重,MKL 是最好的选择,但它很贵。学者们可以从 Continuum Anaconda Python 发行版中免费获得它,而且许多大学都有校园范围的许可证。

于 2014-06-19T17:20:50.827 回答