버전
menu

Wwise SDK 2025.1.0
AkMemoryArenas의 환경 설정 및 튜닝

AkMemoryArena는 Wwise 사운드 엔진에서 사용되는 사용자 지정 메모리 할당자입니다. 다양한 설정을 사용하여 예약된 메모리를 관리할 수 있습니다. Wwise 사운드 엔진은 여러 개의 AkMemoryArena를 사용하며, 이를 프로젝트 요구 사항에 맞게 적절히 조정하면 사운드 엔진의 전체 메모리 예약을 크게 개선할 수 있습니다.

AkMemoryArena 개요

AkMemoryArena는 범용 메모리 할당자 역할을 하며, 모든 메모리 할당은 크기에 따라 Small, Medium, Large, Huge의 네 가지 별도 힙 중 하나에 저장됩니다.

작은 할당은 256 바이트 이하의 모든 할당을 말합니다. 이 스레숄드는 임의로 구성할 수 없습니다. 이 스레숄드는 '소규모 블록 할당자(Small-block allocator, SBA)' 힙에서 관리됩니다. SBA는 고정된 크기의 메모리 블록으로 구성된 범위에서 모든 할당을 관리하므로 메모리 파편화와 관련하여 일관된 동작이 가능합니다. 각 스팬은 구성 가능한 크기로 돼있으며, 이러한 스팬은 상위 Medium 또는 Large 힙에서 할당됩니다. SBA는 초기 메모리 영역으로 초기화되어 SBA 힙에서 할당에 사용되는 오버헤드 양을 줄여줍니다. 일반적으로 모든 크기 클래스에 걸쳐 AkMemoryArena에서 메모리를 할당하려면 16 바이트의 오버헤드가 필요하며 이는 할당 메타데이터에 사용됩니다. 그러나 초기 영역 내의 SBA 할당에는 이러한 오버헤드가 필요하지 않습니다. 예를 들어, 일반 SBA 스팬 크기가 16 키비바이트이고 64 바이트 크기의 할당을 처리하도록 구성된 경우, 이 스팬은 각각 80 바이트 크기의 메모리 블록 약 200개를 처리할 수 있습니다. 그러나 동일한 16 키비바이트 범위가 초기 영역 내부에 할당되면 각각 64 바이트 크기인 약 250개의 메모리 블록을 처리할 수 있습니다.

Medium 및 Large 할당은 크기가 256바이트보다 크지만, AkMemoryArenaSettings::uAllocSizeLarge 이나 AkMemoryArenaSettings::uAllocSizeHuge 값보다 작습니다. Medium 및 Large 할당에 사용된 힙은 Two-Level Segregated Fit(TLSF, 2단계 분리 적합) 알고리즘을 기반으로 하는 알고리즘을 사용합니다. 결과적으로 이러한 힙은 O(1) 성능으로 할당과 해제를 제공할 수 있습니다. 이러한 힙은 메모리 할당이 어디에 배치되어야 하는지 결정하기 위해 적합한 메모리 할당 정책을 사용합니다. 그러나 원래 TLSF 알고리즘과는 달리 AkMemoryArena 에서 사용하는 TLSF 힙은 새로운 메모리 범위가 다른 메모리 범위와 연속적일 필요 없이 메모리 요구 사항이 증가함에 따라 시간이 지나면서 새로운 메모리 범위를 요청할 수 있도록 허용합니다. TLSF 힙은 모든 구성 할당이 해제되면 메모리를 해제합니다. Medim이나 Large 할당이 요청되면 TLSF 힙은 먼저 메모리의 초기 Base 스팬에서 사용 가능한 메모리 블록을 찾으려고 시도하고, 비어 있는 블록을 사용할 수 없으면 이미 매핑된 Medium이나 Large 스팬에서 비어 있는 메모리 블록을 찾으려고 시도합니다. 여전히 비어 있는 블록을 사용할 수 없는 경우 Huge 할당 힙에서 새 스팬에 대한 요청이 이루어지고 Medium이나 Large 스팬 목록에 추가됩니다. 마찬가지로, 스팬에 더 이상 할당이 없으면 "사용되지 않음(Unused)"으로 간주됩니다. 일정 수의 스팬이 사용되지 않으면 이 스팬은 시스템에 해제됩니다.

