矩阵乘法优化

5
我正在执行一系列相当大的矩阵乘法。要运行所有这些操作需要很长时间,我需要我的程序在一个大循环中完成。我想知道是否有人有任何加速的想法?我刚开始使用Eigen,所以我的知识非常有限。 我曾使用过ROOT-cern内置的TMatrix类,但是执行矩阵操作的速度非常慢。我使用Eigen设置了一些对角矩阵,希望它以更优化的方式处理乘法运算。可能是这样,但我无法真正看到性能差异。
// setup matrices
int size = 8000;

Eigen::MatrixXf a(size*2,size);

// fill matrix a....

Eigen::MatrixXf r(2*size,2*size); // diagonal matrix of row sums of a

// fill matrix r

Eigen::MatrixXf c(size,size); // diagonal matrix of col sums of a

// fill matrix c

// transpose a in place
a.transposeInPlace();

Eigen::MatrixXf c_dia;
c_dia = c.diagonal().asDiagonal();

Eigen::MatrixXf r_dia;
r_dia = r.diagonal().asDiagonal();

// calc car
Eigen::MatrixXf car;
car = c_dia*a*r_dia;

这样做会更快吗?Eigen::MatrixXf car = ((a.transpose().array().rowwise() * a.colwise().sum()).colwise() * a.rowwise().sum()).matrix() - jdehesa
2
你真的期望将一个8000x8000的矩阵乘以一个16000x8000的矩阵会很快吗?除非你了解矩阵的结构,并且这种结构可以被利用,否则你获得良好速度的机会将是渺茫的。 - Peter
1
我没想到它会这么快。我希望我是在忽略某些非常简单和明显的东西。看起来我确实是这样。感谢您的评论! - j_natt
1个回答

6
你在这里做的工作太多了。如果你有对角矩阵,只需存储对角线(并直接将其用于乘积)。一旦你将对角矩阵存储在方形矩阵中,结构信息将丢失到Eigen中。
此外,你不需要存储a的转置变量,只需在乘积中使用a.transpose()(这只是一个小问题...)
// setup matrices
int size = 8000;

Eigen::MatrixXf a(size*2,size);

// fill matrix a....
a.setRandom();

Eigen::VectorXf r = a.rowwise().sum(); // diagonal matrix of row sums of a
Eigen::VectorXf c = a.colwise().sum(); // diagonal matrix of col sums of a

Eigen::MatrixXf car = c.asDiagonal() * a.transpose() * r.asDiagonal();

最后,当然要确保启用了优化编译,并且如果可用,启用矢量化(使用gcc或clang编译时使用-O2 -march=native)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接