UNIVERSAL SGEMM CUDA

December 26, 2023 · View on GitHub

仓库更新中,欢迎佬们提pr

Quick Run

GEMM_MODE=0
mkdir build
cd build
cmake ..
make
./sgemm 32 1605632 27 $GEMM_MODE

Naive

在CUDA编程模型中,计算被划分为三个层次:网格、块和线程。每个块最多包含1024个线程,并且它们可以访问相同的共享内存区域。首个内核采用了这些层次结构,其中每个线程负责计算矩阵C中的一个元素,通过启动多个块和线程进行异步执行。

详细介绍:朴素GEMM

Global Memory Coalescing

在深入全局内存合并之前,我们需要了解warp的概念。在执行过程中,一个块的线程被组成为warp,每个warp包含32个线程。一个warp被分配给一个warp调度器,即物理核心。

在Volta架构之前,所有warp的线程来自同一个指令流。然而,自Volta以来,不同分支的指令可能交错执行,因此依赖“warp同步”不再可靠。每个多处理器有四个warp调度器,基于线程ID进行分组。

为了实现全局内存合并,属于同一warp的线程进行的顺序内存访问可以被合并,这在优化GMEM内存访问中很关键。通过改变线程分配的方式,实现线程之间的连续内存访问,我们可以提高吞吐量。

详细介绍:全局内存合并

Shared Memory

在GPU中,共享内存(SMEM)是一块位于芯片上的小区域,有较低延迟和高带宽。A100 GPU内存层次结构中显示了其逻辑分区。在新的内核中,通过将A和B的一块加载到共享内存中,最大程度地利用了共享内存的性能优势。然而,尽管实现了更高的内存带宽,但由于低算术强度,整体性能仍不如cuBLAS。

详细介绍:共享内存缓存块

Blocktiling 1d

新的内核在保持与前一个相似的基础上,引入了一个新的内循环,用于计算每个线程的多个C条目。通过最大程度地利用共享内存。该内核的优化主要体现在减少了内存访问次数,提高了算术强度,尽管整体性能仍受限于内存。

详细介绍:Blocktiling 1d

Blocktiling 2d

第五个内核的核心思想是使每个线程能够计算一个8*8的C元素网格。在内核的第一阶段,所有线程共同填充SMEM缓存,每个线程负责加载多个元素。随后,每个线程计算其相关的SMEM条目相乘,并将结果累加到本地寄存器中。

详细介绍:Blocktiling 2d

Results

$GEMM_MODE=0/1/2/3/4/5
./sgemm 32 1605632 27 $GEMM_MODE
./sgemm 384 14161 1152 $GEMM_MODE
./sgemm 256 43264 1152 $GEMM_MODE
./sgemm 64 1605632 147 $GEMM_MODE
./sgemm 64 559104 147 $GEMM_MODE
./sgemm 256 50176 1024 $GEMM_MODE
MNKAlgorithmTime (us)
32160563227naive123707
384141611152naive179951
256432641152naive373887
641605632147naive702349
64559104147naive252176
256501761024naive439462
32160563227global_memory_coalescing8976.98
384141611152global_memory_coalescing35116.6
256432641152global_memory_coalescing65442
641605632147global_memory_coalescing79366
64559104147global_memory_coalescing28115.3
256501761024global_memory_coalescing63925.2
32160563227shared_memory13594.9
384141611152shared_memory42083.7
256432641152shared_memory85513.6
641605632147shared_memory114396
64559104147shared_memory40141.6
256501761024shared_memory88951.5
32160563227blocktiling_1d2858.95
384141611152blocktiling_1d4176.16
256432641152blocktiling_1d8272.45
641605632147blocktiling_1d10400.3
64559104147blocktiling_1d3626.16
256501761024blocktiling_1d8499.03
32160563227blocktiling_2d2983.98
384141611152blocktiling_2d2572.57
256432641152blocktiling_2d5207.49
641605632147blocktiling_2d8763.37
64559104147blocktiling_2d3188.26
256501761024blocktiling_2d5149.85

picture

参考资料

  1. https://github.com/wangzyon/NVIDIA_SGEMM_PRACTICE
  2. https://siboehm.com/articles/22/CUDA-MMM
  3. https://zhuanlan.zhihu.com/p/372973726