CUTLASS: Fast Linear Algebra in CUDA C++
https://developer.nvidia.com/blog/cutlass-linear-algebra-cuda/
Efficient Matrix Multiplication on GPUs
计算密集度 = (时间复杂度/空间复杂度) = O(N^3)/O(N^2)
= O(N)
// naive for (int i = 0; i < M; ++i) for (int j = 0; j < N; ++j) for (int k = 0; k < K; ++k) C[i][j] += A[i][k] * B[k][j];
对于A的每一行,都会读取一整个B矩阵. 能否达到O(N)的复用次数?B中的元素按照列来访问,那么每次重新读取B[0,0]时是重新进行访存的。而实际上,读取一次B[0,0]只进行了1次计算。
// opt 1 for (int k = 0; k < K; ++k) // K dimension now outer-most loop for (int i = 0; i < M; ++i) for (int j = 0; j < N; ++j) C[i][j] += A[i][k] * B[k][j];
对于A[0,0],只读取一次,但执行j=0~N-1
,共N次计算。
对于B[0,0],读取i=0~M-1
,j=0, 共M次,执行这M次计算,并且这里可能会cache住,所以实际读取次数可能小于M。
对于C[0,0],读取k=0~K-1
,共K次。执行K次(k=0~K-1, i=0,j=0)
计算。
理论上已经比naive更接近于计算密集度O(N)
但这个计算依赖于每一次写入C中的元素时,这个元素的读取,写入速度能和乘法指令一样快,也就是说这些C中的元素最好能一直在cache中,而不发生trash。否则,这个计算过程就会使依赖于访存。
// opt 2 for (int m = 0; m < M; m += Mtile) // iterate over M dimension for (int n = 0; n < N; n += Ntile) // iterate over N dimension for (int k = 0; k < K; ++k) for (int i = 0; i < Mtile; ++i) // compute one tile for (int j = 0; j < Ntile; ++j) { int row = m + i; int col = n + j; C[row][col] += A[row][k] * B[k][col]; }
这样,在tile够小的时候,tile中元素就能放到cache中。
本文来自博客园,作者:ijpq,转载请注明原文链接:https://www.cnblogs.com/ijpq/p/18096507
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!