代码之家  ›  专栏  ›  技术社区  ›  avgn

为什么稀疏密集乘法比密集稀疏乘法快?

  •  3
  • avgn  · 技术社区  · 6 年前

    我很好奇为什么用一个稀疏矩阵乘以一个稠密矩阵需要不同于相反的时间。算法有显著不同吗?

    下面是matlab 2018a中的一个例子:

    a=sprand(M,M,0.01);
    b=rand(M);
    tic;ref1=a*b;t_axb=toc
    tic;ref2=b*a;t_bxa=toc
    

    下面是一个使用1线程的特征3和C++的例子:

    //prepare acol=MxM ColMajor Eigen sparse matrix with 0.01 density
    ...
    Map<Matrix<double,M,M,ColMajor> > bcol (PR, M, M );
    double tic,toc;
    
    tic=getHighResolutionTime();
    result=acol*bcol;
    toc=getHighResolutionTime();
    printf("\nacol*bcol time: %f seconds", (toc - tic));
    
    tic=getHighResolutionTime();
    result=bcol*acol;
    toc=getHighResolutionTime();
    printf("\nbcol*acol time: %f seconds\n", (toc - tic));
    

    当m=4000时,结果为:

    t_axb =
        0.6877
    t_bxa =
        0.4803
    
    acol*bcol time: 0.937590 seconds
    bcol*acol time: 0.532622 seconds
    

    当M=10000时,结果是

    t_axb =
       11.5649
    t_bxa =
        9.7872
    
    acol*bcol time: 20.140380 seconds
    bcol*acol time: 8.061626 seconds
    

    在这两种情况下,对于Matlab和Eigen,稀疏稠密积都比稠密稀疏积慢我很好奇

    1. 为什么是这个案子稀疏稠密算法与稠密稀疏算法有显著差异吗?失败的次数是一样的,对吧?

    2. 为什么特征值匹配或超过了Matlab对于稠密稀疏的性能而不是稀疏稠密积的性能性能上的一个小差异是正常的,但考虑到两者都是高度优化的库,1.4-1.8的差异似乎很奇怪。我正在根据文档编译所有优化的eign。即 -fPIC -fomit-frame-pointer -O3 -DNDEBUG -fopenmp -march=native

    1 回复  |  直到 6 年前
        1
  •  4
  •   ggael    6 年前

    通过比较稀疏矩阵乘以向量积的列主存储和行主存储,可以观察到相同的差异: y = A * x . 如果 A 是主要行(相当于 y ),则每行 可并行处理,无需任何开销(无通信、无附加临时、无附加操作)。相反,如果 IS列主多线程不能免费提供,而且在大多数情况下,开销大于增益。

    即使没有多线程,您也可以看到内存访问模式非常不同:

    • 行主要:多个随机只读访问 x ,每个系数 是的 只写一个。
    • 少校:每科 是一次读取,但我们可以对目标进行多次随机读写访问 是的 .

    因此,即使没有多线程的情况下,自然有利于行主要。