본문 바로가기

GPU-KERNEL

occupancy_reg_pressure_test_v3 - 실제 register pressure 에 따른 occupancy 감소 확인,

1. low / high 커널 리소스 비교

low 커널

=== kernel_low_regs ===
  numRegs          : 9
  sharedSizeBytes  : 0 (static)
  localSizeBytes   : 0
  maxThreadsPerBlk : 1024
  SM max threads     : 1536
  block_size         : 256
  maxActiveBlocks/SM : 6
  activeWarps/SM     : 48 (max 48)
  occupancy (approx) : 1.00
  • 스레드당 레지스터 : 9개
  • block_size = 256 -> warpPerBlock = 256 / 32 = 8
  • SM 당 최대 스레드 : 1536 -> max warps/SM = 1536 / 32 = 48
  • maxActiveBlocks / SM = 6
    • 6 block * 256 threads = 1536 threads ( 스레드 한계 )
  • activeWarps = 6 * 8 = 48 (max 48)
    • 풀 occupancy ( 1.0 )

레지스터 측면에서 보면

  • block 하나가 쓰는 레지스터 ~ = 9 * 256 = 2304
  • SM 이 65536 regs 라 치면 -> 65536 / 2304 ~= 28 블록까지도가능
    • 실제로는 레지스터가 아니라 스레드 제한 때문에 6 블록에서 잘린 상태

즉, low 커널은레지스터가 아무 제약도 안 주고 있다.

 

high 커널  

=== kernel_high_regs ===
  numRegs          : 128
  sharedSizeBytes  : 0 (static)
  localSizeBytes   : 0
  maxThreadsPerBlk : 512
  SM max threads     : 1536
  block_size         : 256
  maxActiveBlocks/SM : 2
  activeWarps/SM     : 16 (max 48)
  occupancy (approx) : 0.33
  • numRegs = 128
    • 스레드당 레지스터 128 개까지 올라감.
  • maxThreadsPerBlk : 512
    • 원래 low 커널은 1024
    • 컴파일러/런타임이이 커널은 레지스터를 너무 많이 먹으니깐 block 에 512 스레드 이상 쓰지 마라하고 상한을 내려버린 것
    • block_size = 256 으로 런치 -> 정상 실행
  • 레지스터 계산 감
    • block 당 레지스터 사용량 ~= 128 * 256 = 32768
    • SM 전체 레지스터 ~= 65536 이라 치면
      • 딱 2 블록/SM 까지만 올릴 수 있음
  • 워프 / occupancy
    • block 당 warp = 256 / 32 = 8
    • active warps = 2 * 8 = 16
    • max warps / SM = 48
    • occupancy = 16 / 48 ~= 0.33

즉, high 커널은 레지스터가 너무 많아서 SM 당 2 블록밖에 못 올라가고, warp 도 16 개만 떠 있는 상태 

occupancy 가 레지스터 때문에 깎인 케이스가 나온 것

 

low 는 스레드 제한에서, high 는 레지스터 제한에서 잘린 케이스

 

같은 연산 구조에서 스레드당 레지스터를 늘리면 

SM 당 활성 블록이 감소, 실행 시간도 느려짐