- 칩 내 장착된 메모리로, SRAM cache등을 지칭함
- x86 아키텍쳐의 on chip memory는 1MB 정도이며 데이터 I/O 속도가 빠르다.
- TSV 기반 메모리를 통해 GB 단위 대용량 메모리를 칩안에 장착했다.
- 칩 밖에 있는 메모리로 DRAM이라고 지칭함
- BUS를 통하기 때문에 on chip memory 비해 속도는 느림
- GB 단위 또는 TB 단위의 메모리 장착 가능
- GPU의 메모리를 고전적으로 Frame buffer memory라고함
- 초기 GPU는 디스플레이의 화면 출력을 위해서 그래픽을 만든 다음 프레임 버퍼에 저장 후 메모리를 전기 신호로 변환, 모니터 케이블에 전송하며 화면에 출력하는 역할
- GPU 병렬 프로그래밍에서는 모니터의 렌더링과 관련없이 Frame buffer 라고 함
- CUDA에서는 Global memory or Device memory 라고함
- 어플리케이션 혹은 하드웨어 드라이버가 사용할 메모리 공간을 할당하여 다른 어플리케이션 혹은 운영체가 사용하지 못하게 하는 메모리
- 최초 생성시 해당접근 막기 떄문에, 물리적으로 메모리가 연속적으로 저장되어 읽고 쓸때 속도가 빠름
- 메모리 관리를 OS가 관장하기 때문에, 사용하는 메모리는 가상공간으로 관리되고 불연속적인 메모리 공간을 사용할 수 있음
- 시스템에서 메모리 컨트롤러와 코어와의 관계에서 각각의 코어가 메모리 컨트롤러에 연결되어있는 경우, 옆 코어에 붙은 메모리에 접근하게 되는데, 이때 시간적이 딜레이가 발생할 수 있으며 이러한 구조를 NUMA라고 함
- Unified memory는 CPU와 GPU가 동일 메모리 포인터를 사용할 수 있음
- 응답속도를 의미, 메모리를 읽는 명령을 내린후 실제 메모리를 불러오는데 걸린 시간등의 지연시간을 의미
//be declared float in[N] and float out[N]
float* gpu_in;
float* gpu_out;
size_t memSize=N*sizeof(float);
cudaMalloc((void**)&)gpu_in,memSize);
cudaMalloc((void**)&)gpu_out,memSize);
cudaMemcpy(gpu_in,in,memSize,cudaMemcpyHostToDevice);
cudaMemcpy(out,gpu_out,memSize,cudaMemcpyDeviceToHost);
cudaFree(gpu_in);
cudaFree(gpu_out);
- 레지스터는 GPU kernel 안에서 선언되는 변수
- GPU chip 안에 상주하기 때문에 접근 속도가 매우 빠름
- 아키텍쳐마다 최대로 할당할 수 있는 개수가 정해져 있음 -> 현) 아키텍쳐에서는 block 당 1024개 thread를 할당 가능
- 각 thread 마다 고유한 local memory에 register 변수를 할당하여 사용 -> register가 부족하면 자동으로 local변수로 할당
__global__ void reverse_kernel(float* in, float* out, int size){
int block_idx=blockidx.x;
int thread_idx=threadidx.x;
int block_dm=blockDim.x;
int grid_dm=gridDim.x*blockDim.x;
int dN=size;
int idx=block_idx*block_dm+thread_idx;
if(idx<dN){
out[idx]=in[dN-1-idx];
}
else{
return;
}
return;
}
- Global memory는 용량을 access하는데 시간이 많이 소요됌
- 최대 500 cycle의 접근 latency를 가질 수 있음
- 병렬 계산 수행시 병목을 일으킴
- GPU는 cache를 사용함
- block 안의 thread는 shared memory를 모두 공유함
- block이 다르면 각각의 block당 자기 자신의 shared memory를 가지게 됌
- 여러개의 block을 활성하는 경우에는 하나의 block당 4KB 정도밖에 사용하지 못할 수 있음
__shared__ float mem_A[4];
if(idx<dN){
mem_A[thread_idx]=in[block_idx*block_dm+thread_idx];
__syncthreads();
out[(gridDim.x-1-block_idx)*block_dm+thread_idx]=mem_A[block_dm-1-thread_idx];
}
- CPU의 메모리를 CPU Global memory에 전송할려면 PCI-e 인터페이스를 통해 전송
- CPU 메모리를 OS가 자동으로 관리하도록 배열 선언이나 malloc 함수를 사용하는 대신, cudaHostAlloc함수를 사용
- GPU로 통신하기 위해서 CPU 메모리 공간이 강제할당되어 데이터 통신시 속도 향상 이점을 가짐
- Memory pinning 기법은 NUMA 아키텍처의 시스템에서 CPU 소켓과 메모리 채널을 바인딩하는데 사용
CPU와 GPU가 동일 메모리 포인터를 사용할 수 있는 메모리 공간
__global__ void APlusB(int* ret, int a, int b{
ret[threadidx.x]=a+b+threadidx.x;
}
int main(){
int* ret;
cudaMallocManaged(&ret,1000*sizeof(int));
APlusB<<<1,1000>>>(ret,10,100);
cudaDeviceSynchronize();
for(int i=0; i<1000; ++i){
printf("%d:A+B=%d\n",i,ret[i]);
}
cudaFree(ret);
return 0;
}