犰狳库是不是会减慢矩阵运算的执行速度?
Posted
技术标签:
【中文标题】犰狳库是不是会减慢矩阵运算的执行速度?【英文标题】:Does armadillo library slow down the execution of a matrix operations?犰狳库是否会减慢矩阵运算的执行速度? 【发布时间】:2018-05-17 07:57:28 【问题描述】:我已将 MATLAB 代码转换为 C++ 以加快速度,使用 Armadillo 库在 C++ 中处理矩阵运算,但令人惊讶的是它比 MATLAB 代码慢了 10 倍!
所以我测试了犰狳库,看看是否是原因。下面的代码是一个简单的测试代码,它初始化两个矩阵,将它们相加并将结果保存到一个新矩阵中。一段代码使用了 Armadillo 库,而另一段则没有。使用犰狳的部分太慢了(注意经过的时间)。
它真的会减慢执行速度(尽管它应该加快执行速度)还是我错过了什么?
#include<iostream>
#include<math.h>
#include<chrono>
#include<armadillo>
using namespace std;
using namespace arma;
int main()
auto start = std::chrono::high_resolution_clock::now();
double a[100][100];
double b[100][100];
double c[100][100];
for (int i = 0; i < 100; i++)
for (int j = 0; j < 100; j++)
a[i][j] = 1;
b[i][j] = 1;
c[i][j] = a[i][j] + b[i][j];
auto finish = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = finish - start;
std::cout << "Elapsed time: " << elapsed.count() << " s\n";
auto start1 = std::chrono::high_resolution_clock::now();
mat a1=ones(100,100);
mat b1=ones(100,100);
mat c1(100,100);
c1 = a1 + b1;
auto finish1 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed1 = finish1 - start1;
std::cout << "Elapsed time: " << elapsed1.count() << " s\n";
return 0;
这是我得到的答案:
Elapsed time: 5.1729e-05 s
Elapsed time: 0.00025536 s
如您所见,犰狳的速度要慢得多!不使用犰狳库会更好吗?
【问题讨论】:
Performance Tradeoff - When is MATLAB better/slower than C/C++的可能重复 @Wolfie 感谢您提供的链接,我已经检查过了,但我想知道犰狳库是否会减慢代码速度,就像我附加的代码一样。 为什么要使用库来帮助进行矩阵运算,然后手动完成矩阵运算?从 MATLAB 的角度来看,我不知道 C++/Armadillo syntax,但您肯定想在使用 Armadillo 时消除循环并执行mat c1 = a1 + b1
?
你的代码没有任何MATLAB,手头的问题和MATLAB有什么关系?
@MAh2014 不是用 C++ 开发 MATLAB 代码,而是用 C++ 做数学运算,与 MATLAB 无关。此外,MATLAB 是用于矩阵运算的最快代码,因为它在底层使用了高度优化的库。如果你认为你可以写出比 MATLAB 更快的线性代数代码,那么要么你错了,要么你会变得非常富有。我打赌它是第一个 ;)
【参考方案1】:
首先确保blas
和lapack
库已启用,Armadillo doc有说明。
第二件事是它可能是犰狳中更广泛的内存分配。如果您重组代码以首先进行内存初始化为
#include<iostream>
#include<math.h>
#include<chrono>
#include<armadillo>
using namespace std;
using namespace arma;
int main()
double a[100][100];
double b[100][100];
double c[100][100];
mat a1=ones(100,100);
mat b1=ones(100,100);
mat c1(100,100);
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 100; i++)
for (int j = 0; j < 100; j++)
a[i][j] = 1;
b[i][j] = 1;
c[i][j] = a[i][j] + b[i][j];
auto finish = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = finish - start;
std::cout << "Elapsed time: " << elapsed.count() << " s\n";
auto start1 = std::chrono::high_resolution_clock::now();
c1 = a1 + b1;
auto finish1 = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed1 = finish1 - start1;
std::cout << "Elapsed time: " << elapsed1.count() << " s\n";
return 0;
这样我得到了结果:
Elapsed time: 0.000647521 s
Elapsed time: 0.000353198 s
我用(在 Ubuntu 17.10 中)编译它:
g++ prog.cpp -larmadillo
【讨论】:
您是否建议使用犰狳将加速矩阵运算?您是否认为如果我使用犰狳将 matlab 矩阵运算转换为完全相同的 C++ 代码(矩阵运算主要是乘法)会加速吗? 如果您使用矩阵/向量运算,犰狳可能不会比 Matlab 快,但是如果您在 Matlab 中循环迭代计算,您将使用犰狳/C++ 获得性能。一个有趣的比较是在 Matlab 中做两个变体(循环和矩阵),在 Matlab 中的差异很可能比犰狳代码更大 但是它是用低级语言(C++)实现的,即使matlab在矩阵运算方面做得更好,它是否会导致更快的执行?【参考方案2】:我相信问题出在您根本没有使用犰狳。您独特地使用它来创建比 C++ 的普通 2D 数组更复杂的变量,但实际上仅此而已。 Armadillo 可以为您提供非常快速的矩阵运算,就像在c1=a1+b1;
中一样,没有循环。
但是,如果您只是将其编写为 elemetwise 操作,那么您就没有使用犰狳。它与使用 MATLAB 进行矩阵乘法相同,但要自己编写矩阵乘法。那你就不用MATLAB的库了!
【讨论】:
所以如果我删除循环并简单地添加矩阵,它必须比不使用犰狳更快,但事实并非如此。毕竟使用犰狳将matlab代码转换为C++会加快速度吗?我替换了没有循环的代码。 @MAh2014 不,将代码从 MATLAB 转换为犰狳一般不会加快速度,具体取决于您的问题。有时,取决于手头的任务,将 MATLAB 转换为低级语言可以加快速度。但是犰狳专门用于线性代数运算,MATrix LABoratory 软件在这方面做得非常好。但是,对于“它会更快”没有真正的答案,因为这在很大程度上取决于您的问题。以上是关于犰狳库是不是会减慢矩阵运算的执行速度?的主要内容,如果未能解决你的问题,请参考以下文章