Host와 Device 메모리

cudamemoryhostdevice

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가 채워지고, cudaMemcpyDeviceToHosth_c에 복사된다.

확인

  • h_ad_a의 차이는 무엇인가?
  • kernel 실행 전에 h_ad_a로 복사해야 하는 이유는 무엇인가?
  • cudaMemcpy(h_c, d_c, ..., cudaMemcpyDeviceToHost)에서 destination은 어느 쪽인가?