CUDA - 7장. 실전 예제 및 프로젝트

2025. 3. 29. 22:47Framework/CUDA

 

🧪 7장. 실전 예제 및 프로젝트

🎯 학습 목표

이 장에서는 CUDA의 핵심 기능과 최적화 기법을 실제 문제 해결에 적용합니다.
직접 코드를 작성하고 성능을 비교하며, CPU 병렬 기술(OpenMP)과의 차이도 실습합니다.


✅ 전체 구성 요약

항목 핵심 내용 확장 과제
7.1 행렬 곱셈 구현 및 최적화 Tensor Core 적용, cuBLAS 비교
7.2 이미지 처리 (그레이스케일, 필터링) Sobel 필터, 텍스처 메모리 활용
7.3 딥러닝 연동 PyTorch 커널 확장, cuDNN 수동 호출
7.4 CUDA vs OpenMP 성능 비교 스레드 조정, SIMD 병렬화 추가 실험

📘 7.1 행렬 곱셈 구현 및 최적화

🎯 목표

  • CUDA로 기본 행렬 곱셈을 구현
  • 공유 메모리, Coalescing 등을 적용하여 속도 향상

🖼️ 구조 다이어그램

행렬 A (NxK) × 행렬 B (KxM) → 결과 행렬 C (NxM)
각 C[row][col] = A[row][k]*B[k][col]의 합
각 스레드가 C의 한 요소를 계산

✅ 기본 커널 코드

__global__ void matMul(float* C, float* A, float* B, int N) {
    int row = blockIdx.y * blockDim.y + threadIdx.y;
    int col = blockIdx.x * blockDim.x + threadIdx.x;
    float sum = 0.0f;
    for (int k = 0; k < N; ++k)
        sum += A[row * N + k] * B[k * N + col];
    C[row * N + col] = sum;
}

🧩 도전 과제

  • FP16 자료형으로 Tensor Core 적용
  • cuBLAS 사용 시 성능 비교
  • 행렬 크기 확장 (2048×2048 이상)

📘 7.2 이미지 프로세싱 예제

🎯 목표

CUDA를 사용하여 이미지의 RGB → 그레이스케일 변환 및 필터링 적용


🖼️ RGB to Gray 변환 원리

[ R G B ] → Gray
[255 128 64] → 0.299*R + 0.587*G + 0.114*B = 142

✅ 커널 예시

__global__ void rgb2gray(unsigned char* gray, unsigned char* rgb, int width, int height) {
    int x = blockIdx.x * blockDim.x + threadIdx.x;
    int y = blockIdx.y * blockDim.y + threadIdx.y;
    int idx = (y * width + x) * 3;
    if (x < width && y < height) {
        unsigned char r = rgb[idx];
        unsigned char g = rgb[idx + 1];
        unsigned char b = rgb[idx + 2];
        gray[y * width + x] = 0.299f*r + 0.587f*g + 0.114f*b;
    }
}

🛠 활용 기술

  • 2D 스레드 및 블록 인덱싱
  • 텍스처 메모리 (cudaTextureObject_t)
  • 스트리밍 처리 (영상 처리)

🧩 도전 과제

  • 가우시안 블러 필터 구현
  • Sobel 엣지 검출 적용
  • 텍스처 메모리 활용 최적화

📘 7.3 딥러닝과 CUDA

🎯 목표

PyTorch 및 TensorFlow에서 CUDA 활용 확인 및 사용자 정의 커널 연동


✅ PyTorch GPU 활용 확인

import torch
print(torch.cuda.is_available())
print(torch.cuda.get_device_name(0))

✅ 사용자 커널 연동 예 (PyTorch)

__global__ void square(float* x, int N) {
    int i = threadIdx.x + blockIdx.x * blockDim.x;
    if (i < N) x[i] = x[i] * x[i];
}

Python에서 torch.utils.cpp_extension.load()로 연동


🧩 도전 과제

  • PyTorch에서 사용자 정의 커널 사용해보기
  • cuDNN API로 Convolution 수동 구현
  • autograd와 연동되는 CUDA 연산 작성

📘 7.4 CUDA와 OpenMP 비교

🎯 목표

동일 연산을 CUDA와 OpenMP로 구현하고 성능 차이 비교


🖼️ 개념 도식

OpenMP       vs      CUDA
8~32 Thread        1000~10000 Thread
→ CPU 스레딩       → GPU 병렬 실행

✅ 벡터 덧셈 코드 비교

OpenMP (CPU)

#pragma omp parallel for
for (int i = 0; i < N; i++)
    C[i] = A[i] + B[i];

CUDA (GPU)

__global__ void vecAdd(float* A, float* B, float* C, int N) {
    int i = blockIdx.x * blockDim.x + threadIdx.x;
    if (i < N) C[i] = A[i] + B[i];
}

🧩 도전 과제

  • 스레드 수별 성능 변화 측정
  • OpenMP + SIMD 비교
  • CUDA fallback 구현 (GPU 미탑재 시 CPU 전환)

✅ 전체 요약 정리

예제 적용 개념 도전 과제
행렬 곱셈 2D 인덱싱, Shared Memory cuBLAS, FP16
이미지 처리 2D 필터링, 텍스처 활용 Sobel, 스트리밍
딥러닝 PyTorch, Tensor Core 커널 연동, cuDNN
OpenMP 비교 CPU vs GPU 구조 SIMD, 스레드 튜닝