我使用cusparse和cublas来计算稀疏密集乘法:C = A'* B.
A是M * N稀疏矩阵
B是M * S密集矩阵
M = 9,633,792,N = 617,004,nnz为28,901,376,S = 3
我尝试了不同的方法来加快速度,
A以CSR格式存储,使用cusparseScsrmm计算A'* B,需要180ms
A'= At以CSR格式存储,使用cusparseScsrmm2计算At *(B')',转置B以改善矩阵B的内存访问,并根据文档,如果op(B) )= B ^ T,只支持op(A)= A,所以我预先以CSR形式存储At,转换B需要8ms,而计算At *(B')'需要4ms,共12ms。
A'= At以CSR格式存储,使用cusparseScsrmm计算A'* B,需要8 ms。
A在迭代中是常数,因此不能考虑在A上操作的时间,但应考虑在B上操作的时间。更具体地说,A是二进制矩阵,它每行有3个非零值。
所以我在徘徊是否有任何方法可以加快速度? 4ms是可以接受的。例如,改善矩阵B的存储器访问但不耗费时间。我也考虑过使用常量内存来存储A,但是cuda似乎只有64K常量内存,或者使用纹理内存来存储B,但是它是只读内存,可能不适合。
/ ****补充*** /
我使用的GPU是GTX TITAN X,我使用<meta name=viewport content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
来转置矩阵B
答案 0 :(得分:1)
我不知道您使用的是哪种设备。但与高端GPU上的B单个D2D副本相比,矩阵转置速度相当慢。
cublas_geam()
如果使用import qualified Data.Vector.Unboxed as V
lcgen s =
lc
where
lc 0 b = lengths V.! b
lc a b = lengths V.! b - lengths V.! (a - 1) - 1
lengths = V.fromList $ scanl1 ((+) . (1 +)) $ map length $ words s
来转置矩阵B,则可能意味着矩阵太薄,并且对于这种情况,例程没有很好地优化。您可以实现自己的转置内核并针对3-col矩阵进行优化。通用矩阵转置仅适用于32或大于32的倍数。但它的代码是实现自己的代码的良好开端。
https://devblogs.nvidia.com/parallelforall/efficient-matrix-transpose-cuda-cc/