稀疏矩阵与密集矩阵乘法 C++ Tensorflow

Posted

技术标签:

【中文标题】稀疏矩阵与密集矩阵乘法 C++ Tensorflow【英文标题】:Sparse Matrix Vs Dense Matrix Multiplication C++ Tensorflow 【发布时间】:2020-07-28 05:32:16 【问题描述】:

我想用 C++ Tensorflow 写稀疏矩阵密集向量(SPMv)乘法:y = Ax

稀疏矩阵 A 以 CSR 格式存储。 A 的通常稀疏度在 50-90% 之间。目标是达到比密集矩阵密集向量 (DMv) 乘法更好或相似的时间

请注意,我已经查看了以下帖子:Q1Q2Q3。但是,我仍然想知道以下几点:

    SPMv 乘法在时间方面与 DMv 相比如何?由于稀疏性相对较高,我认为 SPMv 应该更好,因为减少了操作数量 - 是吗? 为了使 SpMv 在时间上与 DMv 相同或更好,我应该考虑哪些因素?为什么有人说 DMv 会比 SPMv 表现得更好?存储表示会有所不同吗? 任何在 C++ 中为 CPU 或 GPU 实现执行 SPMv 的推荐库。

这个问题与我在这里的另一个问题有关:(CSCC: Convolution Split Compression Calculation Algorithm for Deep Neural Network)

【问题讨论】:

50% 的稀疏度不值得使用任何稀疏矩阵格式。为了让它变得有价值,它需要远低于 1%。 @HossamAmer 稀疏格式要求至少存储每个条目以及条目的列或行索引。因此,假设 32 位索引和值是存储的因子 > 2。并且缓存中的数据不那么规则且更难(而且您可能会丢失矢量化)。 @Joe 谢谢!我编辑了我的问题,让我们只关注时间......我希望我的执行时间比 DMv 更好我已经看到以下 link 解释了 CSR 乘法 - 即使其中有这个算法,时间会更糟?我认为内存访问是连续的和缓存友好的 + 更少的(加法和乘法)操作 - 不是吗? 欢迎来到 SO;关于您的第三个问题,请花点时间阅读What topics can I ask about here?,并注意要求我们推荐或查找书籍、工具、软件库、教程或其他非现场资源的问题已关闭-SO 的主题。 好的,谢谢! :) 【参考方案1】:

回答编辑后的问题:

    除非矩阵非常稀疏(在 CPU 上 至少翻了一番(列或行索引 + 值),内存访问是不规则的(您可以通过右索引间接访问 -手边),矢量化(或在 GPU 上实现合并)变得更加困难,如果您进行并行化,您必须处理行长度不同的事实,因此静态调度可能不是最佳的。李> 除了以上几点,是的,存储表示很重要。例如,COO 矩阵存储 两个 索引和值,而 CSR/CSC 只存储一个但需要一个额外的偏移数组,这使得它们在运行中构建起来更加复杂。特别是在 GPU 上,如果您想至少实现一些合并,存储格式很重要。本文研究了存储格式如何影响 GPU 的性能:https://onlinelibrary.wiley.com/doi/full/10.1111/cgf.13957 对于通用的尝试Eigen 或cuSparse 在 GPU 上。对于特定用例,还有很多其他的表现更好,但这部分问题并没有明确的答案。

除了矩阵格式本身之外,甚至矩阵中条目的顺序也会对性能产生巨大影响,这就是为什么经常使用 Cuthill-McKee 算法来减少矩阵带宽(从而提高缓存性能)的原因。

【讨论】:

我的 A 中 NZE 的数量在 10-50% 之间。 好的,您对这个问题的第二条评论听起来像是您拥有 50-90% 的 NZE。对于那些接近 10% 的人,您可能 从稀疏矩阵中受益,但对于那些接近 50% 的人,您肯定不会。两者都没有。性能或内存使用。 我的 A 中 NZE 的数量在 10-50% 之间。A 的大小比较大。 CPU case => 有了这个link 中大约50-90% 的稀疏性和CSR 乘积算法,你认为DMv 还会更好吗?你能指出不规则的内存访问吗?为什么矢量化很难? GPU 机箱 => 是的!会有不同长度的行 - 它会比 DMv 更糟吗?时间上能接近吗?我正在尝试重现这篇论文的结果link? d[Col[k]] 会导致内存访问不规则,这也是矢量化困难的部分原因。另一部分是变化的循环边界k = RowPtr[i]; k < RowPtr[i+1]。特别是在 GPU 上,我怀疑你会从 SpMV 中看到任何好处,但如果有疑问:测量。 谢谢,乔 - 我该如何测量?他们推荐使用 C++ 进行测量的方法吗?

以上是关于稀疏矩阵与密集矩阵乘法 C++ Tensorflow的主要内容,如果未能解决你的问题,请参考以下文章

Numpy/Scipy 稀疏与密集乘法

如何在TensorFlow中执行稀疏矩阵*稀疏矩阵乘法?

向量矩阵乘法、浮点向量、二进制矩阵

使用密集和稀疏矩阵

将密集向量与 Tensorflow 中稀疏矩阵的每一行相乘

将稀疏 scipy 矩阵加载到现有的 numpy 密集矩阵中