Huge 할당은 Medium이나 Large 힙에 맞지 않을 만큼 큰 할당입니다. 이러한 할당은 별도의 스팬에 배치되며 다른 할당과 메모리를 공유하지 않습니다. 또한, Huge 스팬에 대한 메모리는 시간이 지나도 재사용되거나 캐시되지 않습니다. 즉, 구성 메모리 할당이 해제되면 스팬도 즉시 해제됩니다.

AkMemoryArenaSettings

AkMemoryMgr 의 초기화 설정에는 사운드 엔진에서 사용하는 다양한 AkMemoryArena 를 구성할 수 있는 다양한 설정이 포함되어 있습니다. 특별한 언급이 없는 한, 아래에 설명된 크기는 2의 거듭제곱일 필요가 없습니다.

  • AkMemoryArenaSettings::bEnableSba - SBA를 활성화할지 여부를 제어합니다. 비활성 상태인 경우 모든 Small 할당은 Medium 할당으로 간주되어 TLSF 힙으로 전송됩니다. 기본적으로 이 옵션은 Media AkMemoryArena 에서 비활성화되어 있습니다. 그 이유는 Media 할당이 일반적으로 SBA에 비해 너무 크기 때문입니다.
  • AkMemoryArenaSettings::uSbaInitSize - SBA 힙의 초기 메모리 영역의 크기입니다 (단위: 바이트). 이 초기 영역에서의 할당은 메모리 할당 오버헤드가 없기 때문에 차지하는 공간이 적습니다.
  • AkMemoryArenaSettings::uSbaSpanSize - SBA 힙에 사용되는 각 메모리 스팬의 크기입니다 (단위: 바이트). 값이 높을수록 시스템 성능은 약간 향상되지만 사용되지 않는 메모리 때문에 메모리 낭비가 커질 수 있습니다. 이 값은 2의 거듭제곱이어야 합니다.
  • AkMemoryArenaSettings::uSbaMaximumUnusedSpans - SBA 힙의 초기 메모리 영역 외부에 할당된 경우 해제되기 전에 사용되지 않는 상태로 남아 있는 SBA 스팬 수입니다.
  • AkMemoryArenaSettings::uTlsfInitSize - TLSF 힙에 사용되는 초기 Base 메모리 스팬의 크기입니다 (단위: 바이트).
  • AkMemoryArenaSettings::uTlsfSpanSize - Medium 할당을 위해 생성된 각 보조 메모리 스팬의 크기입니다 (단위: 바이트). 새로운 스팬을 필요로 하는 할당 요청이 이 크기보다 큰 경우, 스팬 크기는 할당 요청의 크기를 이 값의 다음 배수로 반올림합니다.
  • AkMemoryArenaSettings::uTlsfLargeSpanSize - Large 할당을 위해 생성된 각 보조 메모리 스팬의 크기입니다 (단위: 바이트). 새로운 스팬을 필요로 하는 할당 요청이 이 크기보다 큰 경우, 스팬 크기는 할당 요청의 크기를 이 값의 다음 배수로 반올림합니다.
  • AkMemoryArenaSettings::uTlsfSpanOverhead - TLSF에 대한 새 스팬을 요청할 때, 이는 요청된 Huge 할당에서 빼지는 바이트 수입니다.
  • AkMemoryArenaSettings::uTlsfMaximumUnusedMediumSpans - 해제되기 전에 비어 있고 사용되지 않을 수 있는 Medium 할당에 대한 스팬 수입니다.
  • AkMemoryArenaSettings::uTlsfMaximumUnusedLargeSpans - 해제되기 전에 비어 있고 사용되지 않을 수 있는 Large 할당에 대한 스팬 수입니다.
  • AkMemoryArenaSettings::uAllocSizeLarge - 할당이 Large로 분류되기 위해 필요한 최소 크기입니다 (단위: 바이트). 이 값보다 작지만 256바이트보다 큰 모든 할당 크기는 Medium 할당으로 간주됩니다. 이 값이 uAllocSizeHuge 보다 큰 경우 어떠한 할당도 Large로 분류되지 않습니다.
  • AkMemoryArenaSettings::uAllocSizeHuge - 할당이 Huge 할당으로 분류되기 위해 필요한 최소 크기입니다 (단위: 바이트).
  • AkMemoryArenaSettings::uMemReservedLimit - 이 AkMemoryArena 에서 예약할 수 있는 최대 메모리 양입니다 (단위: 바이트). Huge 힙이 이 제한을 넘어서는 메모리를 요청하려고 하면 nullptr이 반환되고 fnMemAllocSpan 이 호출되지 않습니다.
  • AkMemoryArenaSettings::fnMemAllocSpan: - Huge 힙에 새로운 할당이 필요할 때 실행되는 사용자 제공 콜백으로, TLSF 힙에서 새로운 스팬에 대한 모든 요청이 포함됩니다.
  • AkMemoryArenaSettings::fnMemFreeSpan - Huge 힙이 할당을 해제할 때 실행되는 사용자 제공 콜백으로, 여기에는 TLSF 힙에서 모든 스팬을 해제하는 것도 포함됩니다.

