오늘은 GPU의 원리를 알아보자
일단 GPU란 컴퓨터 그래픽을 처리하는 장치로, 그래픽 카드를 구성하는 핵심 부품이다
GPU는 CPU와 비슷하게 작동하는데 대신 그 성능이 다르다
내용의 출저는 이 영상에 있다
https://www.youtube.com/watch?v=ZdITviTD3VM
상세
여기 초등학생 100명과 박사 1명이 있다
간단한 덧셈 문제 100문제를 초등학생한테 각각 1문제 씩 배분하고 박사한테는 100개의 덧셈 문제를 준다면 누가 더 빨리 풀까? 당연히 초등학생이 더 빨리 풀 것이다 감이 잡힌다면 초등학생 100명은 GPU에 비유한 것이고 박사는 CPU에 비유한 것이다 반대로 복잡한 인수분해 1문제를 준다면 초등학생 100명과 박사 중 누가 더 빨리 풀까?
당연히 박사 쪽이 더 빨리 풀 것이다 이 처럼 CPU는 복잡한 데이터를 빠르게 풀게 할 수 있게 설계 되었고
GPU는 데어터 처리량 쪽으로 특화되어 있다 비유적으로 질은 CPU, 양은 GPU 라는 것이다
그럼 우리가 간단히 GPU의 데이터 처리량을 영상으로 짐작해 보자
우린 영상이나 사진을 디지털 기기로 볼때 많은 점이 rgb로 이루어져 있는데 그 점을 픽셀이라고 한다

그리고 우리가 보는 한 픽셀의 크기는 rgb로 16비트 형식이다 (R=255,G=242,B=100)
ex): #f231da(R=f2,G=31,B=da)
그럼 한 픽셀은 8*3비트(3byte)가 된다는 것이다
우리가 보는 영상은 보통 해상도는 1920*1080이다 그리고 초당 프레임을 아무리 낮게 잡아도 30이라 하자
그럼 1920*1080*30= 62,208,000pixel = 186,624,000 byte = 178MB 라는 정신 나간 데이터 처리량을 보여준다
게다가 이 데이터를 초당 처리해야 하는 데이터 이므로 1 프레임을 처리 할 때 드는 시간은 아무리 늦어도 0.016초 안에 처리 해야하는 정신 나간 사양을 요구한다 이걸 소화 하는 것이 요즘 GPU라는 것이다
작동방식
CPU에는 고성능 프로세서가 몇 개 정도 들어 있지만 GPU에는 저성능 프로세서가 몇 천개나 있다 그 이유는 알다 싶이 복잡한 데이터 보다는 많은 데이터를 많이 처리해야 하기 때문이다 픽셀의 정보는 CPU가 계산 할 수 있지만
그건 박사한테 초딩 문제 100문제나 주는 일이나 다름 없는 말이기 때문에 효율적이지 않다
GPU의 작동방식을 알아보기 위해선 3D 그래픽이 어떻게 표현되는지 알 필요가 있다
3차원 모델은 보통 점 선 면으로 이루어져 있다

점과 점을 연결하면 선이 되고 선과 연결된 공간을 칠하면 면이 된다
그리고 도형의 구성 중 제일 중요한 점은 정점이라 부른다
이런 정점들을 서로 연결해서 만든 3차원 모델을 폴리곤메쉬라고 한다

이 처럼 점과 선을 이으면 폴리곤메쉬로 표현 할 수 있다
보통 폴리곤은 유연한 다각형인 삼각형을 주로 이용하며 대부분 게임 캐릭터가 이 삼각형으로 이루어져 있다 보면 된다
그리고 이 정점에는 위치를 표시 할 수 있는 좌표값(X,Y,Z)를 가지고 있다

그렇다면 정점들이 누가 어디에 있는 3D로 알 수 있다
이 점들을 이용해서 3차원 모델을 표현하기 위해서 각 점들에 수직 방향으로 표현하는 노말이라는 정보도 필요하게 된다

기본적으론 3차원 모델의 바깥쪽으로 노말 값을 표현 한다
그 외에도 이미지의 색상을 표시하기 위해 texture coordinate의 값도 알아야 한다

그리고 이 정점 데이터를 GPU입력하면 입력받은 정보에 대해 연산을 수행하게 된다
정점 데이터 입력 -> 정점연산 -> 삼각형 생성 -> 조각화 -> 픽셀화(색상) -> 이미지 화(명암)

이 사진은 삼각형 생성 뒤, 조각화를 한 과정이다
이 조각화 과정은 정점 데이터의 노말 데이터의 평균 값으로 픽셀들이 어느 방향으로 보게 할 지 정하게 한다
그리고 픽셀화 과정에선 각 픽셀의 색상을 입히게 한다

이는 픽셀화를 간단하게 표현한 사진이다
이제 이 픽셀화된 데이터를 명암을 씌어 밝기를 정한다 그리고 그 과정 중에 정점 데이터를 계산하여
앞에 있는 정점 데이터는 가려내게 된다 그러니까 데이터 앞을 뒤의 데이터를 가리는 과정을 고려하여 픽셀을 잘라낸다

그리고 최종적으로 이미지화가 끝나면 이제 화면으로 출력하게 되는 것이다
한 정점 데이터에는 위치값, 노말, 깊이 등 많은 정보들이 저장되어 있다
게다가 3차원 모델은 계속해서 움직인다 그래서 GPU도 계속 변하는 정점 데이터를 계속해서 계산해야 한다
그리고 이러한 연산은 행렬의 곱셈 형태로 진행 된다

수십만개의 정점 데이터를 행렬의 곱셈으로 실시간 계산해 주어 모니터에 뿌릴 픽셀을 계산하는 것이
GPU가 하는 일이다

