C ++ Matrix产品:速度快,变化不大

时间:2015-01-09 20:56:07

标签: c++ matrix sparse-matrix matrix-multiplication

我编写了一个代码,用于将稀疏矩阵与一个完整矩阵相乘。

我创建了2个类:SparseMatrix和Matrix,它将数据存储为向量的共享指针向量。在SparseMatrix案例中,我将项目保存为对象,称为SparseMatrixItem,具有2个属性:position和values。在Matrix案例中,我只是保存了值。 它们可以是行或列,基于bool属性的值。

现在我试图在2个矩阵之间编写一个有效版本的标准产品。通过第一个实现中的简单性,我只考虑第一个矩阵是基于行的SparseMatrix而第二个矩阵是基于列的矩阵的情况。我通过重载运算符*。将代码写入SparseMatrix类。

我发布了我的实施:

template <typename scalar>
Matrix<scalar> SparseVectorMatrix<scalar>::operator*(Matrix<scalar> &input2) {
    Matrix<scalar> newMatrix(getNumberOfRows(),input2.getNumberOfColumns(),true);
    int numberOfRow=newMatrix.getNumberOfRows();
    int numberOfColumn=newMatrix.getNumberOfColumns();

    for (int i=0; i<numberOfRow; i++) {
    vector<SparseMatrixItem<scalar>>& readRow(*horizontalVectorMatrix[i]);
    vector<scalar>& writeRow(*newMatrix.internalMatrix[i]);

        for (int j=0; j<numeroColonne; j++) {
            vector<scalar>& readColumn1(*input2.internalMatrix[j]);
            writeRow[j]=fastScalarProduct(readRow, readColumn1);

        }
    }
}

我无法弄清楚的奇怪事实是,如果我改变2循环顺序,性能会大大加快。 我用2矩阵测试它:6040x4000和4000 * 6040,第一次实现花了将近30秒,而第二次实现只用了12秒。 我发布了它:

template <typename scalar>
Matrix<scalar> SparseVectorMatrix<scalar>::operator*(Matrix<scalar> &input2) {
    Matrix<scalar> newMatrix(getNumberOfRows(),input2.getNumberOfColumns(),true);
    int numberOfRow=newMatrix.getNumberOfRows();
    int numeroColonne=newMatrix.getNumberOfColumns();

    for (int j=0; j<numeroColonne; j++) {
        vector<scalar>& readColumn(*input2.internalMatrix[j]);
        vector<scalar>& writeColumn(*newMatrix.internalMatrix[j]);

        for (int i=0; i<numberOfRow; i++) {
            vector<SparseMatrixItem<scalar>>& readRow(*matriceOrizzontaleVettori[i]);
            writeColumn[i]=fastScalarProduct(readRow, readColumn);
        }
    }
}

我还发布了我使用的函数fastScalarProduct()的代码:

template <typename scalar>
scalar SparseVectorMatrix<scalar>::fastScalarProduct
    ( vector<SparseMatrixItem<scalar>> &vector1
    , const vector<scalar> &vector2
    ) {
    int totalSum=0;
    int position;
    auto sizeVector1=vector1.size();

    for (int i=0; i<sizeVector1; i++) {
        position=vector1[i].position-1;
        if (vector2[position]) {
            totalSum+=(vector1[i].value)*vector2[position];
        }
    }
    return totalSum;
}

我使用MATLAB尝试相同的产品,或多或少只需1.5秒。我认为缓存存在问题,但由于我对这类问题不熟悉,我无法弄清楚真正的问题。

我也试图编写一个高效的全矩阵产品,我也面临同样的问题。

1 个答案:

答案 0 :(得分:1)

你说'#34;问题&#34;是缓存内存。我建议你阅读一下引用的位置(http://en.wikipedia.org/wiki/Locality_of_reference),它解释了当迭代次数最多的循环位于迭代次数较少的循环内时,程序运行速度更快的原因。基本上,数组是线性数据结构,它们充分利用了空间局部性。

至于在matlab和C ++中运行算法的时间,我建议你阅读这篇文章:Why is MATLAB so fast in matrix multiplication?