MATLAB的速度是Numpy的两倍



我是一名工程研究生,目前正在从MATLAB过渡到Python进行数值模拟。我的印象是,对于基本的数组操作,Numpy会像MATLAB一样快。然而,对于我编写的两个不同的程序,MATLAB的速度似乎是Numpy的两倍。我为Numpy(Python 3.3)使用的测试代码是:

import numpy as np
import time
a = np.random.rand(5000,5000,3)
tic = time.time()
a[:,:,0] = a[:,:,1]
a[:,:,2] = a[:,:,0]
a[:,:,1] = a[:,:,2]
toc = time.time() - tic
print(toc)

而对于MATLAB 2012a,我使用的是:

a = rand(5000,5000,3);
tic;
a(:,:,1) = a(:,:,2);
a(:,:,3) = a(:,:,1);
a(:,:,2) = a(:,:,3);
toc

我使用的算法是美国国家航空航天局网站上使用的比较Numpy和MATLAB的算法。该网站显示,Numpy在该算法的速度方面超过了MATLAB。然而,我的结果显示Numpy的模拟时间为0.49秒,MATLAB的模拟时间则为0.29秒。我还在Numpy和Matlab上运行了高斯-塞德尔解算器,得到了类似的结果(16.5秒对9.5秒)

我是Python的新手,在编程方面不是很精通。我使用的是WinPython 64位Python发行版,但也尝试过Pythonxy,但没有成功。

我读过一件应该可以提高性能的事情,那就是使用MKL构建Numpy。不幸的是,我不知道如何在Windows上做到这一点。我需要这样做吗?

有什么建议吗?

由于缓存,这种比较最终是苹果对桔子的比较,因为在连续的内存块上传输或做一些工作更有效。这个特定的基准测试是内存绑定的,因为实际上不需要进行计算,因此缓存命中率是实现良好性能的关键。

Matlab将数据按列主顺序(Fortran顺序)排列,因此a(:,:,k)是一个连续的内存块,复制速度很快。

Numpy默认为行主顺序(C顺序),因此在a[:,:,k]中,元素之间有很大的跳跃,这会减慢内存传输。实际上,数据布局是可以选择的。在我的笔记本电脑中,用a = np.asfortranarray(np.random.rand(5000,5000,3)) LED创建阵列的速度提高了5倍(1秒vs 0.19秒)。

对于numpy MKL和普通numpy来说,这个结果应该非常相似,因为MKL是一个快速的LAPACK实现,并且在这里你没有调用任何使用它的函数(MKL在求解线性系统、计算点积时肯定有帮助…)。

我真的不知道高斯-塞德尔解算器发生了什么,但不久前,我写了一个题为"Numpy以MATLAB一半的速度运行"的问题的答案,其中谈到了MKL、FFT和MATLAB的JIT。

您正试图重新创建NASA实验,但您已经更改了许多变量。例如:

  • 您的硬件和操作系统不同(www.ccs.nasa.gov/dali_front.html)
  • 您的Python版本不同(2.5.3与3.3)
  • 您的MATLAB版本不同(2008年与2012年)

假设美国国家航空航天局的结果是正确的,结果的差异是由于这些变量中的一个或多个发生了变化。我推荐你:

  • 使用SciPy预构建的二进制文件重新测试
  • 研究MATLAB相对于这种类型的计算是否有任何改进

此外,您可能会发现此链接很有用。