Post

GPU 프로그래밍 - 개요

GPU Programming

1. 개요

이전엔 GPU라고 하면 그래픽 작업이나 게임할때 필요한 부품이었다.
하지만 최근에 AI가 급속도로 발달하면서 GPU의 필요성이 매우 높아지고 있다.

이러한 GPU를 사용하기 위해서는 Python의 Pytorch 나 Tensorflow를 이용하여 코딩할 수도 있겠지만 여기서는 C와 C++을 이용한 코드를 이용하여 프로그램을 만들어보려 한다.

코딩을 해보기에 앞서 GPU에서 구동되는 코드를 알아보려면 먼저 어떤 문제에 대해 GPU를 사용할 수 있고 GPU의 성능은 어떻게 계산할 수 있으며 어떤 종류가 있고, 또 GPU가 어떻게 이루어져있는지 구조부터 알아봐야한다.

2. GPU를 이용할 수 있는 문제

어떤 데이터를 가지고 어떤 문제를 해결하는 방법 대해서 총 4가지로 분류 할 수 있다.

  • SISD (Single Instruction Single Data)
  • SIMD (Single Instruction Multiple Data)
  • MISD (Multiple Instruction Single Data)
  • MIMD (Multiple Instruction Multiple Data)

SISD는 한 개의 데이터에 대한 한 개의 명령이니 전통적인 프로그램이다.
SIMD는 다수의 데이터를 동일한 명령을 통해 처리해야하는 프로그램이다.
MISD는 한 개의 데이터를 다수의 명령어로 처리하는 것으로 한 개의 스트림을 다른 코어들이 처리하는 것으로 생각할 수 있다.
MIMD는 다수의 명령으로 각기 다른 데이터를 처리해야하는 프로그램으로 CPU의 다중 코어를 이용하여 멀티스레드를 하는 것으로 생각할 수 있다.

요컨대 각기 연산에 대해서 다른 연산에 의존성을 갖지 않고 동일한 형태의 연산을 한다면 SIMD 라고 볼수 있는 것이다. 여기서 GPU를 사용하는 문제는 SIMD를 가진 문제라고 할 수 있다. 예를 들어 보자.

  • 그래픽 연산이 대표적인 예시인데, 다수의 픽셀에 대해서 동일한 연산을 하는 것으로 전형적인 SIMD 연산이다.
  • 행렬 연산 역시 SIMD 연산이다. 각각의 원소들이 다른 원소에 대해 의존성을 갖고 있지 않기 때문에 SIMD를 가진 문제로 볼 수 있다.

최근 각광받는 AI 역시 가중치와 편향을 계산할때 대략의 벡터에 대해 부동 소수점 연산이 필요하므로 SIMD를 가진 문제이고 때문에 GPU로 처리할 수 있는 문제인 것이다.

3. GPU 성능 척도

흔히들 GPU 성능을 나타낼때 FLOPS(FLoating point Operations Per Second)라는 단위를 많이 사용한다.
이는 초당 부동소수점 연산을 몇번이나 하는가에 대한 것이다.

관련해서 정보를 찾아보면 FLOPS와 FLOPs 이 두 개에 대해서 나올텐데 이 두 개는 엄연히 다른 지표이다. FLOPs(FLoating point OPerations)는 부동소수점 연산을 뜻하는 것으로 사칙연산을 포함해서 root, log, exponential 등의 연산도 포함하여 1회로 취급한다.
이 FLOPs가 초당 몇번이 가능한지가 FLOPS 되겠다.

4. NVIDIA GPU 종류

가장 일반적으로 많이 사용하는 NVIDIA GPU의 종류를 살펴보겠다.
NVIDIA GPU의 종류를 본다면 뭔가 많다. 일단 아래의 표를 보도록 하자

GenerationCompute CapabilityGeForce(Gaming)Tesla(HPC)Quadro(Workstation)Chipset Codes
Tesla (2007)1.0~1.3GTS 8800C1060FX 5800G80/92/GT200
Fermi (2010)2.0~2.1GTX 480/580C2070Quadro 4000GF100/102/107/110
Kepler (2012)3.0~3.7GTX 680/780K40/K80K4000GK104/110/210
Maxwell (2014)5.0~5.3GTX 980M60/M40M6000GM200/204/206
Pascal (2016)6.0~6.2GTX 1080P100/P40P6000/100GP100/104/106
Volta (2017)7.0~7.2TITAN VV100GV 100GV100
Turing (2018)7.5RTX 2080T4RTX 8000TU102/104/106
Ampere (2020)8.0~8.7RTX 3090A100A6000GA100/102/104/106
Ada (2022)8.9RTX 4090L40/L20RTX 6000 AdaAD102/104/106
Hopper (2022)9.0H100/200GH100

일단은 크게 세 부류로 나뉜다. 게이밍을 위한 Geforce 시리즈, 슈퍼 컴퓨터를 위한 Tesla 시리즈(그래픽 기능이 빠져있다), 수퍼컴퓨터 만큼은 아니지만 더 높은 성능을 가진 워크스테이션을 위한 Quadro이다.
Quadro의 경우에는 엄청 성능의 차이는 크지 않지만 훨씬 안정적이고 bus 대역폭도 크다.

이 세 종류에서 각각의 세대(Generation)마다 별도의 코드명이 붙어있다. 사실 여기서 중요한 건 Compute Capability와 Chipset Codes이다.

Chipset Code는 Nvidia와 AMD의 그래픽 처리 장치(GPU)를 식별하는 데 사용된다 그리고 Compute Capability는 컴퓨터 기능 묶음이라고 볼수 있는데 해당 번호를 지원하면 대상 번호에 속한 모든 기능을 지원하는 형태이다. 실질적인 스펙에 대해서는 아래와 같다.

참고문헌

This post is licensed under CC BY 4.0 by the author.