휴일에 읽는 멀티코어 테크니컬 아티클 시리즈

멀티 쓰레드 프로그래밍의 기본적인 개념을 가지고 있다는 전제하에 순서대로 읽어면서 멀티코어를 게임 엔진에 적용하기 위해 필요한 기본적인 개념과 접근 방법, 그리고 전략을 정리하기 좋은 몇 가지 글들. (연관된 글들을 함께 읽으면 이해가 빠르죠~)

첫 번째로 "Multithreaded Game Programming and Hyper-Threading Technology".(Will Damon) 본문의 내용중에서 decouple이라는 단어에 주목하자. 멀티코어 환경하에서는 시스템간에 상호 의존성을 최대한 배제할 수 있도록 (쓰레드로 분리할)시스템을 설계해야 한다.

다음으로는 "Threading Basics for Games". (Jaff Andrews) 멀티 쓰레딩의 두 가지 방식인 데이터 병렬 처리와 함수 병렬 처리 방식 중에서 함수 병렬 처리에 대한 내용에 초점을 맞추어 설명을 하고 있다.

마지막으로 Gamasutra에 올라 온 조금 오래된 글로 "Threading 3D Game Engine Basics"( Henry Gabb & Adam Lake)에도 볼만한 내용들이 있다. 특히 암달의 법칙과 Granularity 섹션의 내용은 눈여겨 볼만하다. Granularity의 내용은 Threading Basics for Games의 Figure 1의 그림을 생각하면서 읽으면 훨씬 더 이해하기가 쉽다.


...Nebula3의 멀티코어 아키텍쳐를 이해하고자 하는 분들에게도 일독을 권합니다. Advanced 한 글들은 추후에 또 모아서 포스팅하겠습니다.

by kimsama | 2009/05/04 14:48 | MultiCore | 트랙백 | 덧글(0)

팀 스위니 CEDEC 2008에 대한 소고

http://blog.naver.com/saebaryo/30035653812 으로부터 트랙백

작년 CEDEC에서의 팀 스위니의 강연 내용을 잘 번역해 놓은 글이 있어 소개합니다. (작년에 네이버 재팬의 번역기로 본 내용이지만 새로 깔끔하게 번역해서 올라와서 소개할 겸 몇자 덧붙여 트랙백도 함께 보냅니다.)

강연 내용을 본 대부분의 사람들이 이야기했던 충격적인 내용은 소프트웨어 렌더러로의 회귀였고 (본문 내용에는 자세하게 나와 있지는 않습니다만 회귀가 DX와 같은 하드웨어 가속 플랫폼 레이어의 사멸을 의미하지는 않으며 아마도 공존하는 형태가 될 것이라고 덧붙인 것으로 알고 있습니다.) 개인적으로 관심 있었던 부분은 멀티 코어에 맞는 새로운 언어의 등장입니다. 강연에서 언급했는지의 여부는 알 수 없습니다만 게임 개발에 효율적인 언어의 필요성 때문에 언리얼 스크립트를 개발했던 만큼 (Haskell을 이야기하고 있긴 하지만) 멀티 코어에 맞는 새로운 언리얼 스크립트를 개발할 가능성도 있다고 봅니다.

생산성과 관련한 이슈는 이미 시작된 것이고 앞으로는 아마 더욱 심해지리라 봅니다. 이는 직접적으로는 게임 엔진이나 툴의 변화를 가져오겠지만 컴퓨팅 환경의 변화에 따른 것이므로 그래픽스와 관련한 산업 전반에 영향을 미친다고 봐야 할 것입니다. 그래서 개발 공정(아트 파이프라인 등)에도 기존과는 확연히 구분되는 새로운 혁신이 등장하는 일이 필연적이라 예상됩니다.

...그런데 이런 추세라면 개발자도 앞으로는 더욱 세분화되지 않을까요? 2000년대 초반 이후로 그래픽 하드웨어의 발전은 게임계로로 다른 산업으로부터의 인력 유입과 같은 타 산업과의 컨버전스가 가속되는 촉매 역할을 했는데 이러한 현상이 앞으로 더욱 가속화될 것 같습니다.

...음, 그러니까 요약하면 먹고 살기가 더 힘들어지지 않을까라는 생각...ㅡㅡ;