다음 코드 예제는 AkMemoryMgr 의 AkMemoryArenaSettings 기본 초기화에 사용할 수 있으며 AkMemoryArenaSettings 를 추가로 사용자 지정하기 위한 좋은 시작점이 될 수 있습니다.

AkMemSettings memSettings;
for (AkUInt32 eArenaType = AkMemoryMgrArena_Primary; eArenaType < AkMemoryMgrArena_NUM; eArenaType++)
{
AK::MemoryArena::AkMemoryArenaSettings& arenaSettings = memSettings.memoryArenaSettings[eArenaType];
// 모든 설정에 대한 기본값을 설정합니다.
arenaSettings.bEnableSba = true;
arenaSettings.uSbaInitSize = 0;
arenaSettings.uSbaSpanSize = 16384;
arenaSettings.uSbaMaximumUnusedSpans = 1;
arenaSettings.uTlsfInitSize = 2 * 1024 * 1024;
arenaSettings.uTlsfSpanSize = 2 * 1024 * 1024;
arenaSettings.uTlsfLargeSpanSize = 8 * 1024 * 1024;
arenaSettings.uTlsfSpanOverhead = 128; // std::malloc in particular appears to generate 128B of overhead for our large allocations
arenaSettings.uTlsfMaximumUnusedMediumSpans = 1;
arenaSettings.uTlsfMaximumUnusedLargeSpans = 1;
arenaSettings.uAllocSizeLarge = UINT_MAX;
arenaSettings.uAllocSizeHuge = 4 * 1024 * 1024;
arenaSettings.uMemReservedLimit = 0;
}
// ... 다음 경우는 제외:
// 기본 힙은 더 큰 uTlsfInitSize 와 uSbaInitSize 로 초기화되어야 합니다.
// 거의 모든 프로젝트에 많은 양의 데이터가 들어가므로
// 미디어 힙에는 SBA가 전혀 없어야 합니다.
// "optimized"(즉, 릴리스) 구성에 있는 경우 "profiler" 아레나는 전혀 초기화되어서는 안 됩니다.
#if defined(AK_OPTIMIZED)
#endif

AkMemoryArenaSettings 할당 콜백

AkMemoryArenaSettings::fnMemAllocSpanAkMemoryArenaSettings::fnMemFreeSpan 의 경우 콜백에는 다음과 같은 요구 사항과 동작이 필요합니다.

  • fnMemAllocSpan 은 요청된 크기의 메모리 할당에 대한 포인터만 반환하면 됩니다. 반환된 할당에는 반환된 메모리의 정렬과 관련된 요구 사항이 없으며, 다른 이전 메모리 할당과 연속될 필요도 없습니다.
  • fnMemFreeSpan 은 주어진 주소의 메모리만 해제하면 됩니다.
  • fnMemFreeSpan 은 이전에 fnMemAllocSpan 을 통해 반환된 주소로만 호출됩니다. 크기 매개 변수는 할당이 처음 요청된 값과 동일합니다.
  • fnMemAllocSpan 을 실행하는 동안 임의의 값을 out_userData 에 쓸 수 있습니다. 이 값은 fnMemFreeSpan 에 대한 동등한 호출에 in_userData 매개 변수로 제공됩니다.

