게임 개발에 사용되는 메모리 할당 패턴


20

나는 메모리 할당 및 프로파일 링과 같은 것들을 지원할 나만의 할당 자 메소드를 만드는 것을 연구하고 있지만, 연구를 계속함에 따라 이것이 게임 개발에서 어떻게 이루어 졌는지 찾고있다.

어떤 메모리 할당 기술을 사용할 수 있으며 왜 좋은 기술입니까?


1
정말로 필요합니까? 팀이 구현할 수있는 가장 복잡한 것 중 하나 일뿐입니다.
Ali1S232

4
그것은 나에게 관심있는 분야이므로 그것에 대해 배우고 구현하고
싶습니다

나는 그 주제가 정말로 흥미 롭다고 말해야한다. 그것이 할당 할 수있는 경우가 있지만, 당신은 보통 PC 게임에서 나는 실제 게임에 대해 오히려 걱정할 것이다 ...
rioki

현대 표준 라이브러리 malloc의 소스 코드를 조사했으며 무료 또는 신규 및 삭제를 했습니까? 대안 적 할당 전략을 알고리즘 또는 실제와 비교할 수있는 매우 유용한 기반을 제공 할 것으로 보입니다. 그것은 당신이 무엇을 얻을지에 대한 진정한 통찰력을 제공 할 것 같습니다.
Louis Langholtz 2016 년

답변:


25

게임 엔진 아키텍처 에는이 주제에 관한 정보가 있습니다. 기본 사항은 레벨 / 프레임 등의 메모리 요구 사항을 이해하기 위해 약간의 분석을 수행해야한다는 것입니다. 저자가 언급 한 몇 가지 패턴이 있습니다.

  • 스택 기반 할당 자 : 이들은 큰 메모리 세그먼트를 한 번 할당 한 다음 게임 내 다른 곳의 요청에 따라 해당 메모리 블록 내에 포인터를 할당합니다. 이는 메모리 할당에 필요한 컨텍스트 전환을 피하는 데 유용하며, 자체 기술을 사용하여 SIMD 작업에 대한 연속성 또는 특정 정렬을 적용 할 수 있기 때문에 유용합니다. 일부 엔진은 또한 한 종류의 리소스가 맨 위에서로드되고 다른 하나가 맨 아래에서로드되는 이중 엔드 스택을 사용합니다. 아마도 LSR (로드 앤 스테이 레지던트, 게임 전체에 필요할 것)과 맨 아래의 레벨 별 데이터 일 것입니다.
  • 단일 프레임 메모리 또는 이중 버퍼 프레임 메모리 : 하나 또는 두 개의 프레임주기 내에서 발생하는 작업을위한 메모리입니다. 이 기능은 모든 프레임을 할당 / 할당 해제하는 대신 메모리 추적을 유지하는 데 사용하는 포인터를 블록의 시작 부분으로 재설정하여 마지막 프레임의 데이터를 날려 버릴 수 있기 때문에 유용합니다.
  • 오브젝트 풀 : 파티클, 적, 발사체와 같은 동일한 크기의 오브젝트를위한 메모리 블록. 풀에서 사용하지 않는 첫 번째 세그먼트를 찾아서 쉽게 연속성을 얻을 수 있기 때문에 유용합니다. 또한 각 객체가 마지막 객체와 알려진 오프셋에 있기 때문에 반복이 쉽습니다.

필자가 언급 한 가장 큰 것은 메모리 조각화입니다. 신뢰할 수있는 일종의 메모리 페이징 백업이있는 PC와 같이 PC를 개발하는 경우 문제가되지 않지만 콘솔과 같은 고정 메모리 컨텍스트에서는 "메모리 부족"위험이 있습니다. 작은 연속 블록 만 사용할 수있는 방식으로 메모리가 조각화되어 큰 개체를 할당하려고 할 때 이를 위해 위와 같은 스택 기반 할당 자에는 내용을 정기적으로 조각 모음하는 방법도 포함하는 것이 좋습니다.

