[App 개발] OpenCL: democracy for GPU computing?
-
2회 연결
-
2회 연결
본문
by Damien Triolet
March 19, 2009
OpenCL 개발 실무진이 꾸려진 지 6 개월 후 Khronos 라는 이름으로 출범하게 되었습니다. 아시는 것처럼 OpenCL (Open Compute Language) 는 대규모 병렬 프로세싱을 위해 꾸며진 API 으로서, 애플에 의해 처음 제안되었습니다. 크로너스 그룹은 OpenGL 과 같은 오픈 API 를 개발하기 위한 시장 선도 그룹의 컨소시엄입니다.
이제 아시게 되겠지만, GPU 는 NVIDIA 진영의 CUDA 라든지 AMD 의 Brook+/CAL 을 이용한 대규모 병렬 프로세싱 유닛으로 활용될 수 있습니다. 이런 개별 API 의 출범은 호환성 문제를 일으킵니다. CUDA 프로그램은 Radeon 에서 동작하지 않고 Brook+ 는 GeForce 에서 동작하지 않기 때문입니다. 이에 애플사는 OpenCL 을 제안함으로써 특정 회사의 제품에 한정되지 않고 GPU 성능을 활용할 수 있도록 하였습니다. OpenCL 은 이러한 방식을 규격화한 API 입니다. 언제나 그렇듯이 현실은 훨씬 더 복잡합니다. 그래서 이런 글도 쓰여지게 되지요.
OpenCL versus CUDA?
CUDA 가 현재로서는 GPU 컴퓨팅 API 로 가장 많이 사용되고 있으므로 많은 사람들이 위의 질문을 하게 됩니다. 하지만 OpenCL 은 CUDA 와 경쟁하기 위해 만들어진 것이 아닙니다. 이를 이해하기 위해서는 CUDA 가 실제로 무엇인지를 이해해야 합니다. CUDA 는 대규모 병렬 프로세싱을 위해 디자인된 아키텍쳐입니다. NVIDIA 는 이를 위하여 API 를 개발했고, 특별히 C 언어를 위해 CUDA "CUDA for C" 를 만들어 CUDA 라는 이름으로 아키텍쳐와 함께 자사 API 를 동시에 각인하게끔 한 것입니다.
CUDA 호환카드 (GeForce, Quadro, Tesla) 는 CUDA for C 와 OpenCL 을 모두 지원합니다. 같은 방식으로 Stream 호환카드 (Radeon, FireGL, Firestream) 는 Brook+ 와 OpenCL 을 모두 지원합니다. OpenCL 은 따라서 모든 아키텍쳐에 공통된 언어입니다. OpenCL 은 반드시 GPU 만을 위해서 고안된 것이 아니며, CPU 및 Cell 같은 액셀러레이터도 지원합니다. 그렇다면 이제 당장 어느 아키텍쳐에서나 호환 가능한 코드를 작성할 수 있을까요? 그 문제는 좀 더 복잡합니다. 사실 OpenCL 에 참여하는 기업들 중 특히 애플, AMD, 인텔, NVIDIA, 소니는 포팅하기 쉽게 만들기보다는 개별 아키텍쳐의 특수성을 살리는 방향으로 개발하고 있습니다.
OpenCUDA
OpenCL 문서를 살펴보시면 OpenCL 의 기저에는 확실히 C for CUDA 가 있음을 볼 수 있습니다. 처음부터 몽땅 개발할 필요는 없지요. 쉽게 말해서 컨소시엄 업체들은 NVIDIA 의 API 를 가져다가 회원사들이 원하는 대로 확장한 것입니다.
기본 동작 원리는 C for CUDA 와 동일합니다. 커널은 "processing elements" 가 "work item" 작업을 수행하는 "compute units" 로 구성된 "compute device" 액셀러레이터로 전송됩니다. 설명 자체는 완전히 동일합니다. 하지만 정치적인 이유로 크로너스는 C for CUDA 와 전혀 다른 명칭을 사용하고 있습니다. 다음은 여러분이 익숙한 CUDA 명칭을 번역한 것입니다.
Multiprocessor -> Compute Unit
Processor -> Processing Element
Block -> Work-group
Thread -> Work-item
Texture -> Image Object
Shared Memory -> Local Memory
그러나 OpenCL 에서는 shared memory 를 work group 내의 공유 메모리의 개념으로 사용하지만 그 특성에 대해서는 정의하지 않고 있습니다. 왜냐하면 이 메모리는 매우 특수하기 때문에, 유용하게 사용하기 위해서는 회사의 매뉴얼을 살펴보아야 합니다. 한 가지 작은 차이점으로, C for CUDA 에서는 local memory (그래픽 카드 내) 와 global memory (시스템 내) 를 따로 정의하지만, OpenCL 에서는 모두 global memory 로 정의합니다.
OpenCL 은 특정한 형식이 없습니다. 하지만 OpenCL 은 향후 사용될 모든 그래픽 카드 형식을 활용할 수 있게 합니다. 개발자들은 이 형식을 바탕으로 코드와 그래픽 카드의 호환성을 확인해야 합니다. 경우에 따라서는 코드가 그래픽 카드와 호환되지 않을 수 있습니다. 예를 들어 endian 형식은 지정되어 있지 않습니다. 개발자는 그래픽 카드 형식에 맞춰서 코드를 조정해야 합니다. 하지만 이런 몇 가지 경우를 제외하면 그리 큰 차이는 없습니다.
The main difference
OpenCL 은 C for CUDA 보다 약간 하위 개념 API 입니다. C for CUDA 는 런타임 모드 (기본) 혹은 드라이버 모드 (조금 더 복잡) 로 활용됨을 기억하실 겁니다. 드라이버 모드가 OpenCL 에 해당하는 모드로서, 개발자는 메모리 관리를 수동으로 해 주어야 합니다. C for CUDA 의 런타임 모드에서는 자동으로 해 주는 기능이지요.
그리고 인텔의 Ct 언어처럼, OpenCL은 데이터와 태스크 레벨의 패러랠리즘을 지원합니다. 데이터 패러랠리즘은 GPU 에서 사용되는 것(NVIDIA 에서는 쓰레드라고 하는, 이종 데이터에서 실행되는 동일한 프로그램)이고 태스크 패러랠리즘은 예를 들면 SSE 유닛에서 일어나는 작업과 유사한 것입니다. 두 번째 모델은 GPU 상에서는 덜 효율적인 모델입니다.
OpenCL 은 OpenGL 에서 지원하는 것과 동일한 확장성을 지원하는데, 이것은 OpenCL 을 통해 작성되거나 컴파일되지 않은 특수한 그래픽 카드를 위해 작성된 프로그램 코드를 네이티브 커널 내에 포함시키는 기능입니다. 개별 회사들은 자사 제품을 위한 특수 코드를 넣을 수 있습니다. 네이티브 커널에 자사 API 를 사용한 코드는 다른 회사 장치에서 구동되지 못하게 될 수도 있습니다.
OpenCL 은 계산 밀도 측면에서 사양이 떨어지는 모바일 장치를 위하여 고안된 ES 모드를 지원합니다.
NVIDIA 와 OpenCL
지난 주 NVIDIA 의 CUDA 전문가와 만날 기회가 있어서 그곳의 OpenCL 지원 상황을 알 수 있었는데, 회사로부터 확고한 지원을 받고 있다고 하였습니다. 여러분은 아마도 OpenCL 이 C for CUDA 와 경쟁 관계에 있으며 NVIDIA 는 OpenCL 의 등장을 반기지 않을 것으로 생각하실 수도 있겠습니다. 물론 NVIDIA 측에서는 다른 회사도 모두 사용 가능흔 OpenCL 보다는 C for CUDA 사용이 자사 제품을 사용해야만 하므로 더 좋을 수도 있을 것입니다.
하지만 이것은 상황을 너무 단순하게 바라보는 것입니다. 이쪽 시장은 아직 초기 단계이고 자잘한 부스러기를 놓고 싸우기보다는 파이를 더 키우는 쪽으로 나아가는 것이 전략적으로 낫습니다. NVIDIA 가 GPU 를 이용한 대규모 병렬 프로세싱 활용을 위한 모든 기술개발에 선도적 역할에 나서고 있는 이유도 이것 때문입니다.
3D Labs 에서 일하다가 현재 NVIDIA 의 임베디드 제품 VP 로 재직중은 닐 트리베트는 OpenCL 개발팀을 출범시켰습니다. C for CUDA 와 OpenCL 의 유사성과 애플이 (새 맥에 NVIDIA 제품을 탑재하기로 결정한 이후) 이 방법을 제안하여 논의하기로 하게 되면서 NVIDIA 는 실제적인 협력 개발사로 등장하게 되었습니다.
NVIDIA 는 사실 OpenGL 이 자사 GPU 에서 개발되었고 처음 시연되었다는 점을 부각시키고 있습니다. C for CUDA 와 OpenCL 의 유사성으로 NVIDIA 는 물론 OpenCL 초기 개발 과정에서 C for CUDA 컴파일러를 약간 수정하여 OpenCL 버젼으로 만들어 줌으로써 제품 시연을 가능하게 하였습니다. 두 컴파일러는 동일한 중간 언어인 PTX for CUDA 를 사용할 것입니다. 이것은 GPU 에서 동작되는 최적화된 기계어를 작성하는 데 사용됩니다. AMD 는 OpenCL 컴파일러 CAL 을 탑재할 것입니다만, 좀 더 작업이 필요한 상태입니다.
NVIDIA 는 OpenCL 베타판을 이번 봄에 만들 계획이고 곧이어 1.1 버젼을 2009 년 여름에 완료할 것입니다. 따라서 초기 사용자들의 주목을 끌고 있는 OpenGL 의 이해를 넓히게 될 것입니다. AMD 는 OpenGL 의 시험판을 2009 년 상반기에 내놓을 것으로 보도하였습니다.
물론 OpenCL 의 등장은 C for CUDA 의 개발 중단을 의미하지 않으며 CUDA 는 NVIDIA 에 매우 중요합니다. 자사 고유 API 이므로 생산자는 자사 고유 GPU 의 새로운 기능을 다른 회사에게 차세대 칩의 구조를 노출하지 않으면서도 기민하게 라이브러리에 적용할 수 있습니다. CUDA 는 2009 년 상반기에 두 번의 마이너 업데이트를 거쳐 올해 안에 3.0 을 내놓을 계획입니다.
Portability: sort of...
다양한 장치를 모두 지원하는 API 는 그 고유의 특성상 이식성을 갖추게 됩니다. 그러나 다양한 그래픽 카드를 지원하는 OpenCL 코드를 개발하는 것은 쉬운 일이 아닙니다. 고유의 하드웨어를 지원하는 각각의 코드를 작성해 주어야 하는데, 왜냐하면 알고리듬 개발은 3D 보다 훨씬 더 아키텍쳐별로 특성이 매우 다릅니다. 그렇지 않다면 덜 최적화된 코드를 만들어 줄 수도 있습니다만 이종 아키텍쳐의 공통 분모를 본다면, 이종 GPU 간에서는 나름대로 찾을 수 있겠습니다만 GPU 와 Cell 프로세서의 경우는 불가능합니다.
전문적인 용도로 본다면 첫 번째 해법이 가장 좋겠습니다만 Tesla 카드용 OpenCL 코드는 FireStream 카드용 코드와 호환이 전혀 불가능합니다. 개발자가 특정 하드웨어 회사에 덜 의존적이 된다 할지라도 말이지요. 코드가 최적화 되면 될 수록 이식성은 떨어지게 되며, 고성능 컴퓨팅 분야에서 알고리듬의 최적화는 반드시 이루어져야 합니다.
범용 제품 분야에서 어떻게 발전될지 예측은 쉽지 않습니다. 실제로 OpenCL 은 특성에 대한 표준화가 전혀 이루어지지 않은 점에서 실망스럽습니다. 물론 OpenCL 을 GeForce 와 Radeon 에서 동시에 이용하는 것이 C for CUDA 를 Brook+ 에서 이용하는 것보다는 훨씬 쉽습니다. 하지만 그러기 위해서 아직도 많은 일들이 필요합니다. OpenCL 은 넓게 보아서 OpenGL 이 겪었던 동일한 어려움을 겪고 있으며, 우리는 GPU 가 범용 솔루션 분야에서 대규모 병렬 프로세싱에 사용될 때까지 DirectX 11 을 기다려야 할지도 모릅니다. OpenCL 의 방식과 달리 초기부터 문제를 바로잡기 위해서 DirectX 11 이 공통 규격을 정의한 점을 생각해 보아야 하겠습니다. NVIDIA 와 AMD 가 차세대 GPU 개발에 이 점을 고려해 주기를 바랍니다. 물론 쉽지 않겠지요.
크로너스 그룹은 OpenCL 로 여러 가능성을 가진 API 를 개발하였습니다만, 아직 어느 가능성으로도 움직이기 쉽지 않습니다. 아직은 많은 단점을 가지고 있습니다. 물론 확장 일로에 있는 대규모 병렬 컴퓨팅에 새롭게 등장한 유용한 툴입니다만, OpenCL 은 개발자들을 모든 최신 기종의 잠재 능력을 끌어낼 표준화된 방식을 제시하는 만병통치약이 아직은 아닙니다.
최신글이 없습니다.
최신글이 없습니다.
댓글목록 2
용가리님의 댓글
계속된 좋은 정보 감사합니다.
저의 시류에 뒤쳐진 쓸모 없던 잡소리가 있던 댓글은 지웠습니다.
뭔가 심기일전 해서 더 열심히 배워야겠습니다.
좋군요. 반성하는 계기도 되고, 공부도 되고...
hongjuny님의 댓글
시류에 뒤쳐졌다니, 천부당 만부당 하십니다.
OpenCL 자체가 성숙한 기술이 아니고, 그만큼 유연성을 가지고 공부해야 할 것이라 생각합니다.