バージョン

menu_open
Wwise SDK 2023.1.2
メモリ使用量を抑えるヒント

メモリの使用量を定められた制限内に抑えるのは、難しいことがあります。以下は、メモリ使用量を抑えるのに役立つ、幾つかのヒントです:

Objectメモリ

Objectメモリの使用量は、メモリにロードしたサウンド数やイベント数、そしてゲームオブジェクトの量によって直接、左右されます。これはプロジェクトがサウンドデザインの実装に必要とするオブジェクトすべてのプロパティを含んでいます。また、すべてのゲームオブジェクトとそれらの関連する情報 (ゲームシンク値、位置、向きなど)も含みます。より多くのバンクをロードすると、より多くのメモリアロケーションが必要となります。必要なサイズは、一つのシナリオ、レベル、マップ、ゲームエリアなどで一度に再生する可能性のあるサウンド数に依存します。このアロケーションを減らすには、以下のような心がけが役立ちます:

  • 多数のサウンド構造やEventを入れた大きいサウンドバンクは、いくつかの小さいサウンドバンクに分割する。目安としてAdvanced ProfilerのSoundBanksタブを開けば、それぞれのSoundBankがどれだけのメモリを消費しているかをObject Memory列で確認できます。そして必要に応じてSoundBankを動的にロード、アンロードできます。これらの分割は戦略的に考えてください。例えば、ダイアログSoundBankを分割する場合には、単一のキャラクターのすべてのセリフを含むバンクの作成を避けます代わりに、コンテキストに従ってダイアログをグループ化します。
  • AK::SoundEngine::ExecuteActionOnEvent API を利用して、イベント数を減らす。Play/Stop のペアを単一のPlayイベントに置き換えて、AK::SoundEngine::ExecuteActionOnEvent の "ExecuteActionOnEvent" を呼び出し、Stop ならびに Pause/Resume します (同じ Play イベントになります)。
  • ゲームオブジェクトを細かく管理すること。役割が終わったものは、すぐに登録を解除します。全くメリットがない上に、メモリを消費してしまうので、使用しないゲームオブジェクトのプールを生かしたままにしないでください。例えば、NPC が死んだ場合を考えてください。そのゲームオブジェクトの登録を解除します; 何か別のことに再利用しないでください。必要な場合には、新規のものを登録します。基本的な考え方として、数千個のゲームオブジェクトが生きている状態は、多すぎると言えます。
  • アクターミキサー (Actor-Mixer) をサウンドを構成するためだけに使用しないこと。フォルダとワークユニットはメモリを消費しませんが、アクターミキサーは消費します。デフォルトでない同様のプロパティを共有する場合には、そのプロパティはそこに一度しか存在しないのでメモリを節約することができます。もちろん、アクターミキサーが、SetVolumeや、SetPitchなどのイベントにレファレンスされるかどうかにもよります。
  • 大きい階層は、サイズや複雑性を減らすように努力すること。よくある大きい階層として、「Impact(衝撃)」階層や、「Footstep(足音)」階層などがあります。これらは変数が多いため、サイズが大きくなり、構造のだめのメモリを多く必要とします。このような階層を小さくする方法を、以下にいくつか示します。
    • 変化するのが、単純なプロパティであれば、RTPCを使う(サンプルは同じで、ボリューム、ピッチ、ランダマイザーなどが変わる場合)。
    • Switch Container階層を、複数のサウンドバンクに分けることができます。サウンドバンクマネージャでは、Switch コンテナを含む際、すべてのその分岐も含みます。しかし、SoundBank Editor ビューの theGame Sync タブ、または Edit タブで、分岐の幾つかを手作業で除外することができます。例えば、Footstep 階層では、最初の Switch 変数は Surface Type (地面の種類) かもしれません。その場合、Switch を異なるサウンドバンクに分けて、コンテキストによってそれらをロードします。メインの Footstep サウンドバンクには、都市環境のコンクリートや金属の階段など、ゲーム全体で遭遇する地面を含み、他のコンテキストによるサウンドバンクは、ゲーム中の一つのシーン/セクションのみに使用される泥の表面など、特定の地面を含みます
  • 「外部ソース」を利用して、Wwise アクターミキサー階層が提供するような多くの制御を必要としないサウンドのオーバーヘッドを減らす。これは通常ボイスオーバーに向いています。

