menu
 
バージョン
2024.1.4.8780

2024.1.4.8780

2023.1.12.8706

2022.1.18.8567

2021.1.14.8108

2019.2.15.7667

2019.1.11.7296

2018.1.11.6987

2017.2.10.6745

2017.1.9.6501

2016.2.6.6153

2015.1.9.5624


menu_open
Wwise SDK 2024.1.4
AkMemoryArenasの設定と調整

AkMemoryArenaは、Wwiseサウンドエンジンで使用されるカスタムメモリアロケータです。予約メモリの管理に使用できるさまざまな設定が用意されています。サウンドエンジンでは複数のAkMemoryArenasが使用されます。プロジェクトの要件に合わせてこれらを適切に調整することで、 サウンドエンジンのメモリ予約の処理全体を大幅に改善できます。

AkMemoryArenaの概要

AkMemoryArenaは汎用メモリアロケータとして機能し、すべてのメモリアロケーションをSmall、Medium、Large、Hugeのサイズに基づいて4つの独立したヒープのいずれかに分類します。

256バイト以下のアロケーションはSmallアロケーションです。このしきい値は設定できません。Smallアロケーションは「Small-block allocator(SBA)」ヒープで管理されます。SBAは、すべてのアロケーションを固定サイズのメモリブロックで構成されるスパンで管理するため、メモリフラグメンテーションに関して動作が一貫しています。各スパンはサイズが設定可能で、これらのスパンは親のMediumヒープまたはLargeヒープから割り当てられます。SBAはメモリの先頭リージョンで初期化されるため、SBAヒープのアロケーションで使用されるオーバーヘッドのメモリ容量が削減されます。通常、AkMemoryArenaのメモリアロケーションでは、すべてのサイズクラスにおいてアロケーションのメタデータ用に16バイトのオーバーヘッドが必要ですが、先頭リージョン内のSBAアロケーションでは、そのようなオーバーヘッドは必要ありません。例えば、通常のSBAスパンのサイズが16キビバイトで、64バイトのアロケーションを処理するように設定されている場合、スパンでは80バイトのメモリブロックを約200個処理できますが、同じ16キビバイトが先頭リージョン内に割り当てられている場合に処理できるのは、64バイトのメモリブロックで約250個です。

MediumおよびLargeアロケーションのサイズは256バイトを上回りますが、 AkMemoryArenaSettings::uAllocSizeLargeAkMemoryArenaSettings::uAllocSizeHuge の値よりは小さくなります。MediumおよびLargeアロケーション用のヒープで使用されるアルゴリズムは、「Two-Level Segregated Fit(TLSF)」アルゴリズムをベースとしています。その結果、これらのヒープではO(1)のパフォーマンスで割り当てと解放を実行できます。これらのヒープは最適なメモリアロケーションポリシーを使用して、アロケーションをどこに配置するかを決定します。ただし元のTLSFアルゴリズムと異なるのは、AkMemoryArenaによって使用されるTLSFヒープでも、時間が経過してメモリニーズが増加した場合に新しいメモリスパンを要求できますが、新しいメモリスパンがほかのメモリスパンと隣接している必要がない点です。構成されたすべてのアロケーションが解放されると、TLSFヒープもメモリを解放します。MediumまたはLargeアロケーションが要求されると、TLSFヒープは最初にメモリの先頭のBaseスパンでメモリの空きブロックを見つけようとします。空きブロックがない場合は、次にマッピング済みのMediumやLargeスパンの中でメモリの空きブロックを見つけようとします。それでも空きブロックが見つからない場合は、Hugeアロケーションヒープで新しいスパンの要求が作成され、MediumまたはLargeスパンのリストに追加されます。同様に、アロケーションのないスパンは「未使用」とみなされます。一定数のスパンが未使用になると、システムに解放されます。

Hugeアロケーションは、大きすぎるためMediumやLargeヒープに収まらないアロケーションです。これらのアロケーションは別のスパン内に配置され、ほかのアロケーションとメモリを共有しません。また、時間が経過してもHugeスパンのメモリが再利用されたりキャッシュされたりすることはありません。つまり、構成されるメモリのアロケーションが解放されると、スパンは即時に解放されます。

AkMemoryArenaSettings

