CUDA 좌표계와 첫 커널

이 경로는 CUDA를 처음 시작할 때 필요한 좌표 감각을 만든다.

목표는 빠른 커널을 바로 쓰는 것이 아니라, GPU 위의 많은 thread가 각자 어떤 데이터 원소를 맡는지 자연스럽게 읽는 것이다. 먼저 CPU for loop와 GPU kernel의 차이를 비교하고, vectorAdd를 Colab에서 실행한다. 그다음 grid, block, thread 좌표계와 global index를 익히고, host/device memory 이동을 이해한다.

마지막에는 같은 indexing 패턴을 2D matrix와 3D tensor로 확장한다. 이 경로가 끝나면 다음 경로인 memory coalescing, CUDA event timing, naive GEMM, shared memory tiling으로 넘어갈 준비가 된다.

  1. CPU loop에서 GPU kernel로 — CPU는 하나의 loop가 원소를 순서대로 처리하고, GPU는 많은 thread가 같은 코드를 각자 다른 index로 실행한다.
  2. 첫 CUDA 실행: vectorAdd — Colab에서 첫 CUDA 파일을 컴파일하고, CPU 배열을 GPU로 옮긴 뒤 kernel로 elementwise add를 실행한다.
  3. Grid, Block, Thread 좌표계 — kernel launch에서 grid와 block 크기를 정하면 CUDA가 각 thread에 blockIdx와 threadIdx 좌표를 부여한다.
  4. Global Index와 Boundary Check — block 안의 local thread index와 block 위치를 합쳐 전체 배열의 global index를 만든다.
  5. Host와 Device 메모리 — CPU 메모리와 GPU 메모리는 분리되어 있고, cudaMemcpy로 명시적으로 데이터를 옮겨야 한다.
  6. 2D Matrix Add — 2D grid와 block을 사용해 각 thread가 matrix의 한 row, col 위치를 처리하게 한다.
  7. Flattening과 Stride — 2D matrix나 3D tensor도 메모리 안에서는 연속된 1D 배열로 저장되므로 좌표를 index로 바꿔야 한다.
  8. 3D Tensor Add — 2D indexing에 z축을 추가해 3D tensor 좌표를 1D memory index로 변환한다.
  9. Warp와 Block Shape — NVIDIA GPU는 thread를 32개 단위의 warp로 실행하므로 block 총 thread 수와 모양이 성능 감각의 출발점이 된다.