ps. 그런데 강연 장소가 쇼와 여.자. 대학이군요, 흐음~ (팀 스위니 형님, 아마 미혼이죠? 쿨럭)

by kimsama | 2009/05/04 01:05 | MultiCore | 트랙백 | 핑백(1) | 덧글(2)

멀티코어와 스트리밍 - 압축과 메모리 관리


개인적으로 게임에서 스트리밍(streaming)의 중요성과 대단함을 처음 알았던 때는 던전시즈를 끝냈을 때였다. 게임을 다시 시작하지 않는 한 로딩 없이 엔딩까지 진행할 수 있었던 게임, 그 당시의 하드웨어 환경을 사용하면 참 놀라운 일이다.

이제 멀티 코어 환경의 엔진에서 스트리밍은 지원하는 것이 당연한 기본적인 특징이 되었다. 사실 다른 처리에 비하면 스트리밍은 쉬운편에 속한다. 다른 쓰레드의 잡(job)을 방해하는 일 없이 워크 쓰레드(work thread)를 사용해서 손쉽게 처리할 수있는 경우가 대부분이기 때문이다. 이 글에서는 스트리밍 지원에 있어 고려해야할 데이터 압축 몇 가지와 또 스트리밍시 간과해서는안될 메모리 관리자 설계에 대해서 이야기한다.

스트리밍 처리에 있어서 중요한 것은 데이터의 크기이다. 품질을 희생하지 않고 데이터의 크기를 줄이는 일은 백그라운드에서 계속 로딩해야 하는 스트리밍의 특성상 매우 중요하다. 여기에 응용할 수 있는 방법이 바로 압축이다. 스트리밍이 필요한 데이터는 보통 다음의 것들이 있다

  • 메쉬 데이터
  • 애니메이션 데이터
  • 텍스쳐 데이터- 노말 텍스쳐
메쉬 데이터는 다시 정점 컴포넌트들로 구분되며 이들 정점 컴포넌트는 컴포넌트의 특성에 따라 다른 압축 방법을 사용해야 한다.[1]

www.infopub.co.kr/ebook/pdf/5674-214.pdf

최근에 사내에서 메쉬 데이터를 압축해서 사용해 보니 압축율이 무려 55%나 되었다.(100메가인 경우 55메가가 되었다는 이야기.압축한 정점 컴포넌트는 normal, color, uv, bi-normal, tangent, joint indices,weight 값들이다.) 이 정도면 왜 압축을 안하는 것이 이상할 정도. 메쉬 데이터의 압축에 대한 이야기는 Floh씨의블로그에서도 찾을 수 있다.

http://flohofwoe.blogspot.com/2008/03/vertex-component-packing.html

(※한가지 의문이 드는 점은 ShaderX1에서는 uv 값을 패킹하는 경우 피해야 할 방법에 대해서 이야기하고 있는데  위의 블로그포스트에서 이야기하는 DrakenSang에서 사용한 방법은 바로 그 피해야할 방법을 사용하고 있다는 점이다.)

또 cateu님의 블로그에도 Vertex Component Packing이라는 제목으로 좋은 내용이 있으니 읽어 보길 권한다.



두 번째로는 애니메이션 데이터의 압축이 있다.  애니메이션 데이터의 압축 방법 중 하나는 캐릭터의 바운딩 박스에서 데이터의 오프셋을 계산해서 사용하는 방법이 있다.

http://ati.amd.com/developer/shaderx/shaderx_characteranimation.pdf 
(Compression 섹션 참조)

마지막으로 텍스쳐 데이터의 압축과 관련된 이슈는 여러가지 이슈가 있는데 요즘에는 대부분 DDS 포맷을 사용하므로 기본적으로 압축된포맷을 사용하는 셈이다. 여기에 한가지 더 고려해 볼만한 것은 노말맵 텍스쳐 데이터의 압축이다. 노말값은 [0, 1]사이의 값을가지므로 이것을 이용해서 노말맵 텍스쳐 데이터의 압축을 시도해 볼만한다.

http://benjaminnitschke.com/2005/09/07/NormalMapCompressorV13AndPDCInformation.aspx


그런데 스트리밍을 지원할 때에는 반드시 함께 고려해야할 중요한 것이 한가지 있는데 바로 메모리 관리이다. 스트리밍을 통해서 (메모리로) 읽어 들인다는 것은 다른 한쪽에서는 사용하지 않는 리소스를 메모리에서 내린다는 이야기가된다. 열역학의 법칙 - 에너지의 총량은 일치해야 한다 - 은 여기에도 적용이 된다. 들어간 만큼 다시 집어 넣어려면 그만큼빼야 한다.

