벡터로 가득한 책장을 그려봐
행렬은 벡터의 stack. 각 row (또는 column)을 자기 벡터로 슬라이스 가능, 근데 책장 전체는 contiguous 메모리 청크 하나에 들어가야 함. 어느 차원이 contiguous냐가 layout 선택.
GPU mantra: coalesce 아니면 죽음. Warp의 32 인접 thread가 32 contiguous 주소 read하면 하드웨어가 한 번 (또는 한 번 가까이)의 메모리 transaction에 처리. 그 패턴 깨면 bandwidth 폭락.
| Layout | 메모리 순서 | 적합한 경우 |
|---|---|---|
| Row-major | Row 원소 인접 (column 따라 stride 1) | Thread가 row 가로질러 stride |
| Column-major | Column 원소 인접 (row 따라 stride 1) | Thread가 column 따라 내려감 (Fortran/cuBLAS) |
RTX 4090, 4096×4096 FP32 row-sum reality check:
- Row-major + thread가 row 스캔 (coalesced): 610 GB/s
- Column-major + thread가 row 스캔 (strided): 105 GB/s
전적으로 access 패턴이 만든 6× 격차.
Leading dimension (ld)
'Leading dimension'은 연속 row (또는 column) 사이 stride. 빈틈없이 packed 행렬은 row-major면 ld == cols, column-major면 ld == rows. 근데 메모리 bank conflict 피하려고 padding 자주 — ld > cols. 모든 cuBLAS 호출이 lda, ldb, ldc 받는 이유 정확히 이거.