Host와 Device 메모리
CUDA에서 CPU 쪽은 host, GPU 쪽은 device라고 부른다.
host memory:
CPU가 접근하는 메모리
device memory:
GPU가 접근하는 메모리
왜 복사가 필요한가
CPU 배열 h_a는 CPU 메모리에 있다. GPU kernel은 이 배열을 직접 계산하지 않는다. 먼저 GPU 메모리에 배열을 만들고 데이터를 복사해야 한다.
float* d_a;
cudaMalloc(&d_a, bytes);
cudaMemcpy(d_a, h_a, bytes, cudaMemcpyHostToDevice);
kernel이 끝난 뒤 결과도 GPU 메모리에 남아 있다. CPU에서 확인하려면 다시 복사해야 한다.
cudaMemcpy(h_c, d_c, bytes, cudaMemcpyDeviceToHost);
cudaMemcpy 방향
cudaMemcpy는 네 번째 인자로 복사 방향을 받는다.
cudaMemcpy(dst, src, bytes, direction);
주요 방향은 다음과 같다.
cudaMemcpyHostToDevice // CPU -> GPU
cudaMemcpyDeviceToHost // GPU -> CPU
cudaMemcpyDeviceToDevice // GPU -> GPU
cudaMemcpyHostToHost // CPU -> CPU
dst가 먼저이고 src가 다음이다.
메모리 해제
GPU 메모리는 cudaFree로 해제한다.
cudaFree(d_a);
CPU에서 malloc으로 잡은 메모리는 free로 해제한다.
free(h_a);
포인터는 참고 카드로 분리한다
float*, &d_a, A[idx]는 C/C++ 포인터 문법이다. 이 path에서는 실행 흐름을 먼저 잡고, 포인터 자체는 별도 참고 카드에서 다룬다.
인터랙티브 설계
- 화면을 CPU 영역과 GPU 영역으로 나눈다.
cudaMalloc을 누르면 GPU 쪽에 빈 배열 박스가 생긴다.cudaMemcpyHostToDevice를 누르면 CPU 배열 값이 GPU 배열로 복사된다.- kernel 실행 후
d_c가 채워지고,cudaMemcpyDeviceToHost로h_c에 복사된다.
확인
h_a와d_a의 차이는 무엇인가?- kernel 실행 전에
h_a를d_a로 복사해야 하는 이유는 무엇인가? cudaMemcpy(h_c, d_c, ..., cudaMemcpyDeviceToHost)에서 destination은 어느 쪽인가?