메모리 관리를 직접 한다고 해서 스트리밍에서 메모리와 관련해서 발생하는 모든 문제들을 해결할 수 있는 것은 아니다. 예를 들어 게임 내에서 섹터들을 백그라운드 로딩을 사용해서 읽어 들이는 경우를 생각해 보자. 각 섹터마다 정해진 메모리량에 맞추어 비슷하게 메모리를 차지하도록 배경을 디자인하는 일은 레벨 디자이너의 몫이지 프로그래머가 메모리 관리자로 해결해야 하는 일은 아니다. 하지만 정교한 메모리 관리자가 없는 경우에는 이러한 작업이 힘들 뿐만 아니라 문제가 발생해도 어디에서 어떤 문제가 발생했는지 알기가 매우 힘들다. 그러므러 스트리밍을 지원할 때에는 우선 엔진 전체에 걸친 메모리 관리 정책의 수립이 선행되어야 하고 이를 바탕으로 정교한 메모리 관리자의 작성이 필요하다.


최근의 게임들은 그 규모가 점점커지고 (콘솔 게임의 플레이 시간은 더 짧아지고 있지[2]) 복잡해지고 있다. 스트리밍은 더이상 고급 기술이 아니라 현세대 엔진이라면 당연히 지원해야 하는 기본적인 기능 중의 하나이다. 이 글에서는 스트리밍과 관련한 이슈 중 압축과 메모리 관리의 두가지 관점에서 간략하게 이야기했다. 레벨의 스트리밍과 관련해서 참고할 만한 좋은 글은 던전시즈에서 사용했던 방법에 대한 내용인"The Continuous World of Dungeon Siege"와 Saint Row의 레벨 에디팅[4]에 대한 글이있다.



[1] ShaderX1, "Vertex Decompression using Vertex Shaders "(세이더 안에서 정점 압축 풀기기), Dean Calver
[2] 개발 비용과 플레이 시간은 반비례한다는 사실에 대해서 'xxx의 법칙' 같은 것이 나올 법도 하다.
[3] Dungeon Siege, "The Continuous World of Dungeon Siege",
http://www.drizzle.com/~scottb/gdc/continuous-world.htm
[4] The Creation of Saints Row's Open World Cityscape, http://www.dev3d.net/bbs/data/pds/1188110066/saintsrow.pdf

by kimsama | 2009/05/03 23:00 | MultiCore | 트랙백 | 핑백(1) | 덧글(0)

멀티 코어와 메시징

멀티 코어는 여러 개의 쓰레드를 사용하게 된다. 이런 환경에서 가장 문제가 되는 것은 공유 데이터에 대한 접근 방법이다. 물리 시스템이 하나의 쓰레드를 사용하고 렌더링 시스템 역시 쓰레드를 사용하여 분리한 경우를 보자.

게임 루프에서 충돌이 일어난 후 물리 시스템은 충돌 이벤트에 대해서 게임 객체의 새로운 위치를 계산한다. 그리고 렌더링 시스템에서는 갱신된 새로운 위치 데이터를 사용하여 게임 객체를 렌더링한다. 그런데 이들 두 시스템이 각각의 쓰레드로 분리되어 실행되고 있다는 점이다.

일반적인 방법으로는 lock을 사용한다. 물리 시스템에서 게임 객체의 위치를 갱신하기 전에 다른 시스템에서 이 데이터에 접근하지 못하도록 lock을 건 다음 데이터를 갱신한다.

그런데 이 lock의 오버헤더가 만만치 않다. 또 이런 식으로 lock/unlock을 사용하면 전체 시스템이 복잡해지는 것은 두말할 필요도 없다. 행여 실수로 lock/unlock을 빠뜨리는 경우 시스템은 예기치 않은 오동작을 하게 된다. 더 큰 문제는이 문제가 바로 쓰레드와 관련한 문제라는 것이다. 복잡한 시스템에서 쓰레드의 문제는 해결하기가 매우 어려운 경우가 대부분인데다 심지어는 재앙을 초래하기도 한다.

