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 音量

Qt 5.4 - Mac OS X 10.6 支持

MAC OS X 10.6 中的通知中心备用

Mac OS X >= 10.6 上的 Finder 文件图标标记(图标覆盖)

在 10.6 上测试 Mac OS X 10.7 特定代码时出现“未找到符号”崩溃

在Mac OS X 10.6上的Python中,无法在Matplotlib中将字体更改为Helvetica