Numpy EIG 在 Mac OS X 10.6 上比 MATLAB EIG 慢大约 4 倍。我究竟做错了啥?
Posted
技术标签:
【中文标题】Numpy EIG 在 Mac OS X 10.6 上比 MATLAB EIG 慢大约 4 倍。我究竟做错了啥?【英文标题】:Numpy EIG approximately 4x slower than MATLAB EIG on Mac OS X 10.6. What am I doing wrong?Numpy EIG 在 Mac OS X 10.6 上比 MATLAB EIG 慢大约 4 倍。我究竟做错了什么? 【发布时间】:2012-03-31 10:16:47 【问题描述】:我尝试在 MATLAB 和 NumPy 上分析 EIG 函数,以比较我的 Macbook Pro(2 GHz,运行 OS X 10.6 的四核 i7)上的性能。与 MATLAB 相比,NumPy EIG 似乎相当慢。
这是我在 NumPy 上分析的代码:
s = '''\
x = numpy.random.random((2000,2000));
numpy.linalg.eig(x);
'''
t = timeit.Timer(stmt=s,setup="import numpy")
result = t.repeat(repeat=5,number=10)
result
Out[22]:
[197.1737039089203,
197.34872913360596,
196.8160741329193,
197.94081807136536,
194.5740351676941]
这在 NumPy 中约为 19.5 秒/执行。
这是 MATLAB 中的相同代码:
clear all
tic;
for i = 1:50
x = rand(2000,2000);
eig(x);
end
toc;
Elapsed time is 267.976645 seconds.
在 MATLAB 上大约是 5.36 秒/执行。
我想像这样简单的事情不应该过多地依赖于 JIT 性能,所以它可能归结为 BLAS 和访问 BLAS 库的例程。我知道 MATLAB 在 Mac 上使用 Accelerate Framework。
NumPy 似乎也在我的 Macbook Pro 上使用了 Accelerate Framework BLAS;这是numpy.show_config()
的输出
numpy.show_config()
lapack_opt_info:
extra_link_args = ['-Wl,-framework', '-Wl,Accelerate']
extra_compile_args = ['-msse3']
define_macros = [('NO_ATLAS_INFO', 3)]
blas_opt_info:
extra_link_args = ['-Wl,-framework', '-Wl,Accelerate']
extra_compile_args = ['-msse3', '-I/System/Library/Frameworks/vecLib.framework/Headers']
define_macros = [('NO_ATLAS_INFO', 3)]
我正在使用 Python 2.7.2 和 NumPy 1.6(均从 MacPorts 安装)
所以这是我对 NumPy 人员的问题: 为什么在这种情况下 NumPy 会变慢?安装 NumPy 时我是否遗漏了一些优化?
【问题讨论】:
【参考方案1】:据我所知,MATLAB 使用 MKL 库作为 BLAS,而不是 Accelerate Framework。 我的经验告诉我,Accelerate 比 MKL 慢得多。 要检查它,您可以尝试获取 Enthought Python Distribution (EPD) 的学术版本,其中 Numpy 是针对 MKL 编译的,并比较这些时间。 此外,默认情况下,MATLAB 使用所有线程(尝试在单线程模式下运行), 但 Numpy 不是。 在EPD中,可以通过running来完成
import mkl
mkl.set_num_threads(4)
【讨论】:
另外,r.e.不。在线程方面,我注意到 NumPy 和 MATLAB 在运行 EIG 时都使用了我机器上可用的所有四个内核;但是,NumPy 运行时的负载比 MATLAB 运行时要低一些(尚未量化)。【参考方案2】:如果我没看错,除了 eig 函数之外,您还在分析随机数生成器的性能。有一次,我将 GAUSS 与 MATLAB 进行比较时犯了这个错误——我会重新考虑随机数生成,看看你得到了什么。
另一个注意事项——对于一些 LAPACK/BLAS 的东西,如果你确保你的 numpy 数组在内部以 Fortran 顺序存储,你可以获得更好的性能:
In [12]: x = numpy.random.random((200,200))
In [13]: x.flags
Out[13]:
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
In [15]: x = numpy.array(x, order="F")
In [16]: x.flags
Out[16]:
C_CONTIGUOUS : False
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False
-克里斯
【讨论】:
你说得对——但我分别尝试比较在 NumPy 和 MATLAB 上生成随机数组所花费的时间,与 EIG 相比,对于这种大小的数组,它们大致相似且可以忽略不计-- 您可以分析代码以查看其大部分时间都花在了哪里! 将数组更改为 Fortran 顺序对 EIG 没有多大帮助。您可以在致电 EIG 之前执行x = x.T
。【参考方案3】:
巨大的不同是因为在 MATLAB 中你只计算特征值,但在 python/numpy 中你同时计算特征值和特征向量。要更正此问题并进行适当的比较,您必须执行以下操作之一: 1. 将 numpy.linalg.eig(x) 更改为 numpy.linalg.eigvals(x) ,保留 matlab 代码,或者 2. 在 matlab 中将 eig(x) 更改为 [V,D] = eig(x),保留 python/numpy 代码不变(这可能会导致 matlab 脚本消耗更多内存) 根据我的经验,使用 MKL 优化的 python/numpy(我使用 windows;不太了解加速框架)与使用 MKL 优化的 matlab 一样快或略快。
【讨论】:
以上是关于Numpy EIG 在 Mac OS X 10.6 上比 MATLAB EIG 慢大约 4 倍。我究竟做错了啥?的主要内容,如果未能解决你的问题,请参考以下文章
在 10.6 (Snow Leopard) 之后以编程方式设置 Mac OS X 音量
Mac OS X >= 10.6 上的 Finder 文件图标标记(图标覆盖)