메모리 최적화에 대한 이슈는 게임 개발자에게 굉장히 민감한 주제 중에 하나 입니다.
특히나 게임 개발에서 메모리를 가장 많이 차지하는 것은 텍스쳐입니다.
지금부터 언급되는 텍스쳐는 DirectX9 에서 POOL_MANAGED 옵션으로 생성되는
Managed-Texture 형태의 텍스쳐로 국한합니다.
( 텍스쳐 관리 시스템에서 제어되는 텍스쳐는 POOL_MANAGED 옵션을 가진 텍스쳐 뿐입니다. )
게임개발자가 텍스쳐를 사용하는 동작을 제가 아래와 같이 단순화 시켜보았습니다.
먼저 우리가 원하는 텍스쳐를 메모리에 로드할 수 있습니다.
비디오-메모리에 직접적으로 로드할 수 있으며, 시스템-메모리에 로드할 수도 있습니다.
로드할 때, 우리는 메모리를 조금 더 최적화하기 위해서
DirectX 에게 여러가지 힌트 옵션을 설정하기도 합니다.
이런 힌트 옵션들은 DirectX의 여러 버전들마다 설정 방법이 조금씩 다르지만,
기본적으로 내용은 비슷합니다.( 읽기전용/쓰기 전용 등이죠... )
그리고 필요해 위해서 DirectX 의 상태를 변경해서 텍스쳐를 그래픽 파이프라인에 연결합니다.
SetTexture( ... ) 같은 API 들이 이런 역할을 합니다.
마지막으로 필요하지 않는 텍스쳐는 직접 제거를 해줍니다.
결국 개발자가 할 수 있는 것은 Load-->Bind-->Release 의 형태 뿐입니다.
게임을 하는 중에 비디오-메모리가 가득차 있는데,
새로운 텍스쳐가 로드되면 어떤 상황이 벌어질까요?
새로운 텍스쳐를 로드하기 전에 비디오-메모리의 사용 가능한 공간을 체크한 후에,
새로운 텍스쳐를 로드하면 간단히 해결할 수 있습니다.
하지만 지금 우리는 개발할 때, 그런 체크를 하지 않습니다.
이 상황으로 유츄해 보면, 누군가에 의해서 자동적으로 어떤 작업이 이루어지고 있습니다.
그 누군가가 바로 DirectX의 텍스쳐 관리 시스템입니다.
게임 개발자에게 주어진 권한은 텍스쳐의 메모리의 생성과 제거 정도에 지나지 않습니다.
그 이외에 나머지 처리는 모두 DirectX의 텍스쳐 관리 시스템에 의해서 제어됩니다.
이 텍스쳐 관리 시스템은 DirectX6 부터 도입되었습니다.
즉, 이전까지는 아마도 개발자들이 직접 메모리를 계산하면서 처리했을 겁니다.
( 아마도~~ㅎㅎ )
이런 텍스쳐 관리 시스템은 기본적으로 다음과 같은 동작을 합니다.
- 현재 사용 가능한 텍스쳐 메모리의 양을 체크하고 추적
- 현재 렌더링 작업을 위해서 필요한 텍스쳐와 그렇지 않은 텍스쳐를 결정
- 비디오-메모리에 있는 텍스쳐 중에 어떤 것이 제거되어야 하는지를 결정
- 시스템-메모리에서 다시 읽어들일 텍스쳐를 결정
사실 이것보다 더 많은 작업을 하겠지만, 제가 이 정도로만 간략화 시켜보았습니다.
텍스쳐 관리 시스템은 여러 결정권을 가지고 있습니다.
특히나 비디오-메모리에서 제거 권한은 우리 개발자에게 정말 두려운 권한입니다.
힘들게(?) 비디오-메모리에 올려두었는데,
시스템에서 자기 마음대로(?) 그냥 내려버리면 얼마나 가슴 아프시겠습니까?
그래서 이런 가슴 아픈 일을 방지하는 차원에서
텍스쳐들에게 우선 순위를 부여할 수 있습니다.
텍스쳐 관리 시스템은 일정한 규칙을 가지고 비디오-메모리에서 텍스쳐를 제거합니다.
그 규칙이라는 것은 기본적으로 LRU( least-recently-used ) 에 기반을 두고 있습니다.
이는 비디오-메모리가 가득차 있는 상태라면,
이들 중에 비디오-메모리에서 제거가 되는 것은
가장 오랫동안 사용되지 않은 텍스쳐라는 것을 의미합니다.
개발자들은 비디오-메모리의 부족에 고통을 호소합니다.( 저만 그런가요? ㅎㅎ )
비디오-메모리가 가득찬 상태에서 새로운 하나의 텍스쳐가
비디오-메모리로 로드된다고 가정하겠습니다.
그러면, 텍스쳐 관리 시스템은 LRU로 체크를 해서
하나의 텍스쳐를 비디오-메모리에서 제거할 것입니다.
그리고 새로운 텍스쳐를 비디오-메모리로 로드할 것입니다.
실제로 텍스쳐 관리 시스템은 이것보다 훨씬 복잡한 방법으로 동작할 것입니다.
( 예를 들기 위해서 텍스쳐 크기 같은 문제를 제외하고 예를 드는 것 뿐입니다. )
이런 상황에서 10개의 새로운 텍스쳐가 비디오-메모리로 로드된다고 생각해 보십시오.
시스템-메모리에서 비디오-메모리의 데이터 전송이 최소 10번이 이루어져야 합니다.
또한 최소 10번 이상의 비디오-메모리에서 제거할 텍스쳐를 결정하는 작업이 이루어져야 합니다.
이것이 많아지면, 병목 현상을 초래할 수 있습니다.
이것은 텍스쳐 스레싱( texture thrashing ) 이라고들 합니다.
실제 게임 플레이 중인 상황에서 갑자기 새로운 배경이나 오브젝트들이 등장할 때
프레임이 느려지는 현상이 발생하게 되는데, 이런 작업도 거기에 영향을 미치는 요소입니다.
게임이 실행 중인 경우에는 이미 많은 비디오-메모리를 사용 중이니,
사실 빈번하게 발생할 수도 있는 일입니다.
무책임한 말일 수 있으나, 이것은 어쩔 수 없는 일입니다.
( 적절히(?) 개발자들이 노력해야 할 부분이죠? ㅎㅎㅎ )
그런데 비록 오래 사용되지는 않았지만,
무척이나 중요한 텍스쳐가 있으면 조금 문제가 되지 않을까요?
반드시 비디오-메모리에 있어야 할 텍스쳐라는 개념이 아닙니다.
( 만약 반드시 비디오-메모리에 있어야 한다면 POOL_DEFAULT 로 직접 관리해 주시면 됩니다.)
텍스쳐 관리 시스템에서 비디오-메모리에서 제거할 목록들을 구성할 때
일종의 특혜(?) 가 있는 텍스쳐들은 제거 목록에서 제외시켜달라는 의미로 볼 수 있습니다.
이것은 비디오-메모리에 계속해서 남아있을 필요는 없지만,
되도록이면 조금 더 오래 남겨달라는 의미로 해석하실 수 있습니다.
이렇게 특혜(?)를 부여하는 것이 바로 우선 순위를 설정하는 작업입니다.
비디오-메모리에서 제거될 후보군들 중에서 LRU 값이 같다면,
우선 순위가 낮은 텍스쳐가 제거되는 것입니다.
IDirect3DResource9 라는 인터페이스를 상속받아서
Direct3D의 텍스쳐 인터페이스가 만들어졌습니다.
IDirect3DResource9 인터페이스는 이 우선 순위를 설정할 수 있는 멤버함수를 가지고 있습니다.
IDirect3DResource9::SetPriority( ... ) 가 바로 그것입니다.
Managed-Texture 의 경우 기본적으로 우선 순위가 0 입니다.
0보다 높은 숫자를 입력하면, 높은 우선 순위가 됩니다.
그런데 무턱되고 높은 숫자를 입력하면, 문제의 소지가 있을 수 있습니다.
그래서 이를 상수로써 정해진 몇몇 값들이 있습니다.
그 값들은 아래와 같습니다.
D3D9_RESOURCE_PRIORITY_MINIMUM 0x28000000
D3D9_RESOURCE_PRIORITY_LOW 0x50000000
D3D9_RESOURCE_PRIORITY_NORMAL 0x78000000
D3D9_RESOURCE_PRIORITY_HIGH 0xa0000000
D3D9_RESOURCE_PRIORITY_MAXIMUM 0xc8000000
이것은 DirectX가 스케쥴링 목적으로 정의한 상수들입니다.
이 우선 순위를 그대로 텍스쳐에 적용하시면 안됩니다.
일반적으로 텍스쳐의 경우 D3D9_RESOURCE_PRIORITY_NORMAL 우선 순위를 사용해야 합니다.
그리고 아래와 같이 설정하는 것이 좋습니다.
ManagedTex->SetPriority( D3D_RESOURCE_PRIORITY_NORMA + 1 );
ManagedTex->SetPriority( D3D_RESOURCE_PRIORITY_NORMA + 2 );
ManagedTex->SetPriority( D3D_RESOURCE_PRIORITY_NORMA + 3 );
Managed-Texture는 실제로 렌더링 작업이 이루어지기 전까지
비디오-메모리에 데이터가 존재하지 않습니다.
렌더링 작업이 한번이라도 이루어져야 할 때,
시스템-메모리의 텍스쳐 메모리가 비디오-메모리로 전송이 됩니다.
이것도 바로 텍스쳐 관리 시스템이 하는 작업 중에 하나입니다.
그런데 텍스쳐를 로딩하고, 이를 비디오-메모리에 바로 올리고 싶은 경우가 있을 수 있습니다.
이미 텍스쳐를 로딩한다는 것 자체가,
바로 렌더링 작업에 사용할 것이라는 확신이 있는 경우일 것입니다.
그 때는 IDirect3DResource9::PreLoad() 를 사용하시면 됩니다.
그러면 약간의 성능 향상을 보일 수도 있습니다.
( 이것은 저도 아주 약간의 효과를 경험했었습니다.^^ )
게임을 플레이 중에 씬 전체가 새로운 텍스쳐들로 가득 채워져야 하는 경우는 없으셨나요?
그런 경우 텍스쳐 스레싱 현상이 아주 크게 느껴질 수도 있습니다.
그래서 한꺼번에 비디오-메모리를 모두 비워버리는 API가 있습니다.
IDirect3DDevice9::EvictManagedResource() 가 바로 그것인데,
이 API는 보시다시피 Device 인터페이스의 API 입니다.
즉, 버퍼와 텍스쳐를 포함한 Managed 리소스까지 모두 비디오-메모리를 비워버립니다..
그래서 씬이 완전히 새롭게 구성될 때, 꽤 유용할 수 있습니다.
( 저는 이 API 아주 좋아합니다..ㅎㅎㅎ )
DirectX9 의 텍스쳐 관리 시스템은 사실상 이 세가지 API를 통해서 제어를 합니다.
나머지는 우리 개발자의 손을 떠난 문제입니다.
위의 문제를 고민하기 전까지 저는 게임에 사용되는 메모리를 계산해 본 적이 없었습니다.
예를 들면 상점이나 특정 지역에서 사용되는 메모리 계산이겠죠.
게임 프로그래머가 단순히 주어진 리소스를 렌더링만 한다는 개념에서
벗어나게 해주었던 작업들이였습니다.
댓글을 달아 주세요
아니! 이렇게 글솜씨가 좋으시다니! 최곱니다.. ^^ 근데 맨날 바이패드란 말을 많이 들어왔는데.. 대체 바이패드가 뭐에요? -_-;
맥스에서 제공해주는 인간형 기본 뼈대에요
마야처럼 뭐 이것저것 셋팅할필요없이 다되어있어여
아,,, 감사합니다 ^^;;
아~ 그런거였어요? 전 무슨 특별한 형태로 구축한 뼈대가 바이패든줄 알았다는.. 요즘 오토데스크에서는 CAT을 또 만들었던데... 이것도 그냥 새로운 뼈대..?
Biped, CAT 둘 다 플러그인으로 있던 것들이 기본 기능으로 흡수된 것입니다. CAT은 최근에 흡수되었구요. 두 경우 모두 전문적인 리거 없이도 애니메이션 리깅을 자동으로 만들어주는 툴입니다. ^^
와~ 자막파일!!! 첨보는 자막파일!! 정말감사합니다.~
아~ 핑속님... 제 맘대로 '핑속'을 태그로 달았습니다. 필자별로 글 찾아보는 기능이 티스토리에 없어서 태그로 해서 검색을 하게요. 담에 글써주실때 '핑속' 태그 추가해주세요 ^^
알겠습니다 ^^
재미지다... 2탄도 기대.. 기대.. ㅎㅎ
헉~ 이런 우연이~~
핑속님이 '캐릭터 셋업 테크닉' 저자분이셨군요.
저 어제부터 그 책 사서 공부 중이였는데...ㅎㅎㅎ
책 정말 잘 쓰셨더라구요~( 지금 보고 있는 중이라서~~ ㅎㅎ )
저는 아티스트분들과 커뮤니케이션을 위해서 구매했는데,
프로그래머들이 보기에도 유용한 설명이 많았습니다~
( 거의 프로그래머 수준이셨어요~~ ㄷㄷㄷ )
여튼 독자로서 이 기회를 감사를 표합니다.
혹시 나중에 뵙게 되면, 책에 싸인 부탁~~ ㅎㅎ
비키는 제가 아주 유용히 잘 쓰겠습니다..ㅋㅋ
헉~! 비... 비키요?
엇 제가 아시는 그분이신가요..그럼....n모사의.. 저는 핑속님을 압니다만..핑속님은 저를 기억못하실거에요 ^^; 저희 애니메이터들도 그책을 열심히 사서 보고 있습니다..^^; 아주오래전 학창시절 교제가 일루션 오브 라이프 였는데..그때 배웟던 2디 퓨쳐 애니메이션이 생각나는군요..디즈니의 클래식 애니를 배우며 세컨더리 액션의 중요성을 인식은 햇지만..제대로 표현하는게 쉽지만은 않았던 기억이 나네요..좋은글 잘보고 갑니다 ^^
감사합니다.
귀거리님 그림들 완전 제 스타일이에요~ ^^
오 역시 핑속님! 후후후 잡아온 보람이 있...
저도 처음 안 내용이네요. 감사합니다. 세컨더리 액션의 범위는 훨씬 크군요! ㅎㅎ
요즘 대마왕님과 알게된게 과연 좋은 일이였을까 하는 생각이 종종 드네요... 특히 14일, 29일이 가까워지면서 생각이 강해질 것 같습니다.
당신의 기사는 그들의 프로젝트에서이 문제에 대해 직시해야 독자들에게 좋은 그것은 그들에게 당신의 게시물에 대한 많은 고맙습니다 도움이 될 수 있습니다!
보통 일하면서도 세컨더리를 귀, 꼬리, 머리카락 등의 움직임으로 생각하고 작업하게 되는 경우가 많은데, 저도 여러가지 찾아보다보니 세컨더리는 좀더 광범위 하더라구여..바텐더가 손님과 이야기 하는 도중 눈은 손님을 보고있지만 손은 설거지 같은 바텐더 본연의 일을 하는 액션이라든가, 정신이 나갔던 사람이 냉정을 되찾으며 안경을 고쳐쓰는 움직임이라든가..이런 내용의 글 올려주시니 넘흐 좋으네요..
안녕하세요. 테크니컬 아티스트 검색하다 이 블로그까지 왔는데 정말 귀한 말씀이 많네요.
좋은 팁 알려줘서 정말 감사합니다.
유튜브에서는 영상이 짤렸지만 digital tutors 란 사이트도 꽤 좋은 사이트네요 알려줘서 감사해요 ㅠ.ㅠ
마지막 회사에서 임금체불 된후 진지하게 진로를 고민하며 쉬고 있는데, 다시금 열정을 불살라 주시는군요.
제가 그동안 외적인 요인 때문에 자기계발을 너무 등한시 한 것 같아요.
핑속님 책도 사서 다시금 게임 애니메이터의 열정을 불살라 볼렵니다~