그럼, 쓰레드를 사용해서 동시에 여러 개의 시스템을 실행할 때 이들 시스템 간의 데이터 공유 문제에 해결에는 어떤 방법이 좋을까?

바로 데이터를 복사하는 방법이다. 이것은 시스템이 서로 다른 시스템의 데이터에 접근하는 방법이 아니라 각 시스템이 시스템 내부에 공유 데이터의 복사본을 가지고 있고 메시지를 통해서 다른 시스템에 자기 시스템에서의 공유 데이터의 변경을 알리는 방법이다.

쓰레드 A에서 쓰레드 B의 함수를 바로 호출하는 방법도 사실은 다른 시스템의 데이터에 lock을 통해서 바로 접근하는 방법에 속한다. 메시지를 통해서 공유 데이터를 복사하는 방법은 이러한 lock을 사용할 필요가 없거나 혹은 최소한의 lock이 필요할 따름이다. 메시지는 특별한 형태가 아니라 일반적으로 알고 있는 바와 같이 다음과 유사한 형태로 처리할 수 있다.

...
//메시지 생성
Message::MoveMsg moveMsg = Message::MoveMsg::Create();

//메시지 값의 설정
moveMsg.Set(x, y, z);

// 메시지의 전송
moveMsg.SendAsync();
...

일전[1]에 망갈로 게임 프레임워크의 메시지 시스템의 장점 중에 하나로 멀티 코어 시스템에 편리하다고 이야기한적이 있었는데 바로 이런 이유에서다. 또 이렇게 메시지를 사용하게 되면 각 시스템을 서로 완전히 분리(decoupling) 시킬 수가 있는데 이것 역시 멀티 코어를 사용하여 각 시스템들을 동시에 실행시킬 때에는 매우 중요한 것 중의 하나이다.

컴포넌트 방식의 게임 프레임워크[2]에서 컴포넌트 간의 통신에 메시지를 사용하게 되면 이처럼 멀티 코어 환경에서도 잘 작동하는 유용하고 견고한 시스템의 설계가 가능하다.


[1] KGC 2008, Nebula2 Mangalore Game Framework에서
[2] GPG6, Component based Game Framework Library


...이렇게 메시지를 사용하게 되면 이제 메시지 전달의 순서에 대한 문제가 대두됩니다. 무슨 말이냐 하면 물리 시스템의 위치 메시지는 렌더링 시스템의 위치 메시지보다 먼저 처리되어야 합니다. 바꾸어 말하면 물리 시스템에서 계산된 위치 데이터를 계산한 다음 이 메시지가 렌더링 시스템에 전달되어야 순서에 맞습니다다. 이 부분은 또 다음에... ^^

by kimsama | 2009/05/03 18:17 | MultiCore | 트랙백 | 덧글(7)

3Dvia 3D Life

작년 11월에 3DVia의 3D Life 행사에 초청되어 강연한 내용입니다.


포스팅한다는 것을 한참 동안 잊고 있었네요...-_-;

3DVia는 게임 관련 제품으로는 Virtools로 잘 알려져 있는 회사입니다. 여기에서는 매년마다 Virtools를 구매한 업체나 학교, 또 관심이 있는 개발자들을 초청해서 3D  Life라는 행사를 진행하고 있습니다. 2008년에는 게임에 중점을 두고 진행되는 행사라 게임 개발에 종사하는 사람으로 제가 초청되었습니다.

특별히 주제가 정해져 있는 것은 아니고 게임계에서 이슈가 되는 내용으로 자유롭게 정해서 해달라는 부탁을 받았습니다 - 사실 이런게 제일 힘듭니다 -_-;;

강연 주제는 Rapid Prototyping과  Collaboration의 두 가지로 정해서 진행했습니다. 개인적으로도 관심이 많은데다 3DVia의  새로운 프로덕트인 3DVia MP의 특징과도 잘 맞아 떨어지기 때문입니다.

