关于C++中Eigen库效率提升的思考

目录

  • 引言
  • 一、什么是Eigen?
  • 二、使用步骤
    • 1.引入库
    • 2.建立矩阵
    • 3.基本操作
  • 三、具体的例子--矩阵乘法
    • 1.Eigen库
    • 2.GPU并行计算
  • 总结
  • 可能的方案


引言

在处理矩阵运算上,各种语言都有了自己的处理办法,例如:Python中的numpy库以及C++中的eigen库等。本文主要思考在C++语言中,如何采用GPU加速计算,进一步提高矩阵计算效率。


一、什么是Eigen?

Eigen本身是一个线性代数库,在处理矩阵运算上非常有优势,类似于Python中的numpy。不同的是,Eigen是基于C++模板的。

二、使用步骤

1.引入库

// 基本包括所需要的所有函数
#include 

2.建立矩阵

Matrix<double, 3, 3> A; // 表示A是一个三行三列的double矩阵
A << 1, 2, 3, 4, 5, 6, 7, 8, 9;

VectorXd vec1(3); // 动态double列向量
vec2 << 1, 2, 3;

RowVectorXd vec2(4); // 动态double行向量
vec2 << 1, 4, 9, 16;

3.基本操作

cout<< A.rows(); // 行数:3
cout<< A.cols(); // 列数:3
cout<< A(3); // 第4个元素,按列存储:5
cout<< A(1, 2); // 第2行第3列的元素:6

三、具体的例子–矩阵乘法

1.Eigen库

#include 
#include
#include

using namespace std;
using namespace Eigen;
int main()
{
     
	clock_t start, end;
	MatrixXd M, N;
	M.setRandom(1024, 1024);
	N.setRandom(1024, 1024);
	MatrixXd result(1024, 1024);
	start = clock();
	result=M * N;
	end = clock();
	double result1=result.sum();
	cout<<"the sum of matrix is : "<<endl <<result1<<endl;
	cout<<"the total time is : "<<(double)(end - start) / CLOCKS_PER_SEC<<"s."<<endl;

	return 0;
}

运行结果:
关于C++中Eigen库效率提升的思考_第1张图片该图为Eigen计算结果,由于编译器以及设备的原因,显示时间慢了很多,如果是同一设备则应当同GPU时间相差没有这么大。


2.GPU并行计算

关于C++中Eigen库效率提升的思考_第2张图片此图为GPU并行计算矩阵相乘所需要的时间,两个矩阵的大小均为1024*1024, 数据类型为float。注:由于服务器性能较好,故得出的结果可能较普通机器快一些。


总结

根据Eigen和GPU并行计算的时间,可以看出差距还是存在的(也有可能是我没有理解到Eigen的精髓,代码写的不对),但比起普通的矩阵乘法明显快了几倍。如果数据量较小的话,二者所需要的时间则会更加接近,因此改进的必要性需要考虑。同时,由于Eigen库中方法是封装起来的,使用者只能够调用,改进的难度较大。

可能的方案

由于Eigen的计算效率确实比GPU低,如果一定要使用GPU加速的话。我认为可行的方法是放弃Eigen,将需要用到的操作自行实现,封装为一个个的kernel函数,只需要在使用的时候配置线程即可。但也有一些问题需要解决:

  1. 跨文件访问的问题:通常上传到服务器的是一个.cu文件,如何上传整个项目需要下功夫。
  2. 将需要的方法封装为kernel函数:难点。
  3. 放弃Eigen的优越性:Eigen作为一个强大的库,自有其优越的地方,完全放弃是否可取?

以上仅作为一个Eigen初学者的个人理解,如有错误,敬请指出。

你可能感兴趣的:(c++,线性代数,矩阵)