CUDA

 


'''CUDA'''
최신 버전
11.2.0
2020년 12월 업데이트
웹사이트
홈페이지
1. 개요
2. 유사 개념


1. 개요


'''C'''ompute '''U'''nified '''D'''evice '''A'''rchitecture
NVIDIA가 만든 병렬 컴퓨팅 플랫폼 및 API 모델로, 보통 '쿠다'라고 발음한다. CUDA 플랫폼은 GPU 의 가상 명령어셋을 사용할 수 있도록 만들어주는 소프트웨어 레이어이며, NVIDIA가 만든 CUDA 코어가 장착된 GPU에서 작동한다.
2006년 11월에 G80 마이크로아키텍처와 함께 처음 발표된 후, 2007년 6월 23일에 CUDA SDK가 처음 배포되었다. 초기에는 C, C++만 지원했지만 10여 년이 지난 지금은 포트란이나 C# 등 다양한 언어에서 사용이 가능하다. 버전 정보는 이곳에서 확인할 수 있다.
새로운 마이크로아키텍처 혹은 새로운 GPU가 나올 때마다 CUDA Compute Capability가 올라갔기 때문에 오래된 GPU의 경우 CUDA Compute Capability가 낮아서 일부 CUDA 기반 응용프로그램과 호환이 안될 수 있으나, 과거에 개발된 CUDA 기반 응용프로그램은 최신 GPU에서도 잘 작동한다. 또한, CUDA가 대두되면서 2007년에 GPGPU 전용인 TESLA[1] 제품군 이 나왔는데, TESLA 제품군은 ECC 메모리가 들어가서 오류 발생 확률을 낮춰주고 GeForce에서 쓰이는 같은 아키텍처 칩셋이라도 추가 명령어 몇 개를 더 지원한다. 다만 차세대 아키텍처의 GeForce에선 이전 세대의 CUDA 명령어를 전부 흡수하여 지원하는 경향이 있으므로 최신 GeForce 제품을 써도 이전 세대의 Tesla 전용 명령어를 쓸 수 있다.
GPU에 따른 CUDA Compute Capability는 이 링크를 참고하면 되며, 아래는 아키텍처 또는 GPU별로 대략적으로 정돈하였다. CUDA SDK 버전과는 다르므로 구분할 때 주의할 것.
  • G80 : 1.0
  • G84, G86, G92, G94, G96, G98 : 1.1
  • GT215, GT216, GT218 : 1.2
  • GT200 : 1.3
  • Fermi : 2.0~2.1
  • Kepler 1.0 : 3.0~3.7
  • Kepler 2.0 : 3.5~3.7
  • Maxwell 1.0 : 5.0~5.3
  • Maxwell 2.0 : 5.2~5.3
  • Pascal : 6.0~6.2
  • Volta : 7.0
  • Turing : 7.5
CUDA와 비슷한 GPGPU 기술로 OpenCLDirectCompute가 있지만 이들은 표준을 기준으로 만들어졌기 때문에 로우 레벨 API의 하드웨어에 있는 고급 기능까지 사용하여 한계까지 성능을 끌어내긴 어렵다. 즉, 다른 기술은 D3D API 등을 경유하기 때문에 시간이 걸리지만 쿠다는 바로 하드웨어에 엑세스하여 컨트롤 할 수 있다.
하지만 이는 쿠다의 단점으로 이어지는데, 그래픽 기능과의 연동을 전제로 만들어진 DirectCompute에 비해 그래픽 출력 용도로 사용시 오버헤드가 커진다.
그래픽 카드의 GPU는 대량의 데이터에 한 가지 연산을 적용하는 경우가 많기 때문에 단순화된 연산 유닛(코어)을 천여 개씩 탑재하고 있다.[2] 따라서 SIMD(Single Instruction Multiple Data) 형태의 병렬화가 가능한 연산에 GPU를 활용해서 속도를 올리려는 시도는 예전부터 있어 왔다. 그러나 원래 그래픽을 처리하라고 설계된 그래픽스 파이프라인을 가지고 일반적인 병렬 연산을 수행하는 것은 매우 골치아픈 일이었다. 프로그래머가 일일히 GPU의 세부 사항을 다 신경써야 했기 때문이다.
CUDA 프로그램은 스트림 프로세싱[3]에 기반하며, 그 작성에는 C/C++ 언어에 동시에 실행할 쓰레드 개수 등을 선언하는데 사용되는 CUDA 전용 문법을 추가한 언어를 사용한다. CUDA 코드는 대략 GPU 안에서만 돌아가는 함수(커널이라고 부른다)를 호스트(CPU)에서 호출하는 형태로 되어 있다.
CUDA는 GPU의 메모리 모델을 추상화해서 좀 더 편하게 GPU을 이용할 수 있도록 했다. 하지만 여전히 CUDA로 최대한의 속도 증가를 얻으려면 GPU의 메모리 구조에 대해서 잘 알아야 한다. 윈도우 한정으로 CUDA 프로그래밍의 귀찮음을 덜어 주기 위해서 만들어진 BSGP(Bulk-Synchronous GPU Programming)라는 녀석이 존재한다. BGSP는 CUDA의 기계어 명령번역을 사용한 별도 언어다. 레이 트레이싱 류의 coherence가 낮은 작업에선 CUDA보다 성능향상이 있다. 다만 BGSP가 만능은 아니다. 반대로 메모리 참조 연속성이 강한 작업에선 CUDA보다 성능이 낮아진다.
최근에 CUDA를 더 보완한 OpenACC라는 게 나왔다. 좀 더 추상화가 돼있어서 코딩하기 더 편하다고 한다. 마이크로소프트에서는 C++ AMP라는 걸 만들었는데 OpenACC의 DirectCompute 버전 정도라 볼 수 있다. 그래도 아직은 일반 프로그래머가 사전지식 없이 덤빌 만한 난이도는 아니다. 단지 전에 비해 진입장벽이 많이 낮아졌을 뿐.
R337 드라이버 이후부터는 Geforce 제품군에서의 CUDA 기반 비디오 인코딩/디코딩 라이브러리가 삭제되었다. NVENC[4]를 밀기 위해서라는데(이전의 쿠다 인코더를 대체) '''Tesla나 Quadro 제품군은 정상적으로 사용이 가능하다.''' 이에 CUDA 가속을 사용하는 코덱의 사용이 불가능해지거나, 이전의 라이브러리 파일을 따로 넣지 않으면 미디어 편집 프로그램들에서의 호환성에 문제가 생겼다.
딥러닝을 도와주는 여러 라이브러리도 CUDA와 함께 제공된다. cuDNN, Convolution 연산을 더 빠르게 만들어주는 cuFFT[5], 선형대수 모듈인 cuBLAS 등 사실상 필요한 라이브러리들은 대부분 구현되어 있다. TensorFlowPyTorch 프레임워크가 이와 같은 라이브러리들을 사용한다.

2. 유사 개념


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

[1] 전기차 회사 테슬라와는 관계가 없다[2] CPU는 복잡한 계산을 2~4개 정도 동시에 수행할 수 있다면, GPU는 단순 반복 계산 수백~수천 개를 동시에 수행할 수 있다.[3] 병렬처리 프로그래밍의 일종.[4] 하드웨어 기반 가속을 지원하는 라이브러리이다[5] FFT는 고속 푸리에 변환의 약자이다. Convolution 연산을 하는 데에는 MN의 시간이 필요한데, FFT를 이용하면 MlogN의 시간에 처리가 가능하다.[6] 그러나 나온 지 꽤 되었는데도 아직 불안정하다. 애초에 일개 프로젝트로 커버하려는 범위가 너무 넓다.