본문 바로가기

웹 개발/Frontend

Naver FE News 2024-01) What Every Developer Should Know About GPU Computing: GPU의 작동원리와 배경지식

Naver FE News

원문

 

What Every Developer Should Know About GPU Computing

A primer on GPU architecture and computing

codeconfessions.substack.com

대부분의 개발자는 CPU 용 코드를 작성하면서 자랐기 때문에 CPU와 순차적 프로그래밍에 대해 잘 알고 있지만, GPU의 내부 작동 방식과 그 특별한 기능에 대해서는 잘 모르는 경우가 많다. 지난 10년 동안 GPU는 딥 러닝에 널리 사용되면서 그 중요성이 엄청나게 커졌다. 이 글은 GPU의 작동 원리에 대한 배경지식에 대해 소개한다.

 


 

CPU vs GPU

CPU와 GPU의 주요 차이점에 대해 소개한다. 

첫번재 차이점, 설계 목표 

CPU의 설계 목적은 순차적 명령을 실행하는 것이다. 이 성능을 향상시키기 위해 CPU의 많은 특징들이 지난 몇년간 설계되어 왔고, 여기서 중요한 것은 명령 실행 지연시간(instruction execution latency)을 감소시켜 CPU가 가능한 빨리 명령들을 순차적으로 실행할 수 있도록 하는 것이다. 따라서 파이프라이닝, 순서를 바꾼 실행, 멀티 레벨 캐시 등의 특징이 등장하게 된다.

GPU는 중~상 정도의 지연시간을 들여 엄청난 수준의 병렬화와 높은 처리량을 위해 설계되었다. 이러한 방향성은 비디오 게임, 그래픽, 딥러닝 등에 활용되는 것에 영향을 받았다. 이러한 어플리케이션들은 매우 빠른 속도로 수 톤의 선형 대수 및 수치 계산을 해야하기 때문에 디바이스들의 처리량을 향상시키는 데 많은 관심을 기울였다.

 

예시

CPU는 명령 지연시간이 매우 짧기 때문에 GPU보다 빠르게 두 수의 덧셈을 처리할 수 있다. 하지만 이보다 훨씬 더 복잡한 연산을 하게 된다면 GPU는 엄청난 병렬성으로 인해 CPU보다 훨씬 빠르게 처리할 수 있다. 

  • FLOPS (floating point operations): 1초에 몇 번의 부동 소수점 작업을 수행할 수 있는지 나타내는 지표  

Nvidia Ampere A100 TFLOPS (GPU): 19.5

Intel 24-core processor TFLOPS (CPU): 0.66

 

이 수치는 2021 기준이며 매년 무서운 속도로 그 차이가 더 커지고 있다. 

 

CPU 아키텍쳐를 보면, CPU는 커다란 캐시, 적은 ALU, 많은 컨트롤 유닛 등 명령 지연시간을 줄이기 위한 특징으로 설계되어 있다.

반면에 GPU는 ALU를 많이 가지고 있어 계산과 처리량을 극대화하도록 설계되었다.

 

지연 허용과 높은 처리량

고효율적인 GPU의 성능은 어떻게 높은 지연을 허용하면서도 가능한 것일까? 이는 GPU가 보유한 대량의 스레드와 엄청난 컴퓨팅 파워 덕분이다. 개별 명령이 지연 시간이 길어도 GPU는 스레드를 효과적으로 스케줄링하여 GPU의 계산 유닛이 항상 최대 용량으로 작동하도록 하여 높은 처리량을 유지할 수 있다. 

 

GPU 아키텍처

GPU는 스트리밍 멀티프로세스(SM) 배열로 구성된다. 각 SM들은 여러 개의 streaming processor 또는 코어 또는 스레드로 구성된다. 

ex) Nvidia H100 GPU: (SM-64개의 코어) x 132 = 총 8448개의 코어를 가지고 있다.

 

각 SM은 제한된 양의 on-chip 메모리(=공유 메모리=스크래치패드)를 가지고 있다. 이 메모리와 제어 유닛들은 모든 코어에서 공유된다. 또한, 각 SM은 스레드를 실행하는 데 사용되는 하드웨어 기반의 스레드 스케줄러를 가지고 있으며, 특정 워크로드에 필요한 계산을 처리하기 위한 텐서 코어나 광선 추적 유닛과 같은 다양한 기능 유닛이나 가속화된 계산 유닛을 가지고 있다. 

 

GPU 메모리 아키텍처

 

GPU는 몇 가지 다른 종류의 메모리 계층을 가지고 있다. 

 

Register

각 SM에 많은 레지스터가 있다. 

ex) Nvidia A100 및 H100 모델: SM 당 65,536개의 레지스터

레지스터들은 코어 간 공유되며 스레드의 요청에 따라 동적으로 할당된다. 실행 중에 스레드에 할당된 레지스터는 해당 스레드에게만 개인적으로 사용되며 다른 스레드에서는 해당 레지스터를 읽거나 쓸 수 없다.

Constant caches

칩 위에 상수 캐시가 있다. SM에서 실행 중인 코드에서 사용되는 상수 데이터를 캐시하는데 사용된다. 코드에서 객체를 명시적으로 상수로 선언하면 GPU는 그 객체를 상수 캐시에 저장한다.

Shared memory

각 SM은 공유 메모리(스크래치패드)를 가지고 있다. 이는 소량의 고속 및 저지연 on-chip 프로그래밍이 가능한 SRAM 메모리이다. 이것은 SM에서 실행 중인 스레드 블록에 의해 공유된다. 공유 메모리는 여러 스레드가 동일한 데이터를 처리해야 할 경우 해당 데이터를 전역 메모리에서 한 번만 로드하고 나머지 스레드에서 공유하여 중복된 로드 작업을 줄일 수 있게 한다. 이것을 잘 사용할면 전역 메모리에서 중복 로드 작업을 줄인다. 

L1 cache

L2 캐시에서 자주 접근되는 데이터를 캐싱

L2 cache

전역 메모리에서 자주 접근되는 데이터를 캐싱

(SM은 데이터를 L1, L2에서 가져오는 것을 알 수는 없다.)

 

Global memory

고용량, 고대역폭 DRAM으로 구성된 off-chip 메모리 

ex) Nvidia A100 및 H100 모델: 대역폭이 3000 GB/초인 80 GB

SM에서 멀리 떨어져 있기 때문에 지연시간이 크지만 L1, L2 캐시 등의 추가 레이어와 계산 유닛을 사용하여 이 지연 시간을 줄일 수 있다.