C ++ Eigen库如何比专业供应商库更好地运行?

时间:2012-04-28 17:52:25

标签: c++ performance eigen

我正在查看效果基准:http://eigen.tuxfamily.org/index.php?title=Benchmark

我忍不住注意到,eigen似乎始终优于所有专业供应商库。问题是:怎么可能?可以假设mkl / goto将使用特定于处理器的调优代码,而eigen则相当通用。

注意这个http://download.tuxfamily.org/eigen/btl-results-110323/aat.pdf,基本上是一个dgemm。对于N = 1000,Eigen大约为17Gf,MKL仅为12Gf

6 个答案:

答案 0 :(得分:27)

Eigen有懒惰的评价。来自How does Eigen compare to BLAS/LAPACK?

  

对于涉及复杂表达式的操作,Eigen本质上是   比任何BLAS实现都要快,因为它可以处理和优化   全局的整个操作 - 而BLAS强迫程序员   将复杂的操作分成与BLAS匹配的小步骤   固定功能API,由于引入而导致效率低下   临时工。例如,参见Y = a X + b Y的基准测试结果   在Eigen时涉及两次调用BLAS level1例程的操作   自动生成一个矢量化循环。

benchmarks中的第二个图表是Y = a*X + b*Y,Eigen是专门设计用来处理的。毫无疑问,图书馆会在创建的基准测试中获胜。您会注意到更通用的基准测试,如矩阵 - 矩阵乘法,对于Eigen没有任何优势。

答案 1 :(得分:26)

基准旨在被误解

让我们看一下矩阵*矩阵乘积。 Eigen网站上page提供的基准测试告诉您,Eigen(有自己的BLAS)给出的时序与大矩阵的MKL类似(n = 1000)。我在我的计算机(具有核心i7的笔记本电脑)上比较了Eigen 3.2.6和MKL 11.3,对于使用一个线程的矩阵,MKL比Eigen快3倍,比使用4个线程的Eigen快10倍。这看起来完全不同。有两个原因。 Eigen 3.2.6(其内部BLAS)不使用AVX。而且,它似乎没有很好地利用多线程。这个基准测试隐藏了这一点,因为他们在没有多线程的情况下使用没有AVX支持的CPU。

通常,那些C ++库(Eigen,Armadillo,Blaze)带来两件事:

  • Nice运算符重载:您可以将+,*与向量和矩阵一起使用。为了获得良好的性能,他们必须使用称为“智能模板表达式”的棘手技术,以避免在缩短时序时暂时(例如y = alpha x1 + beta x2 with y,x1,x2 vector)并引入当它们有用时(例如A = B * C,A,B,C矩阵)。他们也可以为较少的计算重新排序操作,例如,如果A,B,C是矩阵,A * B * C可以根据它们的大小计算为(A * B)* C或A *(B * C)。 / LI>
  • 内部BLAS :要计算2个矩阵的乘积,它们可以依赖于其内部BLAS或外部提供的BLAS(MKL,OpenBLAS,ATLAS)。在具有大型矩阵的英特尔芯片上,MKL il几乎不可能被击败。对于小型矩阵,可以击败MKL,因为它不是为那种问题而设计的。

通常,当这些库提供针对MKL的基准时,它们通常使用旧硬件,并且不打开多线程,因此它们可以与MKL相提并论。他们也可能将BLAS 1级操作(例如y = alpha x1 + beta x2)与2次调用BLAS 1级函数进行比较。无论如何,这都是一个愚蠢的事情。

简而言之,这些库非常方便他们的+和*的重载,这是非常难以做到而不会失去性能。他们通常在这方面做得很好。但是当他们给你基准测试表明他们可以与他们自己的BLAS相提并论击败MKL时,要小心并做自己的基准测试。你通常会得到不同的结果; - )。

答案 2 :(得分:11)

关于比较ATLAS与Eigen

从这里开始查看Eigen邮件列表中的这个主题:

例如,它表明ATLAS在矩阵矩阵乘积上的表现优于46%:

更多基准测试结果和基准测试如何完成的详细信息可以在这里找到:

编辑:

在我的演讲“高性能计算的软件基础知识”中,我创建了一个名为ulmBLAS的小框架。它包含ATLAS基准测试套件,学生可以根据BLIS论文实现自己的矩阵矩阵产品。您可以查看最终基准,这些基准也可以衡量Eigen:

您可以使用ulmBLAS框架制作自己的基准。

另外看看

答案 3 :(得分:2)

它似乎并不总是优于其他库,正如您在链接的页面上的图表中可以看到的那样。因此,不同的库针对不同的用例进行了优化,不同的库可以更快地解决不同的问题。

这并不奇怪,因为您通常无法完美地优化所有用例。针对一个特定操作进行优化通常会限制其他用例的优化选项。

答案 4 :(得分:2)

我前段时间向ATLAS邮件列表发送了同样的问题:

http://sourceforge.net/mailarchive/message.php?msg_id=28711667

Clint(ATLAS开发人员)不信任这些基准测试。他提出了一些值得信赖的基准程序。只要我有空闲时间,我就会做这种基准测试。

如果Eigen的BLAS功能实际上比GotoBLAS / GotoBLAS,ATLAS,MKL快,那么他们应该提供标准的BLAS接口。这将允许LAPACK与这种Eigen-BLAS的链接。在这种情况下,它对Matlab和朋友来说也是一个有趣的选择。

答案 5 :(得分:2)

通用代码可以很快,因为编译时功能评估(CTFE)允许选择最佳寄存器阻塞策略(存储在CPU寄存器中的小型临时子矩阵)。

Mir GLAS和英特尔MKL比Eigen和OpenBLAS更快。 与Eigen相比,Mir GLAS更通用。另请参阅benchmarkreddit thread