게임 이론: CPU와 GPU (2)
1. GPU
GPU는 게임의 상황을 그림으로 나타내는 처리를 맡아서 실행합니다. 그림을 그릴 때 GPU 역시 메모리를 참조하며 진행합니다. 하지만 GPU는 프로그램을 참조하지 않고 그림을 그려야하는 방법이 기록되어 있는 설계도를 참조합니다. 이 설계도를 그리기 명령이라고 합니다.
그리기 명령에는 '폴리곤을 그린다', '그리기를 종료한다'와 같은 조건들이 연속적으로 기재되어 있습니다.
GPU는 디스플레이에 그림을 그리지 않고 메모리의 임의 장소에 공간을 확보해 그림을 그립니다. 이 메모리 공간을 프레임 버퍼라고 합니다.
GPU는 CPU와 병렬로 처리를 수행할 수 있습니다. 즉, CPU가 게임 처리를 하고 있을 때 GPU는 그림을 그릴 수 있습니다.
GPU는 프레임마다 그리기 명령을 참조합니다. 60fps라면 1초에 60장, 30fps라면 1초에 30장을 찍어냅니다.
2. 더블 버퍼
만약 그림을 그리는 버퍼가 1장 있다면 버퍼가 디스플레이에 표시될 때 GPU가 변경하게 된다면 다른 그림이 화면 아래에 반 정도 남아있을 가능성이 있습니다.
디스플레이는 수직동기 1회의 시간 동안 화면 왼쪽 위에서 오른쪽 아래를 향해 표시합니다. 그러나 한 개의 프레임은 수직동기 1회의 시간 내에 처리를 진행합니다. 때문에 수직동기 중에 버퍼가 변경된다면 화면의 표시내용이 바뀌게 됩니다.
그래서 일반적으로 2장의 버퍼, 즉 더블 버퍼를 준비해 처리를 진행합니다. 표시 처리는 기본적으로 다음 과정을 거칩니다.
- 프레임 버퍼1을 표시하는 동안 GPU가 버퍼2에 그림을 표시합니다.
- 수직동기를 기다립니다.
- 프레임 버퍼2를 표시하는 동안 GPU가 버퍼1에 그림을 표시합니다.
3. GPU에 관한 처리과정
메인 루프의 시작은 제어기의 정보를 얻는 것으로 시작해야 합니다. 그러나 가장 먼저 시작되는 처리는 디스플레이에 표시되는 프레임 버퍼를 선택하는 것입니다. 제어기 처리는 이 후에 하는 것이 좋습니다. 그 뒤에는 게임 처리를 실행하고 그 뒤에는 그것에 따라 변경되는 화면을 처리할 그리기 명령을 넣습니다.
CPU가 GPU에 그리기 명령을 참조해 실제로 그림을 표현하도록 하는 것을 렌더링이라고 합니다. GPU는 그리기 명령을 받자마자 현재 디스플레이에 표시되지 않은 다른 버퍼에 렌더링을 실시합니다. 그런 후 다음 수직동기에서 표시하도록 합니다.
하지만 그리기 명령을 실행하는 데 있어 시간이 걸려 수직동기 시간을 놓치는 경우도 있습니다. 여기서 한번 생각을 해보자면 GPU의 프레임 시작 부분이 비어있어 시간이 낭비되고 있는 것을 알 수 있습니다.
4. 스레드
게임 중에서는 실행 중에 다른 처리를 추가해야 할 때가 생깁니다. 예를 들어 게임 처리와 사운드 처리가 있습니다. 게임 처리와 사운드 처리를 실현하는 데 있어 다른 처리를 추가하는 기능을 가진 CPU는 게임 처리, 사운드 처리를 2개의 경로로 처리하게 됩니다. 이러한 처리를 스레드라고 합니다.
CPU가 GPU에 그리기 명령을 참조해 실제로 그림을 표현하도록 하는 것을 렌더링이라고 합니다. GPU는 그리기 명령을 받자마자 현재 디스플레이에 표시되지 않은 다른 버퍼에 렌더링을 실시합니다. 그런 후 다음 수직동기에서 표시하도록 합니다.
하지만 그리기 명령을 실행하는 데 있어 시간이 걸려 수직동기 시간을 놓치는 경우도 있습니다. 여기서 한번 생각을 해보자면 GPU의 프레임 시작 부분이 비어있어 시간이 낭비되고 있는 것을 알 수 있습니다.
그래서 CPU에서 시작 프레임에 그리기 명령을 저장하고 다음 프레임에서 GPU가 렌더링을 하는 방식으로 게임을 표시합니다.
4. 스레드
게임 중에서는 실행 중에 다른 처리를 추가해야 할 때가 생깁니다. 예를 들어 게임 처리와 사운드 처리가 있습니다. 게임 처리와 사운드 처리를 실현하는 데 있어 다른 처리를 추가하는 기능을 가진 CPU는 게임 처리, 사운드 처리를 2개의 경로로 처리하게 됩니다. 이러한 처리를 스레드라고 합니다.
그림에서는 게임 메인 처리 스레드와 사운드 처리 스레드 2개로 표시되어 있습니다. 각각의 스레드는 우선순위를 가질 수 있습니다. 위에서는 사운드 처리 스레드가 게임 처리 스레드보다 더 높은 우선순위를 가지고 있습니다. 스레드의 처리가 끝났을 때는 '더 이상 처리가 없다'는 것을 명시하고 그 전 스레드로 돌아가야 합니다.
처리 경로가 2개더라도 CPU가 2개를 동시에 실행하는 것은 아닙니다. 그러므로 게임 처리에 사운드 처리를 조합하는 방식을 스레드를 이용하는 것이 훌륭한 조합이라고 할 수 있겠습니다.
5. 멀티코어
CPU 내부에는 실제 처리를 실행하는 코어라고 불리는 부분이 있습니다. 이것을 2개 이상으로 갖춘 것을 멀티코어라고 부릅니다. 이는 처리를 병렬로 실행할 수 있다는 의미이기도 합니다.
병렬로 처리하는 스레드는 게임 플레이에 지장을 주지 않는 처리입니다. 예를 들어 플레이어 처리와 적 처리를 병렬로 동시에 처리한다고 하면 적이 플레이어의 움직임을 모르기 때문에 게임 플레이에 지장을 줍니다. 하지만 게임 캐릭터의 머리카락 날리는 애니메이션은 게임 플레이에 영향을 주지 않습니다. 이럴 때 다른 코어까지 이용해서 처리를 하게 됩니다.
처리를 분산시킬 때는 주의해야 할 점이 있습니다. 각각의 코어가 같은 메모리 영역을 갱신할 가능성입니다. 이럴 때는 어떤 한 코어가 갱신이 끝나는 것을 기다려야 합니다. 그렇지 않으면 예기치 못한 사태가 발생할 수 있습니다.
댓글
댓글 쓰기