레퍼런스 / 검증 제거, 벤치용으로 생성,
개별 커널 분석을 일반적인 workload 에서 하기 위해선 네 가지 섹션을 제대로 읽을 줄 알아야 한다.
Launch Statistics
- Block Size ( Threds / Block )
- Registers Per Thread
- Static Shared Memory / Dynamic Shared Memory
- Blocks per SM
여기서 확인할 것
- 레지스터 / SMEM 때문에 occupancy 가 낮은지
- block 크기가 너무 작아서 SM 에 block 이 너무 많이 뜨는지, 혹은 너무 커서 병렬성이 줄었는지
Summary / Speed Of Light ( SOL )
- SM % (SM Utilization)
- Memory Throughput vs Theoretical Peak
- SOL : Compute vs Memory Bound
감으로?
- SM % 낮고 메모리가 터지는 느낌이면 메모리 바운드
- 메모리 대역은 한가한데 SM% / issue rate 가 낮으면 컴퓨트 / 파이프라인 / occupanccy 문제
Warp State / Scheduler Stats
- Warp Stall Reasons
- Stall Long Scoreboard ( 메모리 로드 대기 )
- Stall Short Scoreboard
- Stall Barrier
- Stall Not Selected
- Stall Math Pipe Throttle
- Eligible Warps per Cycle
여기서
- Long Scoreboard 비율이 매우 크면 : 글로벌 메모리 / SMEM latency hiding 실패 - 더 많은 warps or 더 깊은 pipeline 필요
- Not Seleted / No Instruction 비율이 크면, ILP 부족, 커널 구조 자체를 바꿔야할 수도있음
Memory Workload Analysis
- L1 / L2 Hit Rate
- DRAM Read / Write Throughput
- Global Load / Store Efficiency ( coalescing )
체크 포인트
- DRAM throughput 이 peek 대비 너무 낮으면, 메모리는 안 막혀있고 오히려 compute / occupancy 문제
- Global Load Efficiency 가 100% 멀면 : coalescing 아안 됨 - 행렬 leading dimension , 스레드 매핑 필요
1024, 1024 ncu-rep 내용 일단 먼저 익숙해지자.
443개의 ID... 드가자~

- Duration 기준 정렬
- 가장 오래 먹는 커널 확인
- 내 커널만 보기
- Function Name 에 gemm_bias_act_f32_tiled 여러 개가 보임
- 그 중 하나를 오른쪽 클릭해서 Filter to this value 메뉴, 각 런만 남음
- 대표 하나 골라서 분석
- Duration, Grid Size, Block Size 가 가장 전형적인 케이스 하나 선택
- 아래쪽 Details / Speed of Light / Memoy Workload 같은 섹션은 선택된하나의 커널 인스턴스에 대한 분석
- 대표 하나 잡고 그걸 기준으로...
현재 스크린샷 기준
Theoretical Occupancy ( 16.7 )
스케줄러당 theoretical warps 가 HW 최대 (12) 보다 훨씬 적음, 이 커널의 이론적 occupancy 16.7% 이고, 레지스터 수 + shared memory 가 한계 요인
Block Size : 16, 16, 1 = 256 threads / block = 8 warps / block
Registers : 168 / thread
Grid Size : 8, 8, 1
Ampere 기준으로
스케줄러당 최다 12 warps 까지 돌릴 수 있는데, 지금은 레지스터 / SMEM 때문에 스케줄러당 2 warps 정도만 올라간다. 2 / 12 ~= 16.7
한 번에 SM 위에 올려놓고 돌릴 수 있는 warp 수가 너무 적다. 많은 스레드가 돌아가는 구조가 아니라, 소수의 warp 만 크게불려서 일하는 구조
타일 크기 / 레지스터 사용량이 과함 쪽에 가깝다는 신호
Tail Effect
1 개의 full wave 와 6 개의 block 으로 이루어진 partial wave 를 가진다. 이 partial wave 가 전체 런타임의 최대 50 까지 차지할 수 있다.
wave = 한 번에 SM 전체에 올라갈 수 있는 block 묶음
Grid Size = 8 8 64 blocks
GPU SM 수 * SM 당 가능한 blocks 를 wave size 라고 할 때, 64 가 그 wave size로 나누어 떨어지지 않으니, 마지막 wave 에서 일부 SM 은 일이 없어서 놀고, 일부만 마지막 block 을 처리하는 구간, tail 이 생김
" 블록 개수가 하드웨어 관점에서 나누어 떨어지지 않아 생기는 빈틈 "
shared load bank conflicts
shared load 요청, 8000000 개 중 평균 2.5 - way bank conflict, 60% 정도가 conflict 겪음
- shared memory 는 여러 bank 로 나뉘어 있음
- 한 warp 이 한 사이클에 각자 다른 bank 를 때리면 완전 병렬 처리
- 여러 thread 가 같은 bank 를 동시에 때리면 직렬화 발생, bank conflict
지금, 2.5 - way
- 한 번에 끝날 것을 2.5 번에 나눠서 처리하는 정도의 충돌이 나고 있음
- shared 에서 로드하는 타일 레이아웃이 row, col 인덱싱 + stride 때문인지 bank 에 겹쳐서 매핑되고 있음
'dev_AI_framework' 카테고리의 다른 글
| 실험적 test 코드 작성 - Thread / Block / Grid 인덱싱 감각 잡기 (0) | 2025.11.16 |
|---|---|
| GPU 관련 개념 꽉 잡기 (0) | 2025.11.16 |
| ncu 실제 분석 내용 ( 최적화 항목 확인 ) - 다음 단계 내용 포함 (0) | 2025.11.16 |
| CUDA 성능 분석 도구 다른거 사용하자, (NVTX - 성능 분석용 태깅 도구) 실제 커널최적화의 경우 Ncu ( Nsight Compute) (0) | 2025.11.15 |
| pyd(raw) - glue(gemm.py) - layer(Dense) - capture_safe 경로까지 전부 Numpy 레퍼런스와 일치 확인 ( float32 rounding 수준이라는 개념 습득! ) (0) | 2025.11.15 |