基准测试旨在被误解。
让我们看一下矩阵*矩阵乘积。Eigen 网站上此页面上提供的基准告诉您,Eigen(具有自己的 BLAS)提供的时序类似于大型矩阵(n = 1000)的 MKL。我已经在我的计算机(具有核心 i7 的笔记本电脑)上比较了 Eigen 3.2.6 和 MKL 11.3,对于使用一个线程的此类矩阵,MKL 比 Eigen 快 3 倍,比使用 4 个线程的 Eigen 快 10 倍。这看起来是一个完全不同的结论。有两个原因。Eigen 3.2.6(其内部 BLAS)不使用 AVX。此外,它似乎并没有很好地使用多线程。该基准测试隐藏了这一点,因为他们使用的 CPU 不支持多线程,但不支持 AVX。
通常,那些 C++ 库(Eigen、Armadillo、Blaze)会带来两件事:
- 不错的运算符重载:您可以将 +、* 与向量和矩阵一起使用。为了获得良好的性能,他们必须使用称为“智能模板表达式”的棘手技术,以避免在减少时间时出现临时性(例如 y = alpha x1 + beta x2 with y, x1, x2 向量)并引入当它们有用时(例如 A = B * C 与 A、B、C 矩阵)。它们还可以重新排序操作以减少计算量,例如,如果 A、B、C 是矩阵 A * B * C 可以根据它们的大小计算为 (A * B) * C 或 A * (B * C)。
- 内部 BLAS:要计算 2 个矩阵的乘积,它们可以依赖其内部 BLAS 或外部提供的一个(MKL、OpenBLAS、ATLAS)。在具有大型矩阵的英特尔芯片上,MKL 几乎不可能被击败。对于小型矩阵,可以击败 MKL,因为它不是为此类问题而设计的。
通常,当这些库提供针对 MKL 的基准测试时,它们通常使用旧硬件,并且不会打开多线程,因此它们可以与 MKL 相提并论。他们还可能将 BLAS 1 级操作(例如 y = alpha x1 + beta x2)与 2 次调用 BLAS 1 级函数进行比较,这无论如何都是一件愚蠢的事情。
简而言之,这些库对于 + 和 * 的重载非常方便,而这在不损失性能的情况下很难做到。他们通常在这方面做得很好。但是当他们给你基准说他们可以用自己的 BLAS 达到或击败 MKL 时,要小心并做你自己的基准。你通常会得到不同的结果;-)。