性能测试-Armadillo(OpenBLAS),Eigen3,numpy,QR分解
微信公众号:科文路。转发须注明出处。
想一窥两个 C++ 矩阵库的性能,写了个程序,对比测试了下两个库在 QR 分解上的计算时间。
为了不让错误的结论影响他人,诚邀勘误。
声明:请勿将此文作为严肃文章参考!Notice: This article is not rigorous!
1 环境
- 某不方便透露的比较强的服务器。
- GCC 7.5.0
- CentOS 6
2 版本
- numpy,1.19.2
- Armadillo 10.7.3,动态库
- OpenBLAS 0.3.18,动态库
- Eigen 3.4.0,头文件
3 数据
4 个随机数矩阵
1 | import numpy as np |
4 代码
加载数据
- numpy,使用
loadtxt
- Armadillo,使用
arma::mat
和它的load()
函数 - Eigen3,使用
fstream
写入Eigen::MatrixXd
QR 分解
- Armadillo,使用
arma::qr_econ()
计算后取得R
矩阵 - Eigen3,使用
HouseholderQR<MatrixXd>
构造初始化后,由matrixQR().triangularView<Upper>()
取得R
矩阵
计时
- numpy,使用
%%timeit
- Armadillo,使用
std::chrono
计时,各跑 5 次后计算平均数 - Eigen3, 使用
std::chrono
计时,各跑 5 次后计算平均数
5 结果
- QR 分解平均时间,单位(除特别说明外,µs),四舍五入到个位
R
矩阵末行末列数,作为判断计算结果正确性依据
numpy
- 10x10,846 µs ± 793 µs
- 100x100,3.96 ms ± 2.93 ms
- 1000x1000,60.1 ms ± 3.68 ms
- 10000x10000,6.78 s ± 7.94 ms
Armadillo
- 10x10,95
- 100x100,11 867
- 1000x1000,8 451 469
- 10000x10000,
154254133(计算错误)
Eigen3
- 10x10,145
- 100x100,17 508
- 1000x1000,7 898 760
- 10000x10000,7 402 371 332
Eigen3,采取 -O2 编译选项
- 10x10,10
- 100x100,402
- 1000x1000,118 003
- 10000x10000,119 083 247
Eigen3,采取 -O2 -march=native 编译选项
感谢知乎评论区 @插地魔 指导
- 10x10,15
- 100x100,316
- 1000x1000,35 439
- 10000x10000,31 657 171
6 结论
- numpy 快,不知具体原因(可能 C++ 这边受运行时库拖累了?)
- Armadillo 在矩阵较小时,对 Eigen3 有微弱优势;但当矩阵较大时,不能得出结果
- Eigen3 仅使用头文件就能运行;能在矩阵较大时得出正确结果;采取
-O2 -march=native
编译选项后,Eigen3 速度得到大幅提升,但仍比numpy
慢很多。
Eigen3,棒!
性能测试-Armadillo(OpenBLAS),Eigen3,numpy,QR分解