AkMemoryMgrの初期化設定には、サウンドエンジンによって使用されるさまざまなAkMemoryArenasを構成するための一連の設定が含まれています。特に断りがない限り、以下に記載するサイズは2のべき乗にする必要はありません。

  • AkMemoryArenaSettings::bEnableSba :SBAをアクティブ化する必要があるかどうかを制御します。非アクティブの場合、SmallアロケーションはすべてMediumアロケーションとみなされて、TLSFヒープに送られます。Mediaアロケーションは一般的にSBAで管理するには大きすぎるため、Media AkMemoryArenaではこのオプションがデフォルトで無効になっています。
  • AkMemoryArenaSettings::uSbaInitSize :SBAヒープで使用されるメモリの先頭リージョンのサイズ(バイト単位)。この先頭リージョンのアロケーションにはメモリアロケーションのオーバーヘッドがないため、占有するスペースが減ります。
  • AkMemoryArenaSettings::uSbaSpanSize :SBAヒープで使用されるメモリの各スパンのサイズ(バイト単位)。値を大きくするとシステムパフォーマンスは若干向上しますが、未使用のまま残るメモリがあるため、無駄になるメモリが増える可能性があります。この値は2のべき乗にする必要があります。
  • AkMemoryArenaSettings::uSbaMaximumUnusedSpans :SBAヒープのメモリの先頭リージョン外で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; // Largeアロケーションではstd::mallocにより128Bのオーバーヘッドが特別に生成されます
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::fnMemAllocSpan および AkMemoryArenaSettings::fnMemFreeSpan のコールバックの要件と動作は以下の通りです。

  • fnMemAllocSpan では、要求されたサイズのメモリアロケーションのポインタを返す必要があるだけです。返されたアロケーションには返されたメモリのアライメントに関する要件はなく、先に行われたメモリアロケーションと隣接している必要もありません。
  • fnMemFreeSpan では、指定されたアドレスでメモリを解放する必要があるだけです。
  • fnMemFreeSpan は、 fnMemAllocSpan を通して前もって返されアドレスを使用してのみ呼び出されます。サイズパラメータもアロケーションが最初に要求された時と同じ値になります。
  • fnMemAllocSpan の実行時に任意の値を out_userData に書き込むことができます。この値は in_userData のパラメータとして fnMemFreeSpan と同じ呼び出しに渡されます。

コールバックは非常に柔軟性の高い実装が可能です。例えば、次のようなコードも使えます。

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 Arenasタブには、現在割り当てられているすべてのスパンと、各スパンのアドレスおよびuserData値の一覧が表示されます。これらの値はコールバックから返された値と一致します。このタブはデバッグの際に役に立ちます。ほかのデバッキングツールやプロファイリングツールと一緒に使うと特に便利です。

AkMemoryArena設定の推奨事項

AkMemoryMgrによって管理されるAkMemoryArenasのデフォルト設定は、初期メモリ予約容量を低く抑えていたり、ほかの大きな問題が回避されるように調整されていますが、プロジェクトのニーズに合わせて、これらの設定の多くを調整することを推奨しています。インテリジェントな調整によって、Wwiseのメモリ予約、ゲームエンジンによるメモリ予約全体、およびWwiseのCPUパフォーマンスを大幅に最適化できます。 以下に示す推奨事項を考慮したり、試したりしながら、プロジェクトに最適な設定を見つけてください。

  • 一般的なメモリ使用量や合計メモリバジェットと一致するようにPrimaryアリーナとMediaアリーナの AkMemoryArenaSettings::uTlsfInitSize を設定します。通常、大容量のBaseスパンを使用すると、TLSFアルゴリズムでメモリフラグメンテーションを改善できます。また、使用するスパンを1つにしてみることで、セカンダリメモリスパンの要求が作成されるタイミングをチェックして、メモリバジェットが超過する時期を監視することもできます。これは、アプリケーション全体のメモリバジェットを決める際にも役立ちます。起動時のシステムメモリ予約量の合計は、一定期間が経過した後のシステムメモリ予約量の合計を忠実に反映しているためです。
  • ゲームプレイ時の一般的なSBA予約要件と一致するように、Primary AkMemoryArenaの AkMemoryArenaSettings::uSbaInitSize を設定します。Advanced ProfilerのMemory Arenasタブを使ってSBA Reservedの要件を測定するか、値が大きい特定のウォーターマークを見つけて、ターゲットと一致するように uSbaInitSize を設定します。これを大きな値に設定すると、メモリの先頭リージョンに配置されるSBAメモリアロケーションが増え、個々のメモリアロケーションのオーバーヘッドがなくなるという利点があります。また、Primary 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アロケーションと見なせるしきい値を下げて、そのカテゴリに直接割り当てられるメモリを増やすことが望ましい場合もあります。
  • fnMemAllocSpan 実装のアロケーションメタデータのサイズと一致するように AkMemoryArenaSettings::uTlsfSpanOverhead を設定します。 fnMemAllocSpan の実装により、それ自身がメタデータを必要とするメモリアロケーションが作成される場合は、メタデータのサイズを測定し、そのサイズと一致するようにuTlsfSpanOverheadを増やします。この値を使用することで、要求されるTLSFスパンのサイズを若干減らすことができ、 fnMemAllocSpan のアロケーションで意図したメモリ容量を確実にマッピングすることが容易になります。例えばTLSFスパンサイズが2.00MiB(2097152バイト)とすると、実際にマッピングされるメモリのサイズは2.02MiB(2113536バイト)になる可能性があります。これは、メモリアロケーションのメタデータ用にメモリの追加ページが必要になるためです。ただし、128バイトのメタデータが必要になると考えられる場合は、要求されるTLSFスパンサイズからそのメモリ量を引いた値になるようuTlsfSpanOverheadを設定できます。この例では、要求されるTLSFスパンサイズは2097024バイトになり、正確に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からはじめよう