본문 바로가기

dev_AI_framework

1024, 1024 gemm 벤치 코드 테스트

레퍼런스 / 검증 제거, 벤치용으로 생성,

 

개별 커널 분석을 일반적인 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... 드가자~

 

  1. Duration 기준 정렬
    • 가장 오래 먹는 커널 확인
  2. 내 커널만 보기
    • Function Name 에 gemm_bias_act_f32_tiled 여러 개가 보임
    • 그 중 하나를 오른쪽 클릭해서 Filter to this value 메뉴,  각 런만 남음
  3. 대표 하나 골라서 분석
    • 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 에 겹쳐서 매핑되고 있음