Processingメモリ

Processingカテゴリのメモリは、サウンドの再生に使います。これには解凍のためのバッファを含み、エフェクトを適用し、オーディオソースをミックスします。一度に再生するサウンドの数に直接影響されます。また、同時に使うエフェクトの合計数や種類にも影響を受けます。削減するには、同時にいくつのサウンドを聞かせたいのかを決める必要があります。ゲームによって、サウンドが10個以上聞こえるシナリオがほとんどないものもあれば、100個のゲームもあります。最悪のケースを考える必要があります。

ガイドラインとして、一部のゲーム (Xbox One) でプロファイリングを行い、次の数値を得ました:

  • 1MBで、約42個のボイスを再生
  • 2 MB で約96個のボイスを再生 ほぼ比例関係にありますが、どのコーデックを使用しているか、エフェクトの数、およびその他の要素に依存します。例えば、Vorbis コーデックでは、質の設定によりボイスあたりのメモリは50ほど多くなります。一度に170個のサウンドを再生するとします: これは恐らく理解不能で、役に立たないでしょう。しかし、ゲームのために理想的な本当の数字を見るけるための実験が必要です。プロファイラーの Memory タブを利用して、ゲームで複数のシナリオをプロファイルして、リソースでどれくらい使用しているかに留意します。

処理に使用するメモリ量を減らすには、同時ボイス数を減らしてください。それには次を利用します:

  • 再生制限(Playback Limits):Advanced Settingsの設定。例えば、跳弾50弾分のサウンドが聞こえる必要が、本当にあるのか。必要なければ、その数値を例えば15に制限します。
    注釈: また、バスの数も制限できます。
  • Priority (優先度) : Advanced Settingsの設定。例えば、弾丸は、ダイアログほど重要でないとします。そこで、サウンド数が多すぎる場合は、まず弾丸の再生を落します。Playback limits(再生制限)と組み合わせて使います。
  • Distance-based Priority Offset(プライオリティの、距離に基づくオフセット):Advanced Settingsの設定。一般的に、遠くにあるオブジェクトは、近くのものほど重要ではありません。例えば、10m先にある弾丸の音は、もっと近くに弾丸サウンドが15個ある場合は、聞こえる必要がありません。
  • Below Threshold Behavior(ボリュームしきい値以下の動作):Advanced Settingsの設定。負荷が最も低い動作(CPU、メモリ)は、「Kill Voice(ボイスを消す)」です、非ループサウンドに有用です。次に望ましいオプションは、「Send To Virtual(バーチャルボイスリストに送る)」+「Play from beginning(最初から再生)」であり、その次は「Send To Virtual(バーチャルボイスリストに送る)」+「Resume(再開)」、その次は「Send To Virtual」+「Play from elapsed time(経過した時間から再生)」と続きます。最も負荷が高いのは「Continue to play(再生を続ける)」と、「Play from elapsed time(経過した時間から再生)」のオプションです。Wwiseのデフォルト値は「Continue To Play(再生を続ける)」なので。
  • Volume Threshold (ボリュームしきい値) :Project Settingsの設定。これは、小さすぎて聞こえないようなサウンドをキルする(消す)ために使います。この設定と共に使われるのは、閾値以下の動作設定(Below Threshold Behavior)や、遠くに行けば一般的に音が小さくなる減衰(Attenuation)設定です。
    注釈: プログラム的にボリュームのしきい値をランタイムで変更できます。「ボリュームしきい値以下」の状態により多くのボイスを送るために、より処理が重くなるゲームの箇所でこれを利用できます。
  • 使用したコーデック設定への変更 (Conversion Settings)。Vorbis は、オーディオを解凍するために余分なメモリが必要です。異なるパラメータが、必要量を増やしたり、減らしたりします。しかし、そのコストも充分に考慮する必要があり、コーデックを変えたり圧縮率を下げたりするとProcessingメモリに対する負荷が軽減される一方、ファイルをバンクにロードするのであれば、メモリ内のファイルサイズが大きくなってしまいます。場合によっては、Processingメモリの使用量を500 KB増やしてでも、Media メモリで数MBセーブできるのであれば、オーディオ予算全体の節約につながります。
  • 質を少なく、または低くする。一部のエフェクトは処理に多くのメモリを必要とします。非常に一般的に、利用可能などの場合においてもメモリを多く消費するのが Reverb エフェクトです。現実的には、ゲームは非常に少ない数のリバーブしか同時に実行できません。ルールとしては、4個未満を推奨します。また、リバーブの質を低くする、長さを短くすることは助けになります。

