nVidia GPU 아키텍처 변천사 (하편)

이 글은 이전 글에서 이어지는 글 입니다. 이번 글은 Streaming Multiprocessor의 구조를 중심으로 Maxwell에서 Volta까지의 nVidia GPU 아키텍처의 변화를 다루며 이전 글은 Tesla부터 Kepler 까지의 아키텍처를 다루고 있습니다.

이전 글 : nVidia GPU 아키텍처 변천사 (상편)

Maxwell 아키텍처

Maxwell 아키텍처 개발 당시의 상황은 이전 세대 아키텍처 개발과 비교하여 두 가지 차이점이 있었습니다. 첫째는 Kepler까지는 데스크탑 버전을 위주로 아키텍처 설계를 진행한 후 이를 줄여서 모바일 버전을 만들어왔지만 Maxwell은 모바일 버전을 우선적으로 고려하여 아키텍처 설계가 진행되었다는 점 입니다(관련 링크). 둘째는 이전까지는 아키텍처가 변할 때 마다 공정 기술의 발달이 동반되어 CUDA 코어의 개수를 크게 늘리거나 클럭 속도를 높이기가 용이했지만 Kepler에서 Maxwell로 아키텍처가 변경되는 시점에는 공정이 28nm에 그대로 머물러 있었다는 점 입니다. 트랜지스터가 기존의 CMOS에서 구조가 다른 FinFET으로 변경되면서 공정 미세화가 잠시 정체되어 있었기 때문이지요. Maxwell 아키텍처는 공정 미세화의 이득을 볼 수 없었기 때문에 Kepler 아키텍처를 최적화하는 방향으로 개발이 진행 되었습니다.

Maxwell 아키텍처의 Streaming Multiprocessor 구조 (출처 – “Whitepaper NVIDIA GeForce GTX 980 Featuring Maxwell, The Most Advanced GPU Ever Made.”)

위의 그림은 Maxwell의 Streaming Multiprocessor(SMM)의 구조를 보여주는데 Kepler의 SMX에서 192개이던 CUDA 코어의 갯수가 128개로 크게 줄어들었습니다. CUDA 코어의 개수를 줄인 이유는 Kepler의 SMX에서 명령어 Dispatch Unit에 비해 CUDA 코어의 개수가 많아 CUDA 코어가 사용되지 않고 낭비되는 경우가 많다는 분석이 있었기 때문입니다. nVidia에 따르면 CUDA 코어 개수를 192개에서 128개로 크게 줄였지만(1/3감소) SMM의 성능 저하는 10% 정도밖에 되지 않는다고 합니다(관련 링크). Shared memory와 관련된 부분도 변화가 있었는데, 이전세대 까지는 shared memory의 일부를 L1 cache로 설정하여 사용할 수 있었지만 Maxwell 부터는 shared memory와 L1 cache가 분리되었습니다. L1 cache는 texture cache로도 사용됩니다.

SMM 하나의 면적이 줄어들었기 때문에 Kepler에 비해 SMM의 개수를 두배로 늘리면서도 칩 전체 면적은 두배로 늘어나지 않았는데, Kepler 아키텍처의 GK104 GPU의 경우 8개의 SMX를 탑재하여 1536(=8×192)개의 CUDA코어를 가지고 있는 반면 Maxwell 아키텍처의 GM204 GPU의 경우 2배인 16개의 SMM을 탑재하여 총 2048(=16×128)개의 CUDA 코어를 가지고 있습니다(관련 링크). 칩의 면적은 GK104가 294mm2, GM204가 398mm2로 CUDA 코어의 개수와 거의 비례합니다만 SMX의 90%성능을 가지는 SMM의 수가 두배로 늘었기 때문에 실 사용 성능은 1.8배 정도로 면적증가분(1.35배)보다 더 많이 늘었다고 볼 수 있습니다. (이론상 peak 성능이 아님에 주의!)

