【问题标题】:Why is Eigen's Cholesky decomposition much faster on Linux than on Windows?为什么 Eigen 的 Cholesky 分解在 Linux 上比在 Windows 上快得多?
【发布时间】:2014-05-07 16:45:29
【问题描述】:

我注意到使用 Eigen 库的 Cholesky 分解存在显着的性能差异。

我正在使用最新版本的 Eigen (3.2.1) 和以下基准代码:

#include <iostream>
#include <chrono>
#include <Eigen/Core>
#include <Eigen/Cholesky>
using namespace std;
using namespace std::chrono;
using namespace Eigen;

int main()
{
    const MatrixXd::Index size = 4200;
    MatrixXd m = MatrixXd::Random(size, size);
    m = (m + m.transpose()) / 2.0 + 10000 * MatrixXd::Identity(size, size);

    LLT<MatrixXd> llt;
    auto start = high_resolution_clock::now();
    llt.compute(m);
    if (llt.info() != Success)
        cout << "Cholesky decomposition failed!" << endl;
    auto stop = high_resolution_clock::now();

    cout << "Cholesky decomposition in "
         << duration_cast<milliseconds>(stop - start).count()
         << " ms." << endl;

    return 0;
}

我用g++ -std=c++11 -Wall -O3 -o bench bench.cc 编译了这个基准,第一次在 Windows 上运行(使用 MinGW,[编辑:GCC 4.8.1]),第二次在 Linux(编辑:GCC 4.8.1)上运行,但两次在同一台机器上。

在 Windows 上,它给了我:

Cholesky decomposition in 10114 ms.

但在 Linux 上我得到:

Cholesky decomposition in 3258 ms.

这不到 Windows 所需时间的三分之一。

Eigen 是否可以在 Linux 系统上使用某些东西来实现这种加速?
如果是这样,我怎样才能在 Windows 上完成相同的操作?

【问题讨论】:

  • 只是一个想法,但我会研究时钟的精度,两个系统上可能不一样?
  • @jcoder:相差 7 。时钟甚至不需要非常准确。
  • 你可以使用我的code,而不是使用 Eigen。在我的系统上,分解一个 5790x5790 矩阵需要 1.36 秒。如果 Eigen 的 Cholesky 分解支持 OpenMP(我知道它适用于矩阵乘法),您应该启用 OpenMP 并查看性能如何。很难并行化 Cholesky 分解,但这就是我所做的(对于 MIMD 和 SIMD)。
  • 对,对不起,我看错时间了,请忽略我的评论。

标签: c++ linux performance eigen


【解决方案1】:

确保您使用的是 64 位系统。如果不是这种情况,请不要忘记启用 SSE2 指令 (-msse2),但由于可用的 SSE 寄存器较少,因此性能仍然不如 64 位系统。

【讨论】:

  • 就是这样。我完全忘记了,我的 MinGW 编译器生成 32 位代码,而 linux 上的 g++ 生成本机 64 位可执行文件。使用 MinGW-64 项目的编译器编译 64 位 Windows 二进制文件,我得到与在 Linux 上相同的计时结果。您对 SSE 的提示也是正确的,为 32 位二进制启用它可以将执行速度提高到 6.8 秒(与 10.1 秒相比)。
【解决方案2】:

参见 Eigen 的主页here

报价

Eigen 已成功用于以下编译器:

GCC,4.1 版及更新版本。 GCC 4.2 的性能非常好 和更新版本。

MSVC (Visual Studio),2008 和更新版本(旧的 2.x Eigen 版本支持 MSVC 2005,但没有矢量化)。

英特尔 C++ 编译器。非常好的表现。

LLVM/CLang++ (2.8 及更高版本)。

MinGW,最新版本。很好 使用 GCC 4 时的性能。

QNX 的 QCC 编译器。

论据

您的 gcc (>=4.2) 版本可能比您使用的 MinGW 版本更新...

注意

顺便说一句,您甚至可能有一个不是“最新”的 MinGW 版本,正如链接中所说:

Eigen 是标准 C++98,因此理论上应该兼容 任何兼容的编译器。 每当我们使用一些非标准功能时,这是可选的,可以 已禁用。

因此,也许您的 gcc 版本使用了 MinGW 不具备的新优化功能,并回退到另一个更慢的替代方案。

当然,说到底,也可能是完全不同的东西,这是基于理论的实验猜测……

【讨论】:

  • 总的来说这是个好主意,谢谢!但在检查了两个系统上的 GCC 版本后,发现两者都使用相同版本的 GCC,即 4.8.1。
  • @Callidior 好吧,很抱歉我的猜测不正确,但我认为我的回答可以在类似情况下打开你的思路。 ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-18
  • 1970-01-01
  • 2020-04-29
  • 2014-10-16
  • 2011-12-25
相关资源
最近更新 更多