Vendor BLAS를 peak 90%로 올리는 다섯 기둥
손코딩 tiled GEMM은 peak ~5%. cuBLAS는 80%+. 격차가 수십 년 누적된 엔지니어링 다섯 기둥 위에 세워져. 체크리스트로 읽어; 어느 기둥이든 깨지면 vendor 성능도 무너짐.
| 기둥 | 하는 일 | 관찰 위치 |
|---|---|---|
| Blocking / tiling | Hot 데이터를 shared / L2에 유지 — Track 6의 tiled GEMM이랑 같은 아이디어, 단 multi-level | Nsight 'shared mem reads', Xcode 'L2 hit ratio' |
| Micro-kernel (Tensor / matrix unit) | Instruction당 32–128 FLOP하는 fused 행렬곱 op (FMA당 아님) | SASS mma.* instruction, Apple Instruments matrix-unit counter |
| Split-K & Streaming-K | K 차원을 block 가로질러 병렬화, 그 다음 partial sum reduce | cublasLtMatmulAlgoGetHeuristic, MLX의 split-K path |
| Heuristic algo picker | 특정 shape용 tile size / epilogue / splitK 자동 검색 | Nsight 'Algorithm ID' 패널, cuBLASLt 로그 |
| Epilogue fusion | 커널의 final loop에 bias add + activation + residual add fold | cuBLASLt activationType, β·C 처리 |
표 한 번 읽어. 그 다음 주목: 손코딩 tiled GEMM은 첫 번째 기둥만 가짐. 5%인 이유. 나머지 기둥 각각이 독립적으로 ~2× 가치 — 곱하면 격차 이해돼.
Production에서 각 기둥 깨는 거
- 작은 m이나 k — micro-kernel이 기대 모양 못 채움; 라이브러리가 GEMV-grade 커널로 fallback.
- Hidden size가 16 배수 아님 — Tensor Core path는 이거 요구; off-multiple은 더 느린 fallback 강제.
- L2 thrashing — concurrent 커널이 tile evict; 명백한 이유 없이 성능 절반.
- Shared memory bank conflict — tile loader stall; profiler가 'shared bank conflict' 높게 보여줌.