The three-tier tile pyramid — same shape, two ecosystems
State-of-the-art GEMM on both CUDA and Metal converges on the same three-tier tiling structure. Outer tile fits in shared / threadgroup memory. Middle tile fits in registers. Inner tile is the matrix unit's native shape. The differences are spelling and exact dimensions, not concept.
CUDA (Ada Lovelace / Hopper)
┌── 128×128 thread-block tile (CTA) ───┐
│ ┌─ 64×64 warp tile ─┐ │
│ │ 16×8×16 tensor-core │ · │ ← registers + tensor cores
│ │ 16×8×16 tensor-core │ · │
│ └────────────────────┘ · │
└──────────────────────────────────────┘ ← shared memory (double-buffered)Metal (Apple M-series)
┌── 128×128 threadgroup tile ───┐
│ ┌─ 64×64 SIMD-group tile ─┐ │
│ │ 8×8 matrix unit (FP16) │··│ ← registers + matrix coprocessor
│ └─────────────────────────┘··│
└────────────────────────────────┘ ← threadgroup memory (double-buffered)Three takeaways:
- Same pyramid, different micro-tile size. NVIDIA Tensor Cores work on 16×8×16 (m×n×k) FP16 tiles per instruction. Apple's matrix unit works on 8×8 FP16. Different vendor IP, identical role.
- Double-buffering at the smem layer is mandatory. While the warp computes on tile i, the next-tile load for i+1 happens in parallel. Without it, the matrix unit stalls.
- Tile sizes are auto-tuned per shape. 128×128 is typical, but for tall-skinny GEMMs (m=4, n=4096, k=4096 — single-token decode) the library may pick 32×64 with split-K instead.