예시로 왼쪽에 있는 코드는 한 픽셀을 처리하는 코드며, 왼쪽은 그 코드를 기계어로 컴파일하여
1개의 프래그먼트는 이 명령에 의해 ALU(산술논리장치)에서 처리 된다
그렇다면 코어의 개수를 늘린다면 여러개의 프래그먼트가 동시에 계산할 수 있다
코어에 들어있는 ALU의 개수를 늘린다면 한 번의 명령으로 8개의 프래그먼트의 계산이 가능하다
이렇게 하나의 명령어로 여러개의 데이터를 얻어내는 방식을
(Single Instruction Multiple Data)
SIMD
라고 한다 코어가 많고 그 코어 안에 ALU가 많을수록 더 많은 프래그먼트가 한번에 계산 된다
프래그먼트 뿐만 아니라 픽셀을 만들기 위한 모든 정보들이 이런 방식으로 처리 된다
픽셀은 순차적으로 계산 되는 것이 아닌 픽셀 각각으로 하나 씩 ALU에서 독립적으로 계산 된다
옆에 있는 픽셀 값이 계산되길 기다렸다가 다음 픽셀이 계산 되는 방식이 아닌 여러개의 ALU에서 픽셀 하나 하나가
따로 연산 된다는 의미다
단점
GPU는 순차적인 연산에는 약한 편이다
예시적으로
1: A+B=C
2: C+3=X
일때 2번의 X값을 알기 위해 C의 값을 알아야 하는데 하나의 코어에서 1번 식이 계산 되는 동안 2번 식을 계산 할 수 없다
그렇다고 다른 ALU에서 독립적으로 계산할 수 도 없기에 1번 식이 끝날 때 까지 2번이 연산 할 수 없다는 단점이 있다
그럼 나머지 ALU은 놀게 되고 효율이 떨어지게 된다
그렇기에 대량의 독립 데이터를 GPU을 계산할 때 매우 유리하다 할 수 있다
------------------------------------------------------------------------------------------------------------------
그렇기에 GPU는 대량의 데이터를 더욱 많이 처리하고 싶은 생각이 있지만
GPU는 그래픽 처리를 목적으로 만들어졌기 때문에 데이터 형식을 그래픽이 처리되는 형태로 바꿔줘야 하는 번거로움이 있다
많은 데이터를 행렬의 곱셈 방식으로 처리하는 것은 일반적인 계산에는 적합하지 않을 때가 많다
그래서 이런 불편함을 개선하고자 OpenCL과 CUDA를 개발했다
CUDA는 Nvidia 사에서 제공하는 GPU프로그램이다
이번엔 CUDA코어와 프로그램 데이터를 처리하는 방식에 대해서 알아보자
| 작업1 |
| 작업2 |
| .. |
| .. |
| 작업 100 |
여기 처리해야 할 100개의 작업이 있다
코어가 처리해야 할 하나의 작업을 스레드라고 한다면 서로 독립적인 100개의 스레드를 처리 할 가장 이상적인 방법은
100개의 코어에 각각 하나 씩 할당하는 SIMD방법이다
하지만 GPU가 처리할 스레드는 100개는 절대 아닐 것이다 매우 많은 스레드를 처리해야 할 것이다
100만개의 스레드가 있다면 SIMD 방식으로 코어 하나하나에 배분하기엔 코어가 턱 없이 부족할 것이다
현재 GPU에 들어 있는 코어의 개수는 몇 천 개가 전부다
그래서 GPU는 새로운 스레드 처리 방식인 SIMT(Single Instruction Multiple Threading)
이 방식은 스레드 중심의 처리 방식이라고 한다
100만개의 스레드를 천개의 코어에서 계산한다 친다면
1000개의 스레드를 한 묶음으로 묶어 1000개 묶음으로 만들고 1000개의 코어를 100개씩 묶는다면

1000개씩 묶은 스레드를 또 100개 씩 warp라고 하는 그룹으로 나누어 1코어 씩 또 분배한다면 1:1로 한 스레드를 한 코어가 연산 할 수 있는 효율 적인 분배가 가능하다
지연시간
코어가 스레드를 실행하는 동안 위의 예시 처럼 지연시간이라는 것이 발생한다면 그 지연시간 동안 다른 연산을 하기에는
시간이 넉넉하지 않다 그렇기에 스레드 그룹1를 연산하다 지연시간이 발생한다면 다음 스레드 그룹2을 연산한다 또 지연 시간이 발생한다면 그 지연시간 동안 다른 스레드 그룹이 연산을 하듯 시간을 효율적으로 사용한다
그렇기에 지연시간을 없게 하려면 그만큼 스레드가 많아야 효율이 좋아진다
----------------------------------------------------------------------------------------------------------------------------------------------------------------
이와 같은 방식으로 GPU는 대량의 데이터를 병렬 처리하는데 있어 효율이 좋아 진다
마지막으로 GPU의 사용 예시로는 날씨 예보에 사용되는 컴퓨터는 물이나 공기 같은 유체의 흐름을 계산해야하기 때문에
격자로 나누어 날씨 변화를 계산해야 한다 격자를 더 더욱 나눈다 병렬도는 증가해서 더 많은 스레드를 이용한 병렬 계산을 할 수 있다

그렇다면 GPU의 원리를 알아 봤다
끝!
'컴퓨터' 카테고리의 다른 글
| [NOOBHACK] C언어에서 기계어 변환 과정 (0) | 2023.09.13 |
|---|---|
| [NOOBHACK] GDB를 통한 언더플로우 관찰 (0) | 2023.09.13 |
| [NOOBHACK] CPU의 작동 원리 (1) | 2022.10.17 |