GTC 2017에서 NVIDIA의 차세대 아키텍처인 볼타, 그리고 볼타를 사용한 GPU인 GV100이 발표됐습니다. 그리고 볼타 세대 GPU체는 새로운 CUDA인 CUDA 9이 쓰입니다.
이 CUDA 9에 대해 설명하는 세션인 CUDA 9 and Beyond가 Mr. CUDA라고도 불리는 Mark Harris(Chief Technologist GPU Computing, NVIDIA)에 의해 열렸습니다.
CUDA 9의 새로운 요소 1. 텐서 코어의 지원
CUDA 9의 새로운 특징은 위 4개를 꼽을 수 있습니다. 볼타 플랫폼 지원이라 써져 있으나 CUDA 9는 기존의 NVIDIA GPU도 지원합니다.
첫번재 새로운 요소는 볼타 세대 GPU에 탑재되는 텐서 코어(Tensor Core)의 지원입니다. 텐서 코어가 무엇인가에 대해서는 https://gigglehd.com/gg/1076083 여기에서 설명했으니 여기에선 간단히 소개하고 넘어가지만, 머신 러닝 AI에서 많이 쓰이는 대규모 행렬 계산이나 연산에 유용한 전용 연산 유닛입니다.
텐서 코어가 수행할 수 있는 가장 기본적인 계산은 4x4 행렬의 연산입니다.
볼타 세대 GPU는 4x4 행렬 계산을 두 세트로 묶어 하나의 Warp에서 처리할 수 있습니다.
볼타는 16x16 행렬 연산을 16개의 Warp로 분해해 실행합니다. CUDA 9는 WMMA(Warp Matrix Multiply and Accumulate)이라는 새로운 데이터 타입(계산 모델)을 이용해 거대한 크기의 행렬 계산을 할 수 있습니다. 물론 Warp로 분해해서 처리할 수 있습니다. 위 슬라이드는 8x8 행렬 계산인데 WMMA를 이용해 4x4 행렬로 분해해서 연산했습니다.
WMMA를 대상으로 한 로드/스토어 명령을 새로 만들어, 행렬 형태의 데이터를 Warp의 데이터 스레드에 배포하거나 반대로 메모리에 내보낼 수 있습니다.
CUDA 9 WMMA를 이용해 거대한 행렬 계산을 했을 때의 처리 능력을 볼타 GV100과 파스칼 GP100에서 비교했습니다. 볼타 세대의 GPU는 기존에 없던 행렬 계산 전용 프로세서인 텐서 코어가 있어 압도적인 성능 차이가 납니다. 이 그래프는 CUDA의 수학 라이브러리인 cuBLAS에서 GEMM(GEneral Matrix-matrix Multiplication)의 성능을 비교한 것인데 FP32에서 1.8배, FP16에서 9.3배 차이가 납니다.
CUDA 9의 새로운 요소 2. 데이터 스레드의 자유로운 그룹화
CUDA 9의 두번째 특징은 볼타 세대 이전, 구체적으로는 케플러~파스칼 세대 GPU에 도움을 주는 기능입니다. Warp를 원하는 크기로 그룹으로 나눠, 그룹 사이에 동기화하는 것이죠. NVIDIA GPU에서 일반적인 1 Warp는 32개의 데이터 스레드가 되는데, 이를 4개의 데이터 스레드로 구성된 8개의 그룹으로 나눌 수 있습니다.
그리고 이렇게 나뉘어진 데이터 스레드는 특정 그룹끼리 동기화를 할 수 있습니다. 그룹별로 처리하는 GPU가 다른 멀티 GPU 환경에서도 CUDA 9가 명시적인 동기화를 취할 수 있는 것입니다.
CUDA 8까지는 데이터 스레드의 처리가 끝난 시점을 동기화하는 시기로 잡았으나, cUDA 9는 개발자가 동기화 지점을 명시적으로 만들 수 있습니다. 또 데이터 스레드 동기화는 데이터 스레드 단위, Warp나 그보다 더 작은 수의 데이터 스레드로 구성된 그룹 사이의 동기화, 멀티 GPU 사이의 데이터 스레드 그룹 동기화가 가능합니다.
일반적인 GPU의 명성 실행은 SIMT(Single Instruction Multiple Threads). 하나의 명령으로 여러 데이터 스레드를 처리합니다. 다른 데이터 스레드에 같은 메모리 어드레스 데이터가 포함돼 있고, 거기에 대한 작업을 병렬로 실행한 경우 명시적인 동기화 지정이 불가능했습니다. CUDA 8 이전에는 동기화의 개념이 없어 모든 데이터 스레드에 대한 처리가 끝나면 종료시키는 구조였습니다. 그래서 예상한 결과가 나오지 않거나 디버깅하기 힘든 버그를 초래하기도 했지요.
CUDA 9는 데이터 스레드 단위부터 GPU 단위까지 다양한 단위로 동기화를 할 수 있습니다. 그래서 기존의 문제를 해결함은 물론, 파스칼 세대 이전 GPU에서도 사용할 수 있다는 게 큽니다.
명시적인 데이터 스레드 동기화는 복잡한 데이터 스레드의 병렬 실행을 안전하게 할 수 있는 구조입니다.
CUDA 9의 새로운 요소 3. 데이터 스레드 사이에 데이터를 보거나 작성 가능
동기화 기능은 파스칼 세대 이전 GPU에서도 쓸 수 있으나, 역시 볼타 세대 GPU에서 위력을 발휘합니다. 그리고 이것이 CUDA 9의 세번째 특징입니다. 볼타 세대 GPU는 데이터 스레드의 동기화는 물론이고, 데이터 스레드 사이에 메세지를 교환하거나 데이터 참조가 가능합니다.
A, B, C라는 세가지 목록 구조 데이터가 있고, A와 C에 GPGPU 처리가 이루어지고 있다고 칩시다. 처리 자체에는 문제가 없습니다. 그런데 A와 C는 서로의 메모리 어드레스를 참조하는 목록 구조의 데이터고, 거기에 다른 목록 구조의 데이터인 B를 통합하려 합니다. 목록 구조 데이터를 재조합한 다음 데이터를 지시 포인터(메모리 어드레스 값)에 재작성하기에, 포인터 갱신이 다른 GPGPU 처리에서 무시되지 않도록 A촤 C를 잠궈야 합니다.
그리고 A촤 C 사이에 B가 오도록 포인터를 갱신하고.
데이터 쓰기가 끝나면 잠금을 해제합니다. 이런 처리를 실현하려면 데이터 스레드에 여러 작업을 할 필요가 있으나, CUDA는 그런 처리는 하지 않는다는 전제로 설계한 플랫폼입니다.
파스칼 세대 이전의 GPU에선 하나의 Warp(데이터 스레드 32개)에 대해서 프로그램 카운터와 스택 포인터가 하나씩밖에 없었습니다. 프로그램 카운터가 가리키는 메모리 어드레스에 저장된 명령을 여러 데이터에 수행할 수밖에 없었지요.
그래서 조건 분기 프로그램 명령이 실행됐을 때, if 조건을 충족하는 데이터 스레드에 대해서만 A; 와 B; 작업을 수행하고, 그렇지 않은 else 조건의 데이터 스레드에는 X;와 Y; 작업을 수행하는 방식으로 여러 스레드에 작업을 했습니다.
Warp의 데이터 스레드는 공통 프로그램 카운터와 스택 포인터로 처리하기에 각 데이터 스레드에 별도의 처릴르 적용하는 매커니즘이 CUDA에 없었습니다. A;와 B;, X;와 Y;에 동기화를 처리하는 건 아키텍처 레벨에서 할 수 없었습니다.
이에 비해 볼타 세대 GPU는 Warp의 데이터 스레드가 별도의 프로그램 카운터와 스택 포인터를 가질 수 있도록 GPU 아키텍처가 개선됩니다. 32개의 데이터 스레드가 개별적인 프로그램 카운터와 스택 포인터를 갖게 되는 거지요.
따라서 if 조건을 만족하는 데이터 스레드 A; 처리가 끝난 단계에서 다른 데이터 스레드와 동기화하거나 다른 데이터 스레드 연산 내용을 참조하는 작업이 가능해졌습니다. 사실 이것은 프로그램 병렬도를 높여 성능을 끌어올리는 게 아니라 더 복잡한 프로그래밍 모델이 가능하게 되는 확장이지요.
그리고 모든 데이터 스레드가 데이터를 복사하거나 데이터 스레드 내용을 통합하는 처리랄 할 수 있습니다.
데이터 스레드마다 다른 작업을 수행하는 사례입니다. 비트 마스크라는 규칙을 여럿 준비하고, 규칙에 맞춰 데이터 스레드를 분류하고 여기에 여러 작업-스레드 사이의 동기화-를 처리하는 것이 볼타 세대 GPU에서 가능합니다.
지포스용 볼타에 텐서 코어가 들어갈 것인가?
CUDA 8에서 CUDA 9로 업데이트되며 프로그래밍 모델이 크게 향상돼 CUDA를 사용하는 개발자에 큰 영향을 미칠 것으로 보입니다. NVIDIA는 CUDA 8 이전의 CUDA 애플리케이션은 CUDA 9에서 다시 컴파일해 호환성을 유지할 수 있으나, 앞으로는 CUDA 9 스타일로 개발하길 권장하고 있습니다. 특히 데이터 스레드 동기화 시점의 명시는 CUDA 9에서 매우 중요한 요소입니다.
그럼 CUDA 9는 언제 나오느냐. GTC 2017에선 밝히지 않았습니다. 다만 볼타 GPU의 출시에 맞춰 등장하는 게 당연하기에 2017년 3분기가 될 것으로 보입니다. CUDA는 테슬라나 쿼드로는 물론이고 지포스에서도 동작하지만, 앞으로의 지포스에서 CUDA 9의 모든 기능이 동작할지는 아직 모릅니다. NVIDIA 직원에게 물어봐도 '앞으로 나올 제품에 대해선 대답하지 않는다'가 돌아올 뿐.
지포스에서 CUDA를 쓰는 사람에게 신경쓰이는 건 지포스 GPU에 텐서 코어가 탑재되느냐는 것입니다. 텐서 코어는 머신 러닝 AI와 컴퓨터 비전 처리를 위한 연산 유닛이며, 다이렉트 X나 벌칸 같은 그래픽 API에서 쓸 방법이 없습니다. NVIDIA GPU에 의한 가속이 가능한 물리 시뮬레이션 엔진 PhsX에서 텐서 코어를 지원하면 게임에서 쓸 수 있을 정도겠지요. 당분간은 지포스에 텐서 코어가 올라갈 가능성은 낮다고 봅니다.
그리고 텐서 코어를 제외하면 볼타와 파스칼 아키텍처의 차이는 16nm와 12nm 등 공정 설계 외엔 없다고 봐도 무방할 것이나, 볼타의 세부 스펙이 공개되면 텐서 코어 외에 무엇이 다른지도 알 수 있을 것입니다. 사실 2017년 4월에 플래그쉽인 타이탄 Xp, 5월 17일에 지포스 GT 1030까지 파스칼 라인업이 나온 것을 감안하면 볼타 기반 지포스가 곧 나오진 않을 것입니다. AMD의 차세대 GPU인 라데온 RX 베가가 나온 후에나 움직임이 보이겠죠.
볼타 세대의 테슬라 V100은 싱글 슬롯 PCI-E 확장 카드로도 나옵니다.