特征计划中的绩效瓶颈

时间:2015-04-22 10:59:20

标签: c++ sparse-matrix eigen

作为一个更大问题的一部分,我在处理Eigen中的稀疏矩阵时遇到了性能瓶颈。

我需要从稀疏矩阵(x)中的每个元素中减去浮点数(G),包括系数为零的位置。因此,零元素应具有值-x

目前我这样做的方式如下:

//calculate G
x=0.01;
for(int i=0;i<rows;i++){
   for (int j=0; j<cols; j++) {
       G.coeffRef(i, j) -= x;
   }
}

当G的大小很大时,这个简单的计算是一个瓶颈。

我还尝试将稀疏矩阵G转换为密集矩阵并减去P(填充值x的矩阵):

MatrixXd DenseG=MatrixXd(G);
x=0.01;
for(int i=0;i<rows;i++){
   for (int j=0; j<cols; j++) {
       DenseG(i, j) -= x;
   }
}

这种方法要快得多。但是,我只是想知道是否有其他的解决方法不涉及将G转换为密集的,在非常大的矩阵的情况下需要大量的内存。

2 个答案:

答案 0 :(得分:3)

你的&#34;稀疏&#34;当你从所有n^2元素中减去时,计算实际上是一个密集的计算。一个主要的区别是,不是在一块内存上完成单个操作,而是每次访问零元素时都必须为矩阵分配内存。通常,稀疏矩阵在稀疏时是有效的,并且对于大多数操作而言会产生大量开销。只需要存储很少的元素就可以平衡这种开销,因此,只需重复几次操作。

另一种可能的选择是利用Eigen's lazy evaluation,但这有点取决于您的具体要求,此处未列出。

答案 1 :(得分:1)

正如Avi Ginsburg所说,此操作会导致密集矩阵失去G-X的所有结构,其中G是初始稀疏矩阵,X是一个填充x的抽象密集矩阵{1}}。

我建议您尝试在算法的其余部分中将这两个术语分开,并更新数学以利用此特殊结构。例如,如果下一步是将其乘以密集向量v,那么您可以有利地利用它:

(G-X)*v == (G*v).array()-v.sum()*x