メディアメモリ (サウンドバンク)

サウンドバンク(SoundBank)のメモリ消費は主に、中にあるサウンドデータに起因します。サウンドデータ(メディア)のメモリ消費は、以下のテクニックで抑制できます。

  • 多数のサウンド構造やEventを入れた大きいサウンドバンクは、いくつかの小さいサウンドバンクに分割する。必要に応じて、ロード、アンロードします。
  • ディスクからストリーミングするサウンドの数を増やす(サウンドオブジェクトのプロパティ)。レイテンシに敏感なサウンドは、事前にフェッチしたメディアを使うことができ、 PinEventInStreamCache APIを使用して事前にロード、またはオンデマンドのキャッシュにストリームすることができます。
  • APIの、PrepareEvent()を使う。
  • オーディオの圧縮率を上げる(コンバージョン設定、コーデックなど)。
  • サンプルレートを下げる。Automatic Sample Rate Detection(サンプルレート自動検知)機能を検討してみる(Conversion Settings)。
  • 風(Wind)関連のサウンドを、プラグインSoundSeed Wind/Wooshの同等サウンドに置き換える。風のアンビエントサウンドは、ループサウンドであることが多く、メディアスペースをかなりとります。ブレードのヒューという音、 プロペラ、窓を開けた車での風が勢い良く流れる音、換気の騒音、その他はこのプラグインで作り出すことができます。また風とは関係のない応用も考えられます: どのような騒々しい音も作りだすことができます。例: 海の波、または遠くから聞こえる高速道路の音など。

Tuning "Temp Alloc" Memory

Wwise uses an internal pool of memory to manage some temporary allocations that persist for less than one audio-render tick, which are represented in the Advanced Profiler's Memory tab as "Temp Alloc". These temporary allocations exist for a specific amount of time, have very little overhead, are handled internally by the sound engine, and cannot be forwarded to developer-provided memory allocation hooks. Instead, the only allocations in this regard that are observed by the Advanced Profiler and memory allocation hooks are the larger memory blocks that the temporary allocations are made from. Therefore, it might be desirable to manually tune the management of "Temp Alloc" memory blocks, in order to better optimize memory usage in your game.

During AK::MemoryMgr::Init, AkMemSettings::tempAllocSettings controls the behavior of the memory blocks for each Temp Alloc category. Notably, this includes configuring the size of the memory blocks, the minimum number of blocks that the system keeps allocated at all times, and how many blocks have to be unused for a tick before the system starts freeing memory. You can use AK::GetTempAllocStats() to see how much memory the Temp Alloc system uses in your game at runtime, and better fine tune configuration of the system.