콜백은 구현에 있어서 매우 유연할 수 있습니다. 예를 들어 다음과 같은 것도 사용할 수 있습니다.

void* AllocSpan(size_t size, size_t* out_userData)
{
return std::malloc(size);
}
void FreeSpan(void* address, size_t size, size_t in_userData)
{
std::free(address);
}

Advanced Profiler의 Memory Arena 탭에는 현재 할당된 모든 스팬이 나열되며, 각 스팬의 주소 및 사용자 데이터 값은 이러한 콜백에서 반환된 값과 일치합니다. 이는 디버깅할 때 유용하며, 특히 다른 디버깅 및 프로파일링 도구와 함께 사용하는 경우 더욱 유용하게 사용됩니다.

AkMemoryArena 구성에 대한 권장 사항

AkMemoryMgr 가 관리하는 AkMemoryArenas 에 대한 기본 설정은 초기 메모리 예약을 낮게 유지하고 다른 주요 함정을 피할 수 있도록 조정됩니다. 하지만 프로젝트의 필요에 맞게 이러한 설정 중 대부분을 조정하는 것이 좋습니다. 지능적인 튜닝을 통해 Wwise의 메모리 예약, 게임 엔진의 전체 메모리 예약, Wwise의 CPU 성능이 크게 최적화될 수 있습니다. 프로젝트에 가장 적합한 것을 찾기 위해 실험해 보거나 고려해 볼 수 있는 몇 가지 제안은 다음과 같습니다.

  • Primary 및 Media 아레나에 대해 AkMemoryArenaSettings::uTlsfInitSize 를 설정하여 일반적인 메모리 사용 또는 총 메모리 예산과 일치시킵니다. 일반적으로 더 큰 Base 스팬은 TLSF 알고리즘에 대한 더 나은 메모리 조각화를 가져옵니다. 단일 스팬을 사용하면 보조 메모리 스팬에 대한 요청이 이루어질 때를 확인하여 메모리 예산이 초과되는 시점을 모니터링할 수도 있습니다. 또한, 시작 시 전체 시스템 메모리 예약이 장시간 플레이한 후의 전체 시스템 메모리 예약을 더 잘 반영하기 때문에 애플리케이션 전체의 메모리 예산을 세우는 데 도움이 될 수 있습니다.
  • 게임 플레이 중 일반적인 SBA 예약 요구 사항과 일치하도록 Primary AkMemoryArena 에 AkMemoryArenaSettings::uSbaInitSize 를 설정합니다. Advanced Profiler의 Memory Arenas 탭을 사용하여 일반적인 게임 플레이 중 SBA 예약 요구 사항을 측정하거나 특정 하이 워터마크를 찾고 uSbaInitSize 를 해당 대상과 일치하도록 설정합니다. 이 값을 더 큰 값으로 설정하면 더 많은 SBA 메모리 할당이 메모리의 초기 영역에 배치되고 개별 메모리 할당에 대한 오버헤드가 없는 이점을 얻을 수 있습니다. 이를 통해 TLSF 힙에 할당된 SBA 스팬 수를 줄여 Primary TLSF 힙에서 장기 파편화를 줄일 수도 있습니다.
  • 또는: AkMemoryArenaSettings::uTlsfInitSize 를 더 낮은 값으로 설정하여 다른 시스템에서 메모리를 회수합니다. 메모리 파편화로 인한 잔여 효과가 거의 없이 상당한 양의 메모리를 깨끗하게 해제할 수 있는 게임플레이 시나리오가 있는 경우, 다른 시스템에서 메모리를 사용할 수 있도록 Primary 또는 Media 아레나의 uTlsfInitSize 를 낮추는 것이 더 나을 수 있습니다.
  • 또는: AkMemoryArenaSettings::uTlsfMaximumUnusedMediumSpans 의 더 큰 값을 설정하여 메모리 예약 워터마크를 찾습니다. 기본적으로 uTlsfMaximumUnusedMediumSpansuTlsfMaximumUnusedLargeSpans 는 사용되지 않는 메모리를 쉽게 회수하기 위해 1로 설정됩니다. 이 값을 일시적으로 더 높은 값으로 설정하면 스팬이 할당되어 해제되지 않으므로 메모리 예약 워터마크를 식별하는 데 도움이 될 수 있습니다.
  • Large 메모리 할당을 사용하여 파편화를 완화합니다. 기본적으로 Large 메모리 할당은 비활성화되어 있지만 어떤 상황에서는 특정 크기의 할당을 물리적으로 서로 분리하여 장기적인 시스템 파편화를 완화하는 것이 바람직할 수 있습니다. uAllocSizeLargeuTlsfLargeSpanSize 에 적합한 값을 찾기 위해 몇 가지 실험을 해 보는 것이 좋습니다. 더 많은 스팬에 걸쳐 메모리가 사용되지 않은 채로 남아 있기 때문에 초기에는 전체 메모리 예약이 늘어날 수 있지만, 시간이 지남에 따라 메모리 파편화가 줄어들 수 있습니다. Medium과 Large 할당은 모두 사용 가능한 공간이 있는 경우 Base 스팬에 할당됩니다.
  • AkMemoryArenaSettings::uAllocSizeHuge 를 낮춰 내부 파편화를 줄입니다. Huge 할당은 스탠드얼론으로 간주되므로 내부 메모리 파편화의 영향을 받지 않습니다. fnMemAllocSpanfnMemFreeSpan 에 대한 빈번한 호출로 인해 발생하는 추가 CPU 비용과 외부 파편화를 관리할 수 있다면, Huge 할당으로 간주되는 스레숄드를 낮춰 해당 카테고리에 더 많은 메모리를 할당하는 것이 바람직할 수 있습니다.
  • AkMemoryArenaSettings::uTlsfSpanOverheadfnMemAllocSpan 구현의 할당 메타데이터 크기와 일치하도록 설정합니다. fnMemAllocSpan 구현이 자체적으로 일부 메타데이터를 필요로 하는 메모리 할당을 생성하는 경우 해당 메타데이터의 크기를 측정하고 uTlsfSpanOverhead 를 해당 크기와 일치하도록 늘립니다. 이 값은 요청된 TLSF 스팬의 크기를 약간 줄이는 데 사용되며, 이를 통해 fnMemAllocSpan 의 할당이 의도한 메모리 양을 매핑하는지 확인하는 데 도움이 됩니다. 예를 들어, 원래 2.00MiB(2,097,152바이트)여야 하는 TLSF 스팬 크기는 메모리 할당 메타데이터에 대한 추가 메모리 페이지가 필요하기 때문에 실제로 매핑된 메모리 크기는 2.02MiB(2,113,536바이트)가 될 수 있습니다. 그러나 128바이트의 메타데이터가 필요할 것으로 예상되는 경우 uTlsfSpanOverhead 를 해당 값으로 설정하여 요청된 TLSF 스팬 크기에서 이 양을 뺄 수 있습니다. 이 예시에서 요청된 TLSF 스팬 크기는 2,097,024바이트이고, 정확히 2.00MiB의 메모리가 매핑되어 낭비되는 물리적 메모리 양이 줄어듭니다.
AK::MemoryArena::AkMemoryArenaSettings memoryArenaSettings[AkMemoryMgrArena_NUM]
Configuration of memory arenas for default memory allocator. For more information,...
@ AkMemoryMgrArena_Primary
@ AkMemoryMgrArena_Profiler
AkForceInline void FreeSpan(void *address, size_t size, size_t in_userData)
@ AkMemoryMgrArena_NUM
@ AkMemoryMgrArena_Media
uint32_t AkUInt32
Unsigned 32-bit integer
AkForceInline void * AllocSpan(size_t size, size_t *out_userData)

이 페이지가 도움이 되었나요?

지원이 필요하신가요?

질문이 있으신가요? 문제를 겪고 계신가요? 더 많은 정보가 필요하신가요? 저희에게 문의해주시면 도와드리겠습니다!

지원 페이지를 방문해 주세요

작업하는 프로젝트에 대해 알려주세요. 언제든지 도와드릴 준비가 되어 있습니다.

프로젝트를 등록하세요. 아무런 조건이나 의무 사항 없이 빠른 시작을 도와드리겠습니다.

Wwise를 시작해 보세요