Maxwell 아키텍처에서 이루어진 또 다른 최적화는 Dispatch Unit과 실행 유닛들 (CUDA 코어, LD&ST 유닛, SFU) 사이의 접근성을 제한하여 전력 소모를 줄였다는 점 입니다. 위의 그림에서 왼쪽은 Kepler 아키텍처의 SMX에서 명령어 Dispatch Unit들과 실행유닛들이 하나의 crossbar 스위치를 통해 모두 연결되어 있는 구조를 보여주고 있습니다. 이럴 경우 8개의 Dispatch Unit은 각각 어떤 실행 유닛이든 자유롭게 접근 할 수 있는 장점이 있지만 커다란 crossbar 스위치는 무시할 수 없을 만큼 면적을 차지하고 전력을 소모하게 됩니다. Maxwell 아키텍처의 SMM에서는 위의 그림의 오른쪽과 같이 실행유닛을 4개의 부분으로 나누고 4쌍의 Dispatch Unit이 각자 SMM의 4부분 중 하나만을 접근하도록 구조를 변경하여 crossbar 스위치의 크기와 전력 소모를 크게 줄였습니다. 이럴 경우 한 쌍으로 묶인 두 Dispatch Unit이 동일한 실행 유닛을 사용하려고 할 때 하나의 명령어밖에 실행하지 못할 가능성이 높아지지만 이로 인한 성능감소보다는 전력소모와 칩 면적감소의 잇점이 훨씬 컸다고 합니다.

SMM의 구조가 변경된 점 이외에 전력 소모를 줄이기 위한 또 다른 변화는 L2 cache의 크기가 Kepler의 512KB에서 2MB로 크게 늘었다는 점 입니다. GDDR5 메모리의 전력 소모는 얼마나 자주 메모리를 접근하는지에 크게 영향을 받는데 L2 cache를 늘림으로써 GDDR5 메모리 접근 빈도를 줄여 메모리 시스템에서 발생하는 전력소모를 줄였습니다. 그 밖에 회로가 동작하지 않는 동안 클럭 공급을 끊는 clock gating을 좀 더 폭넓게 적용한 것과 반도체 공정 자체의 최적화도 Maxwell 아키텍처 기반 GPU의 전력소모를 줄이는데 기여를 했다고 합니다.

Maxwell의 SMM에 대해 마지막으로 언급할 점은 64-bit 부동소수점 계산을 위한 Double Precision(DP) 유닛의 개수가 Kepler의 SMX에 비해 대폭 줄어들었다는 점 입니다. 위의 그림에는 나와 있지 않지만 Warp Scheduler 하나당 1개의 DP 유닛이 존재하는 것으로 생각되는데 이 때문에 Maxwell 아키텍처의 64-bit 부동소수점 연산성능은 32-bit 연산성능에 비해 1/32 정도밖에 되지않아 성능이 크게 후퇴했습니다(관련 링크). 개인적으로는 공정기술이 뒷받침되지 않는 한계를 감안하여 보다 많은 사용자들이 원하는 32-bit 연산성능을 위해 64-bit 성능을 포기한 것으로 추측됩니다.

Pascal 아키텍처

Maxwell 아키텍처가 발표된 이후 딥러닝 붐이 일어나 Pascal 아키텍처가 등장한 시점에는 이미 딥러닝과 AI(Artificial Intelligence)분야에 GPU가 널리 사용되고 개발자수도 크게 늘어나고 있는 시기였습니다. nVidia 자체도 GPU회사로 불리기보다는 AI 회사로 불리기를 원했는데 Pascal 아키텍처가 공개된 2016년 GTC(GPU Tech. Conference) 키노트 발표를 보면 3D 그래픽과 관련된 내용보다 딥러닝과 AI와 관련된 내용에 훨씬 많은 발표 시간을 할애하고 있습니다.

