矩阵加法只需要n^2次加法,而矩阵-向量乘法需要n*(n-1)次加法和n^2次乘法。
但是,在Eigen中,矩阵加法的时间是矩阵-向量乘法的两倍。是否存在任何选项来加速Eigen中的矩阵加法操作?
#include <eigen3/Eigen/Eigen>
#include <iostream>
#include <ctime>
#include <string>
#include <chrono>
#include <fstream>
#include <random>
#include <iomanip>
using namespace Eigen;
using namespace std;
int main()
{
const int l=100;
MatrixXf m=MatrixXf::Random(l,l);
MatrixXf n=MatrixXf::Random(l,l);
VectorXf v=VectorXf::Random(l,1);
MatrixXf qq=MatrixXf::Random(l,1);
MatrixXf pp=MatrixXf::Random(l,l);
auto start = chrono::steady_clock::now();
for(int j=0;j<10000;j++)
qq=m*v;
auto end = chrono::steady_clock::now();
double time_duration=chrono::duration_cast<chrono::milliseconds>(end - start).count();
std::cout << setprecision(6) << "Elapsed time in seconds : "<< time_duration/1000<< "s" << std::endl;
auto start1 = chrono::steady_clock::now();
for(int j=0;j<10000;j++)
pp=m+n;
auto end1 = chrono::steady_clock::now();
double time_duration1=chrono::duration_cast<chrono::milliseconds>(end1 - start1).count();
std::cout << setprecision(6) << "Elapsed time in seconds : "<< time_duration1/1000<< "s" << std::endl;
}
测试1:无任何优化:
编译命令:g++-8 -test.cpp -o test
运行命令:./test
用时(秒):0.323秒
用时(秒):0.635秒
测试2:使用-march=native优化:
编译命令:g++-8 test.cpp -march=native -o test
运行命令:./test
用时(秒):0.21秒
用时(秒):0.372秒
测试3:使用-O3优化:
编译命令:g++-8 -test.cpp -O3 -o test
运行命令:./test
用时(秒):0.009秒
用时(秒):0.016秒
测试4:使用-march=native,-O3优化:
编译命令:g++-8 -test.cpp -march=native -O3 -o test
运行命令:./test
用时(秒):0.008秒
用时(秒):0.016秒
==============
我注意到有评论说编译器可能作弊,因为我没有使用前一次迭代的结果。为了解决这个问题,我改为进行一次迭代,并使用更大的数据量进行稳定的时间统计。
#include <eigen3/Eigen/Eigen>
#include <iostream>
#include <ctime>
#include <string>
#include <chrono>
#include <fstream>
#include <random>
#include <iomanip>
using namespace Eigen;
using namespace std;
int main()
{
const int l=1000;
MatrixXf m=MatrixXf::Random(l,l);
MatrixXf n=MatrixXf::Random(l,l);
VectorXf v=VectorXf::Random(l,1);
MatrixXf qq=MatrixXf::Random(l,1);
MatrixXf pp=MatrixXf::Random(l,l);
auto start = chrono::steady_clock::now();
qq=m*v;
auto end = chrono::steady_clock::now();
double time_duration=chrono::duration_cast<chrono::microseconds>(end - start).count();
auto start1 = chrono::steady_clock::now();
pp=m+n;
auto end1 = chrono::steady_clock::now();
double time_duration1=chrono::duration_cast<chrono::microseconds>(end1 - start1).count();
std::cout << setprecision(6) << "Elapsed time in microseconds : "<< time_duration<< "us" << std::endl;
std::cout << setprecision(6) << "Elapsed time in microseconds : "<< time_duration1<< "us" << std::endl;
}
测试1:没有任何优化:
编译命令:g++-8 -test.cpp -o test
运行命令:./test
微秒级的经过时间:3125us
微秒级的经过时间:6849us
测试2:使用-march=native优化:
编译命令:g++-8 test.cpp -march=native -o test
运行命令:./test
微秒级的经过时间:1776us
微秒级的经过时间:3815us
测试3:使用-O3优化:
编译命令:g++-8 -test.cpp -O3 -o test
运行命令:./test
微秒级的经过时间:449us
微秒级的经过时间:760us
测试4:使用-march=native、-O3优化:
编译命令:g++-8 -test.cpp -march=native -O3 -o test
运行命令:./test
微秒级的经过时间:351us
微秒级的经过时间:871us