※ 게임 개발 포에버 http://www.gamedevforever.com 에서 연재 중인 글입니다.

어디다 병렬 프로그래밍을 써야 할까?
앞서 포스팅에서 OpenMP, TBB, PPL 등 유용한 라이브러리를 통해 병렬 프로그래밍을 보다 손쉽게 ( 그래도 힘들지만 ) 사용할수 있다는 것을 알았습니다. 이제 나도 병렬 프로그래밍을 써먹어 볼수 있겠다는 부푼 꿈을 안고 코딩을 시작합니다. 그런데... 그런데... 대체 어디다 적용하지...?
 

막상 병렬 처리를 적용하려니...

병렬 처리를 하기 위해서는 말그대로 병렬성이 있는 곳. 쉽게 말해 동시성을 찾아내야합니다. 그냥 아무곳에나 병렬 처리를 적용 할수 없는 겁니다. 그럼 게임 로직에서 병렬화를 할수 있는 부분은 어떤게 있을까요? 일단 기본적인 게임 로직 흐름도를 살펴보겠습니다.

기본 적인 흐름도

게임 프로그래밍을 조금이라도 하신 분이라면 굉장히 친숙한 흐름도 일겁니다. 사용자의 입력을 받아, 현 상태를 업데이트 하고, 업데이트한 정보를 토대로 그려냅니다. 여기서 병렬화가 가능 한 곳을 한번 찾아볼까요? 처음 입력 부분을 병렬 처리로 하면 어떨까요? 키보드, 마우스, 조이패드 등등을 동시 입력하는 경우가 많으니 이 입력 장치들을 병렬로 처리 하는 겁니다. 여러 입력 장치에서 입력된 정보를 멀티 코어를 이용해 동시에 파파파파팍!!! 처리 하면... 네 별 효용이 없겠죠. 이미 입력 장치는 병렬 처리 같은거 안하더라도 키나 버튼 입력 상태를 한번에 조사가 가능합니다.

이런 쓸데없는 짓은 하지 맙시다.

다음으로 로직/씬 업데이트 부분은 어떨까요? 이곳은 왠지 병렬화 할수 있는 곳이 많을것 같습니다. 게임에 등장하는 각종 오브젝트며, 효과들 처리가 굉장히 많죠. 또한 게임 실행에 있어 가장 많은 시간을 할애 하는 곳 중 하나 이기도 합니다. 보통 게임 오브젝트를 업데이트 할때 씬그래프라는 트리 구조 형태를 따라 순차적으로 업데이트 할때가 많습니다. 이 것을 병렬로 처리 한다면 왠지 빠를거 같지 않나요? 일단 병렬 처리 후보로 생각해봅니다.


위 그림 처럼 트리 형태의 구조를 밑 그림의 형태와 같이 병렬화를 한다면 어떨까?


다음으로 렌더 부분을 살펴보겠습니다. 보통 업데이트가 끝난 오브젝트들을 화면에 순차적으로 그려 내는 부분입니다. 여기서 각 스레드에 여러 오브젝트를 할당해서 각자 맡은 바를 그리게 할 수 있다면 어떨까요? 동시에 여러 오브젝트들을 그려낼수 있으니 한 화면에 많은 오브젝트들이 등장하는 상황이라면 굉장히 유용할 듯 해보입니다. 하지만 이 부분은 생각처럼 쉽지 않습니다. 비동기적으로 오브젝트들을 그리게 된다면 그리는 순서가 뒤죽박죽 될때고 디바이스 점유 문제도 있습니다. 그래도 답이 없는 것은 아닙니다. 최근 DX11 같은 경우 멀티스레드 환경에서 렌더링을 할수 있는 방법을 제공해주고 있죠.

MS사가 그냥 놀고만 있는 것은 아닙니다.

다른 곳도 찾아보자
위 처럼 각 로직 부분에서 병렬화가 가능 곳을 찾는 것외에도 각 로직 부분 자체를 병렬화 하는 것도 생각해볼만 합니다. 전체적인 게임 실행 흐름도를  다시 봐주세요. 입력을 받고 -> 업데이트 하고 -> (업데이트 내용을 기반으로 애니/물리 연산 ) -> 그린다. 이 흐름을 순차적인 아닌 병렬로 처리하면 어떨까요?



위의 흐름도를 보시면 각 스레드별로 특정 작업을 할당 하고 있습니다. 1번 스레드는 게임 로직을, 2번 스레드는 업데이트된 정보를 기반으로 애니메이션 및 물리 연산을 ,그리고 3번 스레드에서는 최종 계산된 정보를 바탕으로 오브젝트를 그려냅니다.

이 외에 다른 곳에서도 병렬화를 통해 멀티코어 CPU를 활용할수 있습니다. 대표적으로 파티클 시스템이 있습니다. 파티클의 경우 데이터 의존성 문제도 크지 않고, 쉽게 병렬화를 할 수 있는 부분 중 하나입니다. 많은 상용 게임 중에서도 파티클 시스템을 병렬화한 경우를 심심치 않게 볼 수 있습니다.

밸브사의 소스 엔진 파티클 시스템

이뿐만이 아닙니다. 후처리 기법 중 하나인 MLAA (Morphological Anti-Aliasing)를 CPU 단에서 병렬화를 통해 빠른 AA 연산을 할수 있도록 하는 방법도 나와있습니다. 보통 AA 연산은 GPU를 통해 이루어지는데 GPU의 부담을 덜어주고, CPU의 멀티코어를 활용해 보다 빠른 AA 연산을 수행 하는 것이지요.

CPU Based MLAA의 성능 지표. GPU에서 지원하는 MSAA 보다 빠르다!!!

CPU 놀지말고 일해!! 찰싹~ 찰싹~
암달의 법칙을 보면 아무리 병렬화를 통해 속도 업을 꾀하더라도 게임의 수행 속도가 몇배가 되지는 않습니다. 어쩌면 들이는 공에 비해 결과물이 그닥 일수도 있습니다. 하지만 그렇다고 CPU를 놀리는 것도 안타깝죠. 그렇기에 멀티 코어를 이용한 다양한 방법들이 연구되고 있습니다. 위의 CPU Based MLAA 같은 것들이 대표적인 예죠. 최근에는 DOD를 이용해 CPU 활용을 극대화 시키는 방법도 많이 연구되고 있습니다( 맥좀비님의 DOD 포스팅 기대 중. 맥좀비님이 다 해결해주실거야~ )

CPU가 놀고 있으면 썰어주자

대략 멀티코어를 활용할 수 있는 방법들을 훓어 보았으니 다음 강에는 좀더 디테일 하게 파볼 수 있으면 파보겠습니다.
고...
 

너무 마구잡이로 써대서 글이 산만해도 이해해주시기 바랍니다.
오류나 다른 의견 있으신 분은 덧글 남겨주세요. 수정/보완 하도록 하겠습니다.
제목이 병맛 프로그램으로 보이는 건 기분탓이 아닙니다.


+ Recent posts