Kim Seon Deok
[CUDA] ch2. CUDA Memory Management - Shared memory & Texture memory & Registers 본문
[CUDA] ch2. CUDA Memory Management - Shared memory & Texture memory & Registers
seondeok 2023. 12. 18. 05:20
Shared memory
shared memory는 CUDA memory hierarchy에서 User-Managed cache로써 역할을 수행한다.
user가 global memory에서 data를 coalesce한 방식으로 read/write하고, user가 control 할 수 있는 cache처럼 작동하는 memory를 제공한다.
- shared memory는 같은 block 내의 thread에게만 visible하다. -> 같은 block 내의 thread끼리만 memory access를 공유
- 같은 block 내 thread들은 result를 공유할 수 있기 때문에, redundant한 계산을 줄일 수 있다.
- shared memory와 CPU cache는 비슷하다. CPU cache는 explicit하게 관리되지 않는 반면 shared memory는 user에 의해 explict하게 manage될 수 있다.
- shared memory는 global memory보다 latency가 낮고 bandwidth가 높다.
shared memory의 내부 구성
Bank conflicts and its effect on shared memory
shared memory는 bandwidth를 높이기 위해 bank로 구성되어 있다.
- 각 bank는 cycle 당 1개의 address를 처리할 수 있다. -> shared memory는 bank 갯수만큼 simultaneous하게 access가 가능하다
- Volta 아키텍쳐의 경우, shared memory에 4byte-wide의 32개의 bank가 들어있다.
하나의 배열이 shared memory에 저장될 때, 인접한 4-byte word는 bank에 연속적으로 저장된다.
- Bank conflict가 발생하지 않는 경우
- Bank conflict가 발생하는 경우
Texture cache
- read-only cache는 kernel 실행 중 변경되지 않는 read-only data를 저장하는 데 적합하다.
- 다른 cache로의 load를 줄여 성능을 향상시키는 역할을 한다.
- GPU에서 Read-only data는 grid 내 모든 thread에서 visible하다.
- CPU는 해당 data에 대해 read 및 write 권한이 모두 있다.
- const __restrict__ 로 read-only data를 표현
- __ldg 로 texture cache를 통한 로딩을 수행
Read-only data는 주로 warp가 동일한 address/data를 read하도록 요구될 때 사용된다.
이를 통해 각 clock period 당 모든 thread에 대해 data request가 이루어진다.
또한 texture cache는 같은 warp 내 thread들이 2D 및 3D locality를 가진 texture address에서 data를 read할 때 성능이 향상되는 경향이 있기 때문에 image scailing과 같은 image process algorithm에 유용하다.
Register
GPU는 CPU에 비해 충분한 갯수의 register를 갖고 있다. 그렇기 때문에 register에 data의 대부분을 저장할 수 있고 context switching을 통해서 latency를 줄일 수 있다. 따라서 register를 optimal하게 만드는 것이 중요하다.
하나의 SM에는 고정된 register set이 있다.
register spill
CUDA compiler는 각 thread 당 최적의 register 갯수를 찾는다.
local variable이나 intermediate value가 많아서 register 갯수가 부족해지는 경우 data는 local memory(L1/L2 cache 혹은 lower level memory)로 이동한다. 따라서 불필요한 local variable을 많이 선언하지 않는 것이 권장된다.
- register는 per-thead로 single thread의 scope를 갖고 있다.
- grid에서 실행되는 모든 thread에 대해 변수의 private copy가 생성되고, copy에 대해 thread가 액세스하게 된다. 단 다른 thread의 private한 variable에는 액세스할 수 없다.
- kernel의 일부로 선언된 local variable과 intermediate value를 저장한다.
'CUDA Programming' 카테고리의 다른 글
[CUDA] ch3. CUDA Thread Programming (0) | 2024.01.16 |
---|---|
[CUDA] ch2. CUDA Memory Management - Global memory (2) | 2023.12.18 |
[CUDA] ch1. Introduction to CUDA Programming (0) | 2023.12.11 |