为什么 cuSparse 对于稀疏矩阵乘法比 cuBlas 慢得多

Why cuSparse is much slower than cuBlas for sparse matrix multiplication

最近在CUDA TOOLKIT 6.5中使用cuSparse和cuBLAS做稀疏矩阵乘法,发现cuSPARSE在所有情况下都比cuBLAS慢很多!

在我所有的实验中,我在 cuSparse 中使用 cusparseScsrmm,在 cuBLAS 中使用 cublasSgemm。在稀疏矩阵中,总元素的一半为零。我使用的 GPU 是 NVIDIA Titan Black。此外,所有消耗的时间都是通过NVIDIA提供的nvvp工具获得的。以下是部分结果:

实验 A:

  1. 稀疏矩阵大小:192x2400
  2. 密集矩阵大小:2400x256
  3. cusparse 时间:1.4ms
  4. cublas 时间:0.21ms

实验 B:

  1. 稀疏矩阵大小:192x75
  2. 密集矩阵大小:75x1024
  3. cusparse 时间:0.27ms
  4. cublas 时间:0.04ms

所以,看到上面列出的结果很奇怪。因为 cuSPARSE 是专门为处理稀疏矩阵操作而设计的,它怎么可能比 cuBLAS 还慢!?如果是这样,则根本不需要使用 cuSPARSE。你能给我解释一下结果吗?另外,你能建议任何其他加速稀疏矩阵乘法的方法吗?

我认为您不能将具有半个零的矩阵分类为 "sparse":您发现的时间安排是合理的(实际上稀疏算法表现得很好!)。

稀疏算法仅在考虑大多数元素为零的矩阵时才有效(例如,来自有限元问题的矩阵)。

这不仅适用于 GPU,也适用于 CPU:将矩阵视为稀疏矩阵会产生很大的开销,并且仅当...大多数元素为零(典型值:10)时才方便使用稀疏算法每行或更少的非零,秩矩阵千 - 十万 - (百万?))。

还有其他具有高效求解算法的矩阵形状,如果它适用于您的问题,您可以尝试,例如带矩阵。不过,我不知道它们是否已移植到 cuBlas。

关于管理费用

密集线性代数算法可以最佳地执行,因为处理器的设计是为了最有效地解决此类系统。考虑 DGEMM 运算(矩阵-矩阵乘法):对于大型矩阵(即,不适合系统的任何缓存的矩阵),它是一种让您以 >95% 的理论峰值浮点性能使用处理器的运算。怎么样?

  • 预取
  • 最佳缓存使用率
  • 矢量化(SSE、AVX)
  • 流水线

在稀疏 LA 算法中,只有非零元素及其对应的索引存储在内存中:内存访问实际上是 间接 。所以稀疏算法无法在相同的优化级别上利用硬件:我不知道这方面的具体数字,但 10% 到 20% 并不奇怪。

好处显然是根本不执行对零(对非存储元素)的操作,从而导致数量级减少操作和更少需要的存储。

整数逻辑、条件语句还有更多的开销,但现代 CPU 在重叠整数和 FP 操作方面非常好,并且 "speculative executions"。不幸的是,它们也可以阻止矢量化,因此在 dense 情况下会产生更多的开销。

GPU 呢?

密集 LA 算法与 CPU 一样最适合 GPU:在这种情况下,您可以最佳使用:

  • 合并
  • 共享内存
  • 内存访问模式

再次间接访问稀疏 LA 算法中的矩阵元素阻止利用相同级别的优化。

参考资料

我不记得遇到稀疏问题时使用的是哪个...我认为是PSBLAS:http://people.uniroma2.it/salvatore.filippone/psblas/

但在这里你会被他们淹没: http://www.netlib.org/utk/people/JackDongarra/la-sw.html