【发布时间】:2013-01-24 20:20:25
【问题描述】:
我正在使用 Eigen 库研究两个大矩阵的简单乘法。对于相同大小的矩阵,这种乘法似乎明显慢于 Matlab 和 Python。
有什么办法可以让 Eigen 运算更快?
问题详情
X : 随机 1000 x 50000 矩阵
Y : 随机 50000 x 300 矩阵
计时实验(在我 2011 年末的 Macbook Pro 上)
使用 Matlab:X*Y 需要 ~1.3 秒
使用 Enthought Python:numpy.dot(X, Y) 大约需要 2.2 秒
使用 Eigen:X*Y 需要 ~2.7 秒
特征细节
您可以获得我的特征码(作为 MEX 函数):https://gist.github.com/michaelchughes/4742878
这个 MEX 函数从 Matlab 中读取两个矩阵,并返回它们的乘积。
在没有矩阵乘积运算的情况下运行这个 MEX 函数(即只进行 IO)产生的开销可以忽略不计,因此函数和 Matlab 之间的 IO 并不能解释性能上的巨大差异。这显然是实际的矩阵乘积运算。
我正在使用 g++ 编译,带有这些优化标志:“-O3 -DNDEBUG”
我正在使用最新的稳定 Eigen 头文件 (3.1.2)。
关于如何提高 Eigen 性能的任何建议?谁能复制我看到的差距?
更新 编译器似乎真的很重要。最初的 Eigen 计时是使用 Apple XCode 的 g++ 版本完成的:llvm-g++-4.2。
当我使用通过 MacPorts 下载的 g++-4.7(相同的 CXXOPTIMFLAGS)时,我得到 2.4 秒而不是 2.7 秒。
任何其他关于如何更好地编译的建议将不胜感激。
您还可以获取此实验的原始 C++ 代码:https://gist.github.com/michaelchughes/4747789
./MatProdEigen 1000 50000 300
在g++-4.7下报2.4秒
【问题讨论】:
-
你知道它实现了什么算法吗?看起来它可能只是使用了一个糟糕的矩阵乘法算法。要尝试的另一件事是启用自动矢量化:gcc.gnu.org/projects/tree-ssa/vectorization.html(默认情况下不启用,我不认为......好吧,也许。不确定)。如果您在英特尔机器上,请尝试使用英特尔编译器......我注意到它在优化方面总是优于其他所有人。也可以在这里查看eigen.tuxfamily.org/index.php?title=FAQ#Vectorization
-
@thang:Eigen 是为线性代数设计的,所以如果使用的算法那么糟糕,我会感到惊讶。根据您的链接,我使用“-O3”优化标志默认启用树矢量化,所以这不是问题 AFAIK。如果没有其他建议出现,我可能会尝试英特尔编译器。
-
@MikeHuges,您还可以尝试绘制随着矩阵大小增加的增长率,并可能对正在发生的事情提供一些提示。这应该表明它使用哪种算法。或者,深入研究他们的源代码或文档。
-
嗨,我用了大约 260 秒在我的机器上运行测试 C++ 代码,我使用 VS2012 和 windows,我的处理器是核心 i5-4570。在测试矩阵乘法时,我也花了大约 1.3 秒。这很有线。