Chapter 4: Classic operator implementations — GEMM
From naive matrix multiply through Block-Warp-Thread tiling, vectorized loads, bank-conflict removal, and double buffering — a full playbook for CUDA GEMM optimization
About this chapter
GEMM (General Matrix Multiply) is the central operator in deep learning — linear layers, the QKV projections in Attention, and FFN compute are all GEMM under the hood. This chapter builds a high-performance GEMM from scratch so you see the bridge between hardware and the frameworks above it.
-
Background and problem setup covers where GEMM sits in deep learning, problem scale, compute and memory-access traits, and what we are optimizing for.
-
Performance analysis brings in arithmetic intensity, the Roofline model, and evaluation metrics, so every later step has a quantitative frame.
-
The naive baseline is the obvious triple-loop kernel. It exposes the memory-bound bottleneck from repeated global-memory access.
-
Thread-block tiling cuts the matrices into tiles loaded into shared memory, quantifies how much global traffic drops, and gets the first round of reuse.
-
Thread-level tiling keeps sub-block results in registers so each thread computes several outputs, raising compute density and reuse further.
-
Warp-level tiling organizes tile layout by warp, maps threads to hardware execution units, and cuts redundant work and sync cost inside a warp.
-
Vectorized access with
float4merges loads and stores, cuts memory-instruction count, and raises effective bandwidth use. -
Bank-conflict removal uses padding or address remapping so shared-memory bank conflicts go away and throughput returns toward peak.
-
Double buffering and pipelining keeps two buffers in shared memory so loads and compute overlap and hide global-memory latency.
-
Ampere async-copy pipelines use
cp.asyncto make global-to-shared copies asynchronous, build a multi-stage software pipeline, and squeeze more latency out. -
SASS-level tuning and register scheduling go into instruction-level work: register allocation, instruction scheduling, and bank conflicts, reading cuBLAS SASS to see where peak performance comes from.
-
Parameter selection and tuning wraps up how to choose tile size, thread layout, and block count, with tuning ideas for different matrix sizes and hardware.