본문 바로가기

School Study/Multi Core Programming

CUDA Memory Model

CUDA Memory Hierarchy

  • Per-Thread (local Memory)
    • Registers
      • 가장 빠르고, 가장 작은 메모리
      • 보통 블록 1개가 8k-64k 32bit register를 사용한다.
      • 각 SM 내부에 존재
      • thread들이 register를 나누어서 가져간다.(register의 영역을 나누어서 사용)
        따라서 context switching이 필요 없다.
    • Local Memory
      • Off-chip memory
        • SM 내부에 없고, DRAM 영역 내부에 존재
        • register에 다 올라가지 못하는 것들은 Local Memory에 올려서 동작
        • Register에 비해 느리지만 더 많은 공간을 활용할 수 있다.(크게 제약이 없다.)
  • Per-Block (shared Memory)
    • Shared Memory(__shared__)
      • On-chip memory
        • SM 내부에 존재해 빠르지만 공간이 적다.
        • 블록 안의 모든 thread들이 공유한다.(모든 thread가 접근이 가능하다.)
          • thread 간의 communication가능
        • SM 내부의 block들이 shared memory 공간을 나누어서 활용(block 개수 제한)
  • Per-Gird (global Memory)
    • Global Memory
      • 모든 thread가 활용할 수 있다.
      • off-chip memory
        • 가장 느리지만 가장 큰 공간을 가진다.
      • Host에서 접근이 가능하다.
    • Constant Memory
      • 읽기 전용 메모리 : 읽을 수만 있다.
        • 선언은 global로 하고 host를 통해 초기화 한다.
      • 공간이 적지만 빠르다.
        • 이 영역을 위한 캐시가 존재한다.(캐시 영역 지원)
          • 기본적으로 DRAM에 저장되어 있지만 할당되어 있는 cache가 존재해서 자주 읽어오는 값들을 저장해놓으면 빠르게 가져가 활용할 수 있다.(인자 값과 같은 것들..)
    • Texture Memory
      • Constant memory와 비슷
      • 2차원 array를 다루는 것에 최적화
      • Hardware 필터링 제공
      • 기본적으로 graphic에 활용되므로 cuda에서 많이 사용하지는 않는다.

 

GPU Caches (Hardware Manage)

  • L1 cache
    • SM마다 존재한다. 
    • Shared memory와 같은 공간에 존재
      • 따라서 L1 cache를 더 사용할 수도 사용하지 않을 수도 있다.
      • Shared memory 공간으로 활용하기도 한다.
  • L2 cache
    • SM 내부에 있는 것이 아니라 바깥쪽에 존재하는 캐시
    • Shared by all SM
  • Read-only constant and texture caches

 

Physical Location of CUDA Memories

  • On-chip memory(In each SM)
    • Registers
    • Shared Memory
    • Constant cache, Texture cache
  • Off-chip memory
    • Local memory
    • Global memory
    • Constant memory and Texture memory
    • L2 cache

GPU Memory Hierarchy

 

그렇다면 각각 Memory Model이 성능에 어떤 영향을 미치는지 알아보자.

일단 각각 Memory Model을 잘 이해하고 적당한 공간에 가져다가 사용해야 한다.
(Design your kernel and block)

무작정 많은 스레드를 사용한다고 성능이 좋아지는 것은 아니다.
결론적으로 Activie WrapActivie Block이 많아야 성능이 좋아질 수 있다.

Activie Wrap

  • 일부 thread가 요구하는 register 공간 할당받지 못할 수 있다.
    • (#thread in a block) * (register per thread) > registers in a SM
  • Active warp
    • wrap 내부의 모든 스레드들이 요구하는 register 공간을 가져야 한다.
  • Activie warp을 늘리기 위해 적당한 register 공간을 배분해야 한다.

 

Activie Block

  • 하나의 블록에서 메모리 자원이 요구되는 것들을 모두 가지고 있는 것(?) 
    • Register - all warps in a block are active wrap
    • Shared memory space
  • SM 내의 Active blocks은 동시에 실행될 수 있다.
  • Activie Block을 늘리기 위해 적당한 Shared memory 공간을 배분해야 한다.

 

Occupancy(얼마나 가득 차 있는가)

= (# of active warp) / (# of maximum warps)
이론적으로 가능한 warp에 비해 active warp이 얼마나 존재하는가

많은 active block이 있을수록 높은 성능의 병렬 처리가 될 수 있는 확률이 높다.

kernal과 thread layout을 최대한 많은 active warp을 낼 수 있도록 설계해야 한다.

  • thread당 register의 수
  • block당 thread의 수
  • block당 shared memory 크기

CUDA C/C++의 Device에 가보면 Max Used Register를 통해 사용되는 Register의 수를 제한할 수 있다.

Set the # of Register Per Thread

 

Occupancy Calculator

설계된 kernel과 thread layout에 따른 occupancy를 계산해준다. (참고만 하도록 하자.)

Occupancy Calculator

 

C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\tools
경로에 들어가 보면 엑셀 파일로 calculator가 존재한다.

 

 

'School Study > Multi Core Programming' 카테고리의 다른 글

CUDA Stream & Concurrent Execution  (0) 2019.05.21
Synchronization in CUDA  (0) 2019.05.21
Maximizing Memory Throughput  (0) 2019.05.14
CUDA Execution Model  (0) 2019.05.07
CUDA Thread  (0) 2019.04.23