Memory Resources as Limit to Parallelism
Final Throughts
GPU 프로그래밍에서 중요한 게 바로 어떻게 maximalize parallazible hardware(fp computation unit 같은 것들) in gpu
Occupancy
- active or runnable number of warp / maximum active or runnable warp each sm
== runnable,active thread on sm /max active thread assign to sm
- cuda program을 쓰게 되면 thread structure을 결정해야할 것임
- multiple block은 sm에 할당할 수 있지만 sm은 limited resource가 있기에 얼마나 block, thread 등등이 sm이 limited factor가 될 거임
- occupancy를 막는 register, shared memory, block size가 limited factor가 될 거임
- 각각의 리소스 관점에서 occupancy를 계산한 후에 가장 min값이 실제 occupancy가 될 것
1) Occupancy Limiters: Registers
- 저 컴파일 코드로 한다면 레지스터를 얼마나 쓰는지를 보여줄 거임
ex GPU) Fermi가 gpu 예시임. 얘는 옛날 꺼여서 좀 더 레지스터가 많을 거 같긴 함
- Fermi는 32000개의 레지스터가 sm에 있다는 소리임
- Fermi는 1536의 쓰레드를 각 sm에 있음
ex1)
- 커널은 20개의 레지스터를 쓰레드마다 쓰고 각 쓰레드는 1개의 implicit register를 쓰므로 총 21개의 레지스터를 씀
- 레지스터 측면에서 32k를 21개로 나누면 최대 1560개의 쓰레드를 동시에 돌릴 수 있는데 fermi가 제공하는 것은 1536개이기에 얘는 occupancy가 1인 것
ex2)
- 두번째는 63개의 레지스터를 사용하므로 32k/64이므로 총 512개의 쓰레드를 최대로 쓸 수 있는데 1536개는 하드웨어가 제공하는 거니까 그걸로 나누면 0.33 occupancy가 됨
Q. 질문
runnable은 기다리지만 상태를 기억하는 거고 기다리는 애이고 동시에 실행되는 게 4개
occcupancy가 1이라고 한다면 최대라고 했을 때 100퍼센트라는 거임… 매시간 최대한으로 쓸 수 있는 게 아니라 최대한으로 쓴다고 했을 때 33퍼센트라는 것… 그거보다 안될 수도 있고 그런 거임
- 그렇다고 해서 코드를 수정하지 않고 register 를 그냥 냅다 줄여버리면 local memory를 쓰게 되므로 fetch from dram이 많아질 수 있다
Occupancy Limiter: Shared memory
fermi는 shared memory로 16k or 48k 메모리를 가질 수 있다
ex1)
- 32바이트를 per thread로 해서 shared memory 최대 사이즈를 32바이트로 나누면 1536개의 쓰레드가 되는데 max랑 같으니까 occupancy가 1
- 가정: 48k가 정확히 shared memory * block size와 들어맞아서 되는 거임
쓰레드 하나다 shared memory로 해서 게산한거고 사실 쓰레드 하나가 아니라 shared memory블록 당 쓰는 거여서 쓰레드 블록 크기를 곱해서 쓰레드 블록이 최대 몇개가 들어왔는지 계산하면 다 못쓸 수도 있는 거지!!
만약에 1024가 블록의 사이즈라면 1k이므로 32k가 되는건데 16k는 못쓰게 되는 건데 위에서는 고려안하는 거임
ex2)
- 16k shared memory라고 한다면 위의 가정을 그대로 사용한다면 33%가 될 것
Q. shared memory 절삭되는 이유?
A. 사실은 블럭단위로 shared memory가 할당되니까 쓰레드가 아니라 블럭단위로 계산을 해야함 → sm 하나당 블럭 이만큼 쓰니까 쓰레드 블럭 최대 몇 개 할당할 수 있고 그걸로 maximum occupancy를 구해야하됨
쓰레드 블럭 사이즈가 1024이면 shared memory는 32k가 필요한데 스레드 블럭 할당 하나 하면 더 할당 못하게 되니까 그 경우에는 쓰레드 블럭 하나만 할당하니까 1024쓰레드만 쓰게 되니까 occupancy가 66%가 되는 거임!!
Q. ex2에서 1024개라고 하면 아예 돌릴 수 없는 코드일까요? A.맞아요~
3) Occupancy Limiters: Thread Block size
- 각 sm은 최대 8개의 thread block을 할당할 수 있다(이게 limited factor)
- 따라서 너무 작게 쓰레드 블럭을 할당한다면 8 block이니까 작게 됨
- size를 적어도 192개의 쓰레드로 블럭을 써야 쓰레드가 적당하게 될 것
- 128~1k사이의 값을 하는 게 좋대
cf. gpu hardware resource가 다르기 떄문에 계산하기 싫으면 엑셀보고 채우면 된대 호호