TL;DR
NVIDIA는 RGB 이미지를 grayscale로 변환하고 32×32 타일별 median을 계산하는 CUDA 예제를 여섯 단계로 최적화한다. Compute Sanitizer와 CCCL의 인덱싱·mdspan API로 shared memory의 범위를 벗어난 접근을 잡고, Nsight Systems와 NVTX로 median 커널이 병목임을 확인한다. 이후 CUB의 GPU 알고리즘, 메모리 풀 기반 컨테이너, pinned host memory, 이미지별 CUDA Stream과 비동기 복사를 차례로 적용해 세 이미지 처리 시간을 6.8초에서 23밀리초로 줄인다. 저수준 최적화 없이도 최종 실행 시간이 약 300배 단축된다.
빠른 이해
새로운 점
저수준 GPU 최적화 없이 CCCL·CUB의 안전한 API와 메모리·Stream 관리만 단계적으로 바꿔 6.8초의 이미지 파이프라인을 23밀리초로 줄인 실습형 접근이다.
핵심 메커니즘
CPU의 RGB 이미지 입력을 pinned host memory에서 이미지별 CUDA Stream으로 비동기 복사하고, CUB의 DeviceTransform으로 grayscale 변환한 뒤 각 32×32 타일을 BlockRadixSort로 정렬해 median을 산출한다. device memory pool은 GPU 버퍼를 재사용하고, 여러 Stream은 복사·커널 실행을 겹치며, 결과 median은 다시 CPU로 비동기 복사된다.
핵심 수치
- 초기 전체 처리 시간: 6.8초- 세 이미지 처리, Nsight Systems 측정
- 초기 median 계산 시간: 이미지당 약 2.1초- computeMedian 커널
- CUB 적용 후 median 계산: 773마이크로초- 기존 대비 2,717배 빠름
- CUB 적용 후 전체 처리: 635밀리초- 초기 대비 10배 빠름
- pinned memory 적용 후 전체 처리: 약 25밀리초- host-to-device 전송 10배 단축
- 최종 전체 처리: 약 23밀리초- 초기 6.8초 대비 약 300배 빠름
섹션별 상세
출발점: RGB 이미지 처리 파이프라인
Compute Sanitizer와 CCCL로 메모리 오류 차단
auto config = cuda::make_config(cuda::block_dims(...), cuda::grid_dims(...));
cuda::launch(stream, config, kernel_name, input)새로운 launch API로 커널의 블록·그리드 구성을 지정하고 특정 Stream에서 실행한다.
Nsight Systems로 실제 병목 측정
cub::DeviceTransform::Transform(
cuda::std::make_tuple(d_image_r, d_image_g, d_image_b),
d_image_gray,
IMAGE_SIZE,
[] __host__ __device__ (pixel_t r, pixel_t g, pixel_t b)
{ return static_cast<pixel_t>(0.299f * r + 0.587f * g + 0.114f * b); },
stream);CUB의 DeviceTransform으로 RGB 세 입력을 GPU에서 grayscale 출력으로 변환한다.
CUB로 GPU 알고리즘 교체
cuda::device_memory_pool_ref device_resource = cuda::device_default_memory_pool(cuda::device_ref{0});
cuda::device_buffer d_image_r = cuda::make_buffer(stream, device_resource, IMAGE_SIZE, cuda::no_init);GPU 메모리 풀을 백엔드로 사용하는 device_buffer를 생성해 반복적인 할당·해제 비용을 줄인다.
메모리 풀과 pinned memory 적용
이미지별 CUDA Stream으로 작업 중첩
cuda::copy_bytes(stream, h_images_r[i], d_image_r);
cub::DeviceTransform::Transform(..., stream.get());
cuda::launch(stream, ...);
cuda::copy_bytes(stream, d_median, h_medians[i]);
stream.sync();각 스레드의 Stream에서 CPU-GPU 복사와 GPU 연산을 비동기로 실행한 뒤 결과 접근 전에 동기화한다.
용어 해설
- CUDA C++ Core Libraries(CCCL)
- — NVIDIA가 제공하는 CUDA C++용 라이브러리 모음으로, GPU 알고리즘·메모리 컨테이너·Stream·인덱싱 API를 표준화된 형태로 제공한다. 원문에서는 CUB, cuda::device_buffer, cuda::host_buffer, cuda::launch 같은 기능을 통해 CUDA 코드의 안전성·성능·유지보수성을 높이는 기반으로 활용된다.
- Compute Sanitizer
- — CUDA 프로그램의 메모리 접근과 기능적 정확성을 검사하는 NVIDIA 도구다. 커널 실행 중 발생한 잘못된 shared memory 접근 위치와 스레드·블록 정보를 표시해, 일반적인 CUDA 오류 메시지만으로 찾기 어려운 인덱싱 버그를 추적하는 데 쓰인다.
- NVTX
- — CUDA 애플리케이션의 특정 코드 구간에 이름을 붙이는 주석·범위 표시 API다. Nsight Systems 타임라인에서 함수와 커널, 메모리 전송 구간을 구분해 병목이 어디에 있는지 확인할 수 있도록 한다.
- 페이지 고정 메모리(Pinned Memory)
- — CPU 메모리의 물리적 위치를 고정해 CUDA가 직접 전송할 수 있도록 만든 메모리다. 일반 pageable 메모리를 사용할 때 드라이버가 임시 pinned 배열을 거치는 추가 복사 단계를 줄여 host-to-device 전송 시간을 단축한다.
- CUDA Stream
- — GPU 커널 실행과 메모리 전송을 순서대로 배치하는 작업 큐다. 이미지나 OpenMP 스레드마다 별도 Stream을 할당하고 비동기 작업을 사용하면 서로 다른 입력의 커널과 전송이 겹쳐 GPU 유휴 시간을 줄일 수 있다.
기술
- CUDA
- CCCL
- Compute Sanitizer
- cuda::launch
- cuda::std::span
- cuda::std::mdspan
- cuda::shared_memory_mdspan
- NVIDIA Nsight Systems
- NVTX
- CUB
- cub::DeviceTransform::Transform
- cub::BlockRadixSort
- cuda::device_buffer
- cuda::device_memory_pool_ref
- cuda::host_buffer
- cuda::make_pinned_buffer
- cuda::stream
- cuda::copy_bytes
- OpenMP
- Google Colab
언급된 리소스
AI 요약 · 북마크 · 개인 피드 설정 — 무료
출처 · 인용 안내
인용 시 "요약 출처: AI Trends (aitrends.kr)"를 표기하고, 사실 확인은 원문 보기 기준으로 진행해 주세요. 자세한 기준은 운영 정책을 참고해 주세요.