Rapid Prototyping(이하 RP)은 이전에도 이슈가 되었던 내용이지만 개발비가 상승한 최근에는 더욱 중요해진 이슈입니다. Virtools의 경우 기술적으로 Rapid Prototyping을 컴포넌트 기반의 엔티티 시스템을 사용하여 해결하고 있습니다. (Virtools에서는 Behaviors Building Blocks라고 이야기합니다) 개념은 Nebula 엔진의 Mangalore 게임 프레임워크의 그것과 같습니다. 다만 Mangalore의 컴포넌트(Mangalore에서는 Property)는 C++로 작성하는데 비해 Virtools의 경우 자체 스크립트로 작성하는데 이것을 프로그래머가 아닌 디자이너나 아티스트도 쉽게 작성할 수 있도록 하기 위해서 비쥬얼 에디터를 제공한다는 것이 큰 차이점입니다.(그런데 프로그래머들은 보통 이 방법을 기피합니다. 번거롭다고 생각하기 때문이죠. 노드들을 연결할 시간에 코딩하는 쪽이 사실 더 빠르긴 합니다.)

Mangalore의 Property(C++로 작성)와 Virtools의 Behavior Block의 중간 쯤에 있는 것으로는 Unity3D를 들 수 있습니다. Unity3D의 경우 제공되는 SDK를 사용하여 C/C++로 직접 컴포넌트를 작성하거나 스크립트로 컴포넌트를 작성하여 게임 엔티티를 정의하도록 되어 있습니다.

RP와 관련한 주제들은 매우 다양하지만 기술적인 측면, 그 중에서도 컴포넌트 기반의 게임 엔티티 시스템으로 RP를 구현하는 것이 중요한 것은 게임 개발 주기에서 컨텐츠 생산이 가장 많은 시간을 차지하는 부분이자 가장 중요한 부분이라고 할 때 게임 엔티티가 컨텐츠의 핵심이기 때문입니다.


Collaboration은 규모가 크질 수록 그 중요성이 부각되는 내용입니다. MMO 게임과 같이 대규모의 개발팀이 필요한 경우는 개발 공정에서 팀이 실시간으로 서로 개발 내용을 확인 할 수 있는 시스템을 가지고 있는 경우 눈에 띄는 생산성 향상을 기대할 수 있습니다. 이전에는 게임 엔진이라고 하면 렌더링 엔진을 생각하거나 아니면 그 부분을 가장 중요하게 생각하는 경향이 짙었습니다. 물론 렌더러가 중요하지 않은 것은 아니지만 게임 엔진의 전부는 아닙니다. 그래서 엔진의 구매나 개발로 이 부분을 해결하고도 다른 부분에 대해 미처 신경을 쓰지 못해서 원하는 결과를 얻지 못하는 경우를 많이 봤습니다. 사실 이 부분은 MMO  게임을 한번 서비스(!)해 본 경험이 있는 팀이나 개발자라면 서비스 컨텐츠 개발의 생산성이 얼마나 중요한지를 알고 있을 것입니다. 그래서 저는 MMO 게임의 경우 서비스 경험이 개발 보다 더욱 중요하다고 생각합니다. 10개가 개발해서 2~3개만이 서비스 되는 현실을 볼 때 개발 경험이 있는 개발자보다 서비스 경험이 있는 개발자가 더욱 귀하기 때문입니다.

Collaboration의 경우 최근에 부각되기 시작한 개념이라서 아직 게임 엔진들이나 미들웨어 중에서도 이를 지원하는 엔진은 찾아보기가 힘듭니다. 상용 엔진의 경우에는 Hero 엔진이 MMO 개발을 전문으로 하는 엔진이라서 그런지 이러한 내용을 잘 알고 만들어진 엔진 같아 보입니다.
Unity3D 엔진도 Asset Server 등의 지원을 보면 Collaboration을 의식하고 있는 것을 알 수 있지만 MMO와 같은 하드코어한 게임 개발의 Collaboration에는 아직 부족해 보입니다.(Unity3D의 경우 RP은 타의 추종을 불허할 정도로 뛰어납니다)


다가오는 세대의 게임 개발에서는 Rapid Prototying과 Collaboration의 이 두 가지 이슈를 늘어난 코어 개수를 잘 이용해서 어떻게 작업하느냐가 중요한 관건이 되리라 예상해 봅니다.

by kimsama | 2009/04/26 10:31 | Conferences | 트랙백 | 덧글(0)

Nebula3 2009년 4월 버전

공개되었습니다.

http://flohofwoe.blogspot.com/2009/04/n3-sdk-apr-2009-download.html


변경 사항 및 Anatomy는 이후 차차...

by kimsama | 2009/04/24 18:02 | Nebula3 | 트랙백 | 덧글(0)

◀ 이전 페이지다음 페이지 ▶