Pascal 아키텍처의 두 가지 버전 – 그래픽을 고려한 GP104와 HPC를 고려한 GP100 GPU의 공통점과 차이점 (출처 – http://www.anandtech.com/show/10325/the-nvidia-geforce-gtx-1080-and-1070-founders-edition-review/2)

Pascal 아키텍처의 Streaming Multiprocessor는 이전세대와는 달리 두가지 버전이 등장했는데, High Performance Computing(HPC) 분야와 그래픽 분야에서 요구되는 성능이 달라졌기 때문입니다. HPC나 딥러닝 분야에서는 64-bit/16-bit 부동소수점연산(FP64/FP16) 성능과 하나의 thread가 많은 레지스터를 사용할 수 있는 것이 중요하지만 그래픽 분야의 shader 프로그램은 32-bit 부동소수점연산(FP32)을 주로 사용하는데다 프로그램이 상대적으로 간단하여 레지스터의 개수를 늘려도 성능이 크게 향상되지 않습니다. 위의 그림은 그래픽 분야를 고려한 GP104 GPU와 HPC/딥러닝 분야를 고려한 GP100 GPU의 공통점과 차이점을 보여주고 있는데 Warp Scheduler 하나 당 레지스터 파일의 크기와 FP32대비 FP64/FP16 성능비율에 차이가 있습니다. GP104의 SM 구조는 FP16 지원을 위한 2개의 유닛이 추가된 것 이외에는 Maxwell의 SMM과 구조가 거의 동일하기 때문에 Pascal 아키텍처는 GP100을 기준으로 살펴 보도록 하겠습니다.

GP100 Pascal 아키텍처의 Streaming Multiprocessor 구조 (출처 – “Whitepaper, NVIDIA Tesla P100, The Most Advanced Datacenter Accelerator Ever Built Featuring Pascal GP100, the World’s Fastest GPU”)

위의 그림은 GP100 Pascal의 SM 구조를 보여주고 있는데 Maxwell의 SMX에 비해 CUDA 코어를 비롯한 실행 유닛의 개수는 1/2인 64개로 줄었습니다. 실행 유닛의 개수가 반으로 줄어들었지만 레지스터 파일의 크기는 그대로 유지된 덕분에 Warp Scheduler 하나 당 접근할 수 있는 레지스터는 두배로 늘어 Pascal의 SM에서 실행되는 thread는 보다 많은 레지스터를 사용할 수 있습니다. SM 하나의 크기가 줄어들고 공정이 28nm에서 16nm로 향상되면서 전체 GPU에 탑재되는 SM의 개수는 크게 늘었는데, Kepler 아키텍처 기반의 GM204/GM200 GPU의 경우 16/24개의 SMM을 탑재하지만 Pascal 아키텍처의 GP100 GPU는 무려 56개의 SM을 탑재하고 있습니다.

GP100버전의 Pascal은 HPC/딥러닝 지원을 목표로 설계되었기 때문에 FP64 성능이 다시 강조됐는데, Kepler와 Maxwell에서 FP32 성능대비 1/3, 1/32 였던 FP64성능이 Pascal에서는 1/2로 크게 향상됐습니다. 이전 세대와 다른 특징은 FP16에 대한 지원이 추가된 점인데 이는 딥러닝을 고려한 조치로 생각됩니다. P100 GPU White Paper에 따르면 nVidia는 16-bit 부동소수점(FP16) 연산이 딥러닝의 training과 inferencing에 최적이라고 생각하는 것 같습니다. FP16연산을 사용하면 딥러닝의 Weight Matrix 저장에 필요한 공간을 FP32연산을 사용할 때에 비해 반으로 줄일 수 있는 장점이 있어 메모리 용량과 대역폭에 대한 부담이 줄어듭니다. 또한 GP100 Pascal에 채용된 CUDA 코어는 FP16 연산을 처리할 때 한 싸이클에 두 명령어를 처리할 수 있기 때문에 FP16연산 성능은 FP32 연산 성능의 두 배가되어 계산 속도면에서도 장점이 있습니다.

Volta 아키텍처

Volta는 아키텍처를 훓어보기 전에 언급하고 넘어가고 싶은 부분이 있는데 Volta 아키텍처를 채택한 첫 GPU인 GV100은 TSMC의 12nm FinFET 공정으로 구현되었으며 엄청난 수(211억)의 트랜지스터를 탑재하고 있다는 점 입니다. 2017년 GTC의 키노트 발표를 보면 nVidia의 CEO Jenson Huang이 Volta 아키텍처를 소개할 때 자랑스럽게 GV100 GPU를 들어보이면서 현재의 기술로 만들 수 있는 가장 큰 실리콘 칩이라고 말합니다. GV100 칩의 면적은 815mm2로 가장 미세한 공정을 사용했지만 지금까지 nVidia가 만들었던 어떤 GPU 보다도 큽니다.

Volta GV100 GPU를 소개하는 Jenson Huang (출처 – 유튜브 영상, “GTC 2017: NVIDIA Announces Tesla V100 (NVIDIA keynote part 6)” )

Volta 아키텍처의 가장 큰 특징은 Tensor 코어의 탑재인데 이름에서 짐작할 수 있듯이 딥러닝가속을 위해 특별히 제작된 코어 입니다. 아래 그림과 같이 Tensor 코어는 16-bit 부동소수점으로 이루어진 4×4 매트릭스 A와 B를 곱한 결과를 32-bit 부동소수점으로 이루어진 매트릭스 C에 더하여 32-bit 부동소수점으로 이루어진 매트릭스 D를 계산하는 동작을(D(FP32) = A(FP16)*B(FP16) + C(FP32)) Pascal에 비해 12배 높은 throughput으로 처리할 수 있다고 합니다. 딥러닝에서 Neural Network의 각 layer의 입력과 layer 노드들 사이의 weight를 이용하여 다음 layer로의 출력을 계산할 경우 매트릭스 연산이 사용되기 때문에 이를 가속하기위한 전용코어를 탑재하는 것은 커다란 도움이 됩니다. 개인적으로는 Tensor 코어를 사용하는 명령어(instruction) 포맷에서 source와 target operand들을 어떻게 정의할지가 궁금합니다.

Volta 아키텍처의 Tensor Core (출처 – 유튜브 영상, “GTC 2017: NVIDIA Announces Tesla V100 (NVIDIA keynote part 6)” )

아래 그림은 Volta 아키텍처의 SM 구조를 나타내고 있는데 기존의 CUDA 코어는 FP32 코어로 이름이 바뀌고 FP32 코어와 동일한 수의 정수연산(INT) 코어가 추가된 부분이 눈에 띄는데 아마도 딥러닝의 inferencing 가속을 위한 것으로 추정됩니다. 구글의 1세대 TPU의 경우 inferencing을 위해 8-bit/16-bit 정수 곱셈을 동시에 대량으로 할 수 있는 multiplier array를 탑재했었고, nVidia도 Pascal 아키텍처를 기반으로 CUDA 코어에 4번의 8-bit 정수연산을 한 클럭 싸이클에 동시 수행하는 기능을 구현하여 (관련 링크) inferencing에 특화된 GPU를 출시하기도 했습니다. Volta에 탑재된 INT 코어가 한 싸이클에 몇 개의 정수연산을 동시에 할 수 있는지는 아직 정보가 공개되지 않았습니다.

Volta 아키텍처의 Streaming Multiprocessor 구조 (출처 – http://www.anandtech.com/show/11367/nvidia-volta-unveiled-gv100-gpu-and-tesla-v100-accelerator-announced)

FP64 코어의 경우 Pascal 아키텍처와 동일하게 FP32 코어의 절반이 탑재되어 있으며 Warp Scheduler마다 2개의 Tensor 코어가 짝을 이루고 있습니다. Pascal과 비교하면 Warp Scheduler 하나당 짝지어진 FP32/64 유닛의 갯수가 1/2로 줄었는데 Dispatch Unit의 개수도 1/2로 줄어들었으므로 FP32/64 유닛과의 비율은 Pascal과 동일하게 유지되고 있습니다. Warp Scheduler 하나당 LD&ST 유닛과 SFU의 수는 줄어들었는데 아직은 이유가 확실하지 않습니다. 그 밖에 이전에는 보이지 않던 L0 cache도 등장했는데 여러 상황을 종합해 볼 때 Volta는 단순히 Pascal에 Tensor 코어를 추가한 것이 아니라 그 이외의 부분에도 많은 변경이 있었던 것으로 생각됩니다.

Volta 아키텍처에서 변경된 thread scheduling (출처 – http://www.anandtech.com/show/11367/nvidia-volta-unveiled-gv100-gpu-and-tesla-v100-accelerator-announced)

AnandTech의 Volta 소개글에 따르면 Pascal 까지는 하나의 Warp를 이루고 있는 32개의 thread는 반드시 동시에 진행을 해 했지만 Volta 부터는 아래와 같이 하나의 Warp를 이루더라도 32개의 thread가 각각의 PC(Program Counter)를 가지고 독립적으로 진행하는 것이 가능해졌다고 하는데, Warp Scheduler와 짝을이루는 Dispatch Unit의 개수가 줄어든 이유는 이와 관련이 있는 것으로 생각됩니다. Volta에서 각각의 thread가 독립된 PC를 가지도록 변경된 이유는 탑재된 실행 유닛들(FP16/32/64 코어, INT 코어, LD&ST, Tensor 코어, SFU)의 종류가 다양해지면서 각 유닛별 latency 차이때문에 발생하는 비효율을 피하기 위한 것으로 추측이 되는데 이 부분도 추후 자료가 공개되어야 이유를 확실히 알 수 있을 것 같습니다.

마무리

Tesla부터 Volta 까지의 Streaming Multiprocessor(SM) 구조는 아키텍처가 개발되던 상황에 맞춰 계속 진화해왔습니다. GPU의 동작속도가 상대적으로 낮았고 공정상의 제약 때문에 CUDA 코어의 개수를 늘리기 어려웠던 Tesla/Fermi 시절의 GPU는 칩 면적을 아끼기 위해 SM을 두배 빠른 속도로 동작시켜서 원하는 성능을 달성했습니다. Kepler 시절에는 칩 면적보다 전력소모가 문제가되어 SM을 두배 빠른 속도로 동작시키는 대신 CUDA 코어의 개수를 대폭 늘리는 방법으로 성능과 효율성 두 마리의 토끼를 모두 잡았습니다. Maxwell 아키텍처는 Kepler와 동일한 28nm 공정을 계속써야 했기 때문에 Kepler 아키텍처를 철저히 분석한 후 SM하나 당 CUDA 코어의 개수를 최적화하여 효율성과 성능 모두 향상시켰지만 FP64 성능은 퇴보하는 한계가 있었습니다. Pascal은 딥러닝에 대한 지원을 위해 FP16 성능을 FP32 연산에 비해 두배로 늘렸고 Warp Scheduler 하나가 접근할 수 있는 레지스터 파일의 크기도 두배로 늘렸습니다. 가장 최근의 Volta는 딥러닝을 더욱 빠르게 가속하기 위해 4×4 매트릭스 곱셈을 Pascal 보다 12배 빨리 처리할 수 있는 Tensor 코어를 추가하고 Warp Scheduling 또한 개선했습니다.

nVidia GPU 아키텍처는 처음에는 3D 그래픽 가속기로 시작하여 HPC 응용을 고려한 기능들이 들어가다가 결국은 딥러닝과 AI를 가속하는데 중점을 두는 구조로 진화했습니다. 구글의 경우 딥러닝과 관련된 서비스에 대한 요구가 늘면서 TPUTPU2를 제작하여 데이터 센터에서 사용하고 있는데 nVidia의 Volta가 이들을 물리치고 딥러닝/AI 컴퓨팅 시장을 평정할지 아니면 각 데이터 센터마다 구글 처럼 TPU와 같은 커스텀 칩을 만드는 것이 대세가 될지 지켜보는것이 흥미로울 것 같습니다. Volta 아키텍처의 경우 아직 공개된 자료가 별로 없는데 white paper라도 빠른 시일내에 공개되기를 기대해 봅니다.

 

– 2022년 2월 13일 업데이트

다음 글 : nVidia GPU 아키텍처 변천사 (Turing)

 

You may also like...

8 Responses

  1. 김수혁 댓글:

    정리된 글 잘 읽었습니다. 감사합니다.

  2. 이주일 댓글:

    SSM은 무엇의 줄임말인지 알 수 있을까요?

    • 골수공돌이 댓글:

      SSM은 제가 본문에 사용하지 않은 약자라 어떤 문맥에서 사용되었는지 알려주시면 답을 드릴 수 있을 것 같습니다.
      혹시 SMM에 대해 물어보신거라면 SMM은 Streaming Multiprocessor의 약자인 SM에 Maxwell의 앞 문자를 뒤에 붙여 Maxwell 아키텍처에 사용된 SM을 나타내는 단어입니다.

  3. ffff 댓글:

    GP100의 FP16 연산이 FP32 연산하는 CUDA를 이용해서
    Packed 방식(2-Way SIMD)으로 처리하니까 FP32의 2배 성능인건 대충 이해할 수 있었는데요
    GP104의 FP16 연산 성능이 FP32 연산의 1/64인건
    GP100과는 다르게 FP32 유닛의 1/64만큼의 개수를 지닌 ‘FP16 연산 전용 유닛’이 존재하기 때문인가요?

  4. 초록물꼬기 댓글:

    NVIDIA GPU 아키텍처 관련해서 이보다 더 훌륭한 한글 문서를 보지 못하였습니다.
    CUDA 공부 중간중간에 계속 와서 다시 보게 될 것 같네요.
    정리 잘 해주셔서 너무 감사합니다.

  5. 라이푸 댓글:

    지금까지 본 것 중에서 제일 좋은 자료인 것 같습니다. 정말 감사합니다.
    새로 나온 아키텍쳐들에 대해서도 정리된 글을 볼 기회가 있으면 좋겠다는 생각이 듭니다.
    개념을 정리하는데 너무 도움이 됐습니다.
    다시 한 번 감사드립니다.

댓글 남기기