The following are some suggestions depending on your game's requirements, or other behavior observed during profiling:

  • If you are not concerned about the overhead of allocating and freeing the memory blocks, or the memory fragmentation that is incurred when the memory blocks are freed, it might be desirable to set AK::TempAllocInitSettings::uMinimumBlockSize to a lower value than the default, so that it better matches the memory usage of your game's needs at any given time.
  • If the allocation and freeing of blocks causes excessive memory fragmentation, you can measure AK::TempAllocStats::uPeakMemUsed to view the Temp Alloc system's peak memory usage, and then ensure that the AK::TempAllocInitSettings::uMinimumBlockCount is set to a high enough value so that all of the blocks you might use are allocated when the sound engine is initialized, and never freed afterward.
  • If you want to avoid freeing memory blocks without evaluating your peak memory usage, you can set AK::TempAllocInitSettings::uMaximumUnusedBlocks to a high value to ensure that the system can allocate new blocks, but not free them, even during periods of low memory load.
  • If you are using the Job Manager for audio rendering, as described in Leveraging the Job Manager for Concurrent Execution of Audio Rendering Jobs, the number of memory blocks will increase. This is because the memory blocks are all thread-local, and one memory block is typically allocated by each active worker. It might be desirable to lower AK::TempAllocInitSettings::uMinimumBlockSize so that using more workers does not cause a significant increase in used memory in your game.
  • If your memory allocation system includes some metadata adjacent to large memory allocations, it might be worth ensuring that the amount of memory allocated by the memory blocks does not cause a significant amount of waste. Given a requested allocation of 2048 KiB, some memory allocation systems might actually map 2112 KiB of memory. However, a requested allocation might of 2047 KiB would map 2048 KiB of memory. The block sizes do not need to be powers of two, or exactly matched to page sizes, so it might be preferable to set AK::TempAllocInitSettings::uMinimumBlockSize to a slightly reduced value than intended in order to mitigate waste in this regard.

Some debugging options are available in AK::TempAllocInitSettings. In the Debug and Profile configuration of the sound engine, AK::TempAllocInitSettings::bDebugDetailedStats and AK::TempAllocInitSettings::bDebugEnableSentinels are enabled by default in order to improve tracking of usage statistics, and to provide some easy detection of buffer overruns. Disable these options when the highest performance, or most accurate profiling data, is required for your application. Support for these options is removed entirely in the Release configuration of the sound engine.

Tuning "Span Count"

If your Memory Manager integration relies on Wwise's integration of rpmalloc, it might be desirable to adjust AK::MemSettings::uVMSpanCount and AK::MemSettings::uDeviceSpanCount in order to reduce the amount of memory reserved by the system. There are three options available for these settings, which provide different trade-offs for CPU and Memory use: AkSpanCount_Small, AkSpanCount_Medium, and AkSpanCount_Huge.

AkSpanCount_Huge is the default value, which offers the best CPU performance by reducing the number of calls made to AkMemSettings::pfAllocVM, but also because in supported integrations, and on some platforms, memory mappings can be made using 2MiB pages, instead of 4KiB or 16KiB pages. Utilization of 2MiB pages can reduce the number of translation lookaside buffer (TLB) misses during sound engine execution, and help improve overall CPU performance.

AkSpanCount_Small adjusts the amount of memory requested at any given time to be as low as 64KiB. This can reduce the amount of memory reserved by Wwise, but can increase the amount of CPU usage due to an increase in calls to AkMemSettings::pfAllocVM. Depending on your implementation of the AkMemSettings::pfAllocVM callback, this might also prevent the usage of 2MiB pages for memory mappings.

AkSpanCount_Medium balances memory and CPU usage, by requesting memory blocks as low as 512KiB. This can reduce the number of calls to AkMemSettings::pfAllocVM compared to AkSpanCount_Small, but still might prevent the usage of 2MiB pages for memory mappings.

注釈: If your implementation of AkMemSettings::pfAllocVM provides blocks of pre-mapped memory, and rarely invokes a system call for a new memory mapping, we strongly recommend that you use a setting of AkSpanCount_Small because the relative cost of calls to AkMemSettings::pfAllocVM should be greatly reduced, and your pre-mapped memory might already be using 2MiB pages.

このページはお役に立ちましたか?

サポートは必要ですか?

ご質問や問題、ご不明点はございますか?お気軽にお問い合わせください。

サポートページをご確認ください

あなたのプロジェクトについて教えてください。ご不明な点はありませんか。

プロジェクトを登録していただくことで、ご利用開始のサポートをいたします。

Wwiseからはじめよう