为什么 Eigen 的 Cholesky 分解在我的 Ubuntu 上非常慢
Why is Eigen's Cholesky decomposition very slow on my Ubuntu
我在 Core i5 机器上使用 Ubuntu 14.04。以下代码在不同的计算机上以非常快的 运行 时间(3258 毫秒)进行了测试,但在我的系统上它需要 112921 毫秒。我使用 g++ 作为编译器。
#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;
}
我假设您是在没有优化的调试模式下编译。
如果您使用的是 CMake,请使用 cmake -DCMAKE_BUILD_TYPE=Release
或 cmake -DCMAKE_BUILD_TYPE=ReleaseWithDebugInfo
进行构建。否则尝试将优化标志 -O3
添加到您的 g++ 编译器。
当您在调试模式下编译程序时(例如 g++ -std=c++11
),很多事情都会在幕后发生。回想一下发生崩溃时您可以看到哪些信息。所有这些信息和内务管理都需要时间。
因此,当您的程序经过测试并且运行良好时,您不再需要内务处理,您希望性能发挥作用。
使用optimization flags, like O1, O2 or O3 (there are more)。使用哪一个? 很大程度上 取决于您的应用,因此至少尝试这三个选项。
注意:确保您使用大写的 Omikron,否则(如果您键入小写的 omikron 或零)您会认为您编译代码时启用了优化,但它仍会在调试模式下编译。
采购 Gcc tutorial:
为 gdb 和许多警告消息生成符号信息。
g++ -g -Wall myprog.C -o myprog
在带有警告的 Solaris 机器上生成优化代码。 -O 是大写字母 o 而不是数字 0!
g++ -Wall -O1 -mv8 myprog.C -o myprog
我在 Core i5 机器上使用 Ubuntu 14.04。以下代码在不同的计算机上以非常快的 运行 时间(3258 毫秒)进行了测试,但在我的系统上它需要 112921 毫秒。我使用 g++ 作为编译器。
#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;
}
我假设您是在没有优化的调试模式下编译。
如果您使用的是 CMake,请使用 cmake -DCMAKE_BUILD_TYPE=Release
或 cmake -DCMAKE_BUILD_TYPE=ReleaseWithDebugInfo
进行构建。否则尝试将优化标志 -O3
添加到您的 g++ 编译器。
当您在调试模式下编译程序时(例如 g++ -std=c++11
),很多事情都会在幕后发生。回想一下发生崩溃时您可以看到哪些信息。所有这些信息和内务管理都需要时间。
因此,当您的程序经过测试并且运行良好时,您不再需要内务处理,您希望性能发挥作用。
使用optimization flags, like O1, O2 or O3 (there are more)。使用哪一个? 很大程度上 取决于您的应用,因此至少尝试这三个选项。
注意:确保您使用大写的 Omikron,否则(如果您键入小写的 omikron 或零)您会认为您编译代码时启用了优化,但它仍会在调试模式下编译。
采购 Gcc tutorial:
为 gdb 和许多警告消息生成符号信息。
g++ -g -Wall myprog.C -o myprog
在带有警告的 Solaris 机器上生成优化代码。 -O 是大写字母 o 而不是数字 0!
g++ -Wall -O1 -mv8 myprog.C -o myprog