CUDA

CUDA(Compute Unified Device Architecture). 보통 쿠다라고 읽는다.

CUDA 는 NVIDIA 가 만든 병렬 컴퓨팅 플랫폼 및 API 모델이다. 쿠다 플랫폼은 GPU 의 가상 명령어셋을 사용할 수 있도록 만들어주는 소프트웨어 레이어이며, NVIDIA 가 만든 쿠다코어가 장착된 GPU 에서 GPGPU 용도로 사용이 가능하다. 2006년 11월, G80 아키텍쳐와 함께 처음 발표되었으며, 초기에는 C, C++ 만 지원했지만 10여년의 세월이 지난 지금은 포트란이나 C# 등 다양한 언어에서 사용이 가능하다. 현재 최신 버전은 6.0 이다.

CUDA 가 작동하는 GPU 는 현재 NVIDIA 제품들만 있으며, 새로운 아키텍쳐가 나올 때마다 CUDA 버전이 올라갔기 때문에 G80 등 오래된 제품의 경우 쿠다 버전이 낮아서 일부 쿠다 어플리케이션과 호환이 안될 수 있으나, 과거 쿠다 응용프로그램은 최신 아키텍쳐에서도 잘 작동한다. 또한, 쿠다가 대두되면서 GPGPU 전용인 Tesla 제품군이 나왔는데, Tesla 제품군은 ECC 메모리가 들어가서 오류발생확률을 낮춰주고 Geforce에서 쓰이는 같은 아키텍쳐 칩셋이라도 추가 명령어 몇개를 더 지원한다. 다만 차세대 아키텍쳐의 Geforce 에선 이전 세대의 CUDA 명령어를 전부 흡수하여 지원하는 경향이 있으므로 최신 Geforce 제품을 써도 이전세대의 Tesla 전용 명령어를 쓸 수 있다.

제품에 따른 쿠다 지원 버전은 이 링크를 참고하면 되며, 아래는 아키텍쳐 별로 대략적으로 정돈하였다.

  • G80 Tesla (GTX8800~GTX285) : 1.0~1.3
  • Fermi (GTX480~580) : 2.0~2.1
  • Kepler (GTX680~780) : 3.0~3.7
  • Maxwell (GTX980) : 5.0~5.3
  • Pascal (GP100) : 6.0~6.2

CUDA 는 NVIDIA 가 독자적으로 개발한 GPGPU 기술이며 NVIDIA 그래픽카드의 성능을 최대로 끌어낼 수 있다. 비슷한 GPGPU 기술로 OpenCL 및 DirectCompute 가 있지만 이들은 표준을 기준으로 만들어졌기 때문에 쿠다에 비해 추상화 수준이 낮아서 로우 레벨 API 의 하드웨어 특유의 고급 기능까지 사용하여 한계까지의 성능을 끌어내기 어렵다. 즉, 다른 기술은 D3D API 등을 경유하기 때문에 시간이 걸리지만 쿠다는 바로 하드웨어에 엑세스하여 컨트롤 할 수 있다.

이는 쿠다의 단점으로 이어지는데, AMD 나 인텔 등 다른 회사의 GPU 에선 작동하지 않는다. 또한, 그래픽 기능과의 연동을 전제로 만들어진 DirectCompute 에 비해 그래픽 출력 용도로 사용시 오버헤드가 커진다.

그래픽 카드의 GPU는 대량의 데이터에 한 가지 연산을 적용하는 경우가 많기 때문에 단순화된 연산 유닛(코어)을 천여 개씩 탑재하고 있다.[1] 따라서 SIMD(Single Instruction Multiple Data) 형태의 병렬화가 가능한 연산에 GPU를 활용해서 속도를 올리려는 시도는 예전부터 있어 왔다. 그러나 원래 그래픽을 처리하라고 설계된 그래픽스 파이프라인을 가지고 일반적인 병렬 연산을 수행하는 것은 매우 골치아픈 일이었다. 프로그래머가 일일히 GPU의 세부 사항을 다 신경써야 했기 때문이다.

CUDA 프로그램은 스트림 프로세싱[2]에 기반하며, 그 작성에는 C/C++ 언어에 동시에 실행할 쓰레드 개수 등을 선언하는데 사용되는 CUDA 전용 문법을 추가한 언어를 사용한다. CUDA 코드는 대략 GPU 안에서만 돌아가는 함수(커널이라고 부른다)를 호스트(CPU)에서 호출하는 형태로 되어 있다.

CUDA는 GPU의 메모리 모델을 추상화해서 좀 더 편하게 GPU을 이용할 수 있도록 했다. 하지만 여전히 CUDA로 최대한의 속도 증가를 얻으려면 GPU의 메모리 구조에 대해서 잘 알아야 한다. 윈도우 한정으로 CUDA 프로그래밍의 귀찮음을 덜어 주기 위해서 만들어진 BSGP라는 녀석이 존재한다. CUDA 위에 한 층의 추상화 레이어가 더 있다고 생각하면 된다.[3]

NVIDIA 이외의 그래픽카드에도 병렬 연산을 시키고 싶은 사람은 OpenCL을 사용하면 된다.[4] CUDA와 문법이나 메모리 모델은 비슷한데 코딩하기는 이쪽이 좀 더 더럽다. 추상화가 덜 된 느낌. 애플, 인텔, AMD, ARM등 에서는 NVIDIA를 견제하기 위해 이 녀석을 밀고 있다.

최근에 CUDA를 더 보완한 OpenACC라는 게 나왔다. 좀 더 추상화가 돼있어서 코딩하기 더 편하다고 한다. 마이크로소프트에서는 C++ AMP라는 걸 만들었는데 OpenACC의 DirectCompute 버전 정도라 볼 수 있다. 그래도 아직은 일반 프로그래머가 사전지식 없이 덤빌 만한 난이도는 아니다. 단지 전에 비해 진입장벽이 많이 낮아졌을 뿐.

R337드라이버 이후부터는 Geforce 제품군에서의 CUDA 기반 비디오 인코드/디코딩 라이브러리가 삭제되었다. NVENC[5]를 밀기 위해서라는데 Tesla나 Quadro 제품군은 정상적으로 사용이 가능하다! 이에 CUDA가속을 사용하는 코덱의 사용이 불가능해지거나, 미디어 편집 프로그램들에서의 호환성에 문제가 생겼다. 황사장 : 꼬우면 쿼드로 사시던가 이렇게 된 이상 AMD로 간다!
  1. 범용성을 목적으로 한 CPU를 4명정도 되는 수공업자 내지는 장인으로, 단순 반복작업에 최적화된 GPU의 코어구조를 수백 명의 막노동꾼으로 비유하면 이해하기 쉽다. 이들이 각자 모여서 삽질을 시작했다고 생각해보자. 당연히 장인 4명의 삽질보다는 막노동꾼 수백 명의 삽질한 양이 더 많다.
  2. 병렬처리 프로그래밍의 일종
  3. 사실 이 표현도 어폐가 있는 것이... BSGP는 CUDA의 서브셋이 아니다. CUDA의 기계어 명령번역을 사용한 별도 언어라고 보는것이 더 타당. 일례로 레이 트레이싱 류의 coherence가 낮은 작업에선 CUDA보다 성능향상이 보이지만, 반대로 메모리 참조 연속성이 강한 작업에선 CUDA보다 성능이 낮아진다.
  4. 그러나 나온 지 기간이 꽤 되었는데도 아직 불안정하다. 애초에 일개 프로젝트로 커버하려는 범위가 너무 넓다.
  5. 하드웨어 기반 가속을 지원하는 라이브러리이다