이에 관련된 실제 코드에 대한 자세한 내용은 Christian Gyrling의 기사 "우리는 기억이 부족합니까?"를 강력히 추천 합니다. , 이는 주로 메모리 사용 패턴을 분석하는 관점에서 사용자 지정 할당 자에 대한 기술을 다루지 만, 이는 메모리 관리를위한 사용자 지정 솔루션을 고안하는 데에도 적용됩니다.


1

내가 보았지만 (완료하지는 않았지만) 각 게임은 프레임 워크, 게임 엔진, 이전 버전 (2010-> 2011)에서 할당 메커니즘을 상속하거나 그 게임을 위해 특별히 작성된 새로운 게임 세트를 얻습니다. 구조 (데이터 구조가 재사용 가능하고 고정 된 크기이거나 다양한 유형 및 가변 크기 인 경우).

또한 동일한 프로젝트의 레벨 및 기타 게임 오브젝트와 사운드 파일 / 컴포넌트에 대해 다른 할당자를 가졌습니다. 다른 프로젝트에서 할당자는 해당 라이브러리가 관리하는 구성 요소에 대해서만 외부 라이브러리에서 상속됩니다.

최적화는 실제로 귀하의 요구에 달려 있습니다. 그러나 일반적으로 게임 장면에 들어가기 전에 할당이 이루어지고 메모리가 재사용됩니다. 일부 게임은 커스텀 할당자를 사용하지 않고 도망 갈 수 있습니다. 그러나 프로세서, 메모리 및 데이터 리소스가 예산이 책정 된 액션 게임의 경우 대규모 할당에서 처리 시간을 잃을 여유가 없으며 조각화 및 기타 문제로 메모리를 낭비 할 수 없습니다.

예를 들어 OGRE 3D 게임 엔진을 살펴 보는 것만으로 시작해야합니다 . 메모리 할당자를 구성 하는 몇 가지 옵션이 있습니다 .


0

종종 실수는 자신의 할당자를 작성하여 각 시스템에서 사용되는 메모리 양을 더 잘 제어하고 진행 상황에 대한 가시성을 높이는 것입니다. 이를 달성하는 가장 좋은 방법은 메모리 프로파일 러를 사용하는 것입니다. 거기에는 많은 메모리 프로파일 러가 있으며 내 프로파일 러 MemPro 가 하나의 예입니다. 이것은 모든 메모리 사용량을 추적하는 완전히 비 침습적 인 방법이며 콜 스택 와일드 카드 필터를 사용하여 자동으로 하위 시스템으로 분류 할 수 있습니다. 메모리 할당과 메모리 추적을 완전히 분리 된 상태로 유지하는 것이 가장 이상적이며 요구 사항이 완전히 다릅니다.

각 풀에는 오버 헤드가 있기 때문에 메모리를 풀로 임의로 나누는 것이 종종 해로울 수 있습니다. 실제로 인식하지 않고도 필요한 것보다 훨씬 많은 메모리를 사용할 수 있습니다. 낭비를 줄이려면 항상 모든 것을 한꺼번에 모으는 것이 좋습니다. 그러면 전체 시스템에서 여유를 공유합니다.

사용자 지정 할당자를 사용하는 유일한 이유는 CPU 성능 (주로 캐시 일관성) 및 조각화를 제한하는 것입니다. 이것의 완벽한 예는 파티클 시스템입니다. 모든 파티클이 메모리에 연속되어 있기를 원하고 짧은 메모리 할당이 많은 메인 메모리를 사용하고 싶지 않습니다. 파티셔닝 해제에 대한 또 다른 좋은 예는 스크립팅 언어입니다.

범용 malloc 대체의 예를 원하면 내 VMem 할당자를 살펴볼 수 있습니다 . 많은 AAA 게임에서 사용되었습니다. 콘솔 게임에 중요한 조각화를 제한하고 메모리 공간을 적게 유지하는 기술이 있습니다. 높은 스레드 경합에서도 매우 빠릅니다. 내 웹 사이트에는 이러한 기술에 대한 광범위한 문서가 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.