目录

优化内存池

Wwise 有两个内存池:

  • Default(默认内存池t):用来存储上层声音结构的通用池。加载 SoundBank 时,这里是非 WAV 数据的存储位置。Game Object 及其相关位置和 RTPC 数据结构也存储在这里。它还包含 Command Queue(命令队列),Command Queue 中存有应用程序发送来的事件,这些事件会由音频线程来处理。最后,它包含少量的与各 voice(声部)相关的上层播放数据。
  • Lower engine(底层引擎内存池):主要的音频处理管线池,在没有播放内容时基本为空。这里分配了所有中间处理用的缓冲区,供解压缩、格式转码、变调、效果处理和混音等操作所用。

确定内存池的合适大小

声音引擎内部内存池的默认大小非常大,以确保初次试用声音引擎的任何人都有足够的资源来运行最极端的应用场景。各个池的默认大小为:

Note.gif
备注: 如果您使用 SDK 的示例代码来集成流管理器,则还会为流播放缓冲区(流播放 I/O)分配 8 MB 内存。

默认内存池的大小将最终取决于您创建的游戏类型。举例而言,如果您的游戏有数千兆字节的音频素材,但很少同时播放四个或五个以上的声音,且不用效果器或者使用的效果器很少,那么默认内存池的内存需求可能较大,而底层引擎内存池的需求则可能较小。另一方面,如果游戏里的声音很少,但会同时播放这些声音,并且播放时使用大量混响、回声和其他环境效果器的话,比如在第一人称射击游戏中的情况,那么默认内存池的内存需求可能较小,而底层引擎内存池的需求则可能较大。底层引擎内存池的大小最终取决于您打算使用声音引擎来执行什么任务。如果游戏将同时播放大量声部(包括虚声部),并处理大量效果器,则您需要让这个池有更大的内存。

设置内存池的大小

在 PC 中,在没有加载 SoundBank 或播放声音的情况下,占用的内存量应大约为 150 KB。您可以在 Wwise 中查看具体的内存占用量,方法是通过切换到 Profiler 布局并在 Performance Monitor 中查看 Total Used Memory 值。此值将随着加载的素材数量、播放的声部数量、游戏对象位置等而增加。

内存池的所需大小取决于大量不同的因素,包括音频质量、已加载的声音数量、同时播放的声部数量、声音结构的复杂性、选择的编码方法、需要处理的效果器类型和数量、3D定位声音的数量、切换开关等。

要了解需要多少内存,唯一可靠的方式是以下的操作:

  1. 为内存池分配任意数量的内存。如果条件允许,则可以先使用默认内存大小。
  2. 将 Wwise 连接到游戏。
  3. 使用声音引擎的 Profile 版本来运行一个复杂的游戏场景。
  4. 查看 Advanced Profiler 的 Memory 选项卡。Peak Used 列的读数将会提示您所需内存池的合适大小。

一般而言,各个池的最佳大小为超出最大内存占用值的 15-20。

在 Communications、Monitor 和 Monitor Queue 内存池中分配有仅用于调试的内存,Release 版本中没有创建这些内存池。从总大小中减去这些池的大小就等于 Release 版本需要占用的内存大小。

Note.gif
备注: 您还可以在不连接到游戏的情况下,在 Memory 选项卡中查看声音引擎的内存占用量,方法是通过从 Wwise 本身直接捕获(Capture)性能分析信息。

开始时我应该使用多大的内存?

在大多数情况下,开始时最好使用默认的内存池大小(每个池 16 MB)。通过设置如此大的内存大小,您可以轻松地了解您的实际内存使用量,然后相应地削减内存池大小。如果您能分配给这些池的内存大小十分有限(16MB 太大),则在开始时您可以使用以下值:

  • 默认内存池:2 MB
  • 底层引擎内存池:2 MB
  • 流媒体管理:2 MB

各个池有 2 MB 应该足以满足大多数场景的需求。流播放缓冲区大小将取决于您是否打算用流来播放大量声音、声音的质量、流播放声音的安全时间要求。对于大多数游戏来说,默认值 8 MB通常被视为是一种内存浪费,但是最好的方式同样是在开始时分配较大的内存,然后在逐渐弄清楚了内存需求量时再进行削减。有关流播放缓冲区内存的详情,请参阅 Audiokinetic Stream Manager 初始化设置

内存池大小和平台

在为各个平台设置池大小时,要理解一条重要的原则:内存池的大小更多地取决于音频内容和用途,而不是平台。这意味着在开始时您可以对各平台使用相同的池大小,然后根据特定的平台在 Advanced Profiler 中的内存读数来调整平台内存池大小。

可为各个内存池设置的最佳大小是多少?这取决于诸多因素,包括:

  • 使用的文件格式
  • 可同时播放的声音最大数量
  • 使用 SoundBank 预加载的声音数量
  • 使用的效果器
  • 每秒钟的事件 /RTPC/ 位置刷新速率
  • 选择的扬声器设置(特别是在 PC 中)
  • 其他相关考虑因素

选择最坏情况进行测试

各个内存池可能具有不同的最坏情况。例如,一次播放六十四个声音会大大增加底层引擎池的占用,而只会微略地提高上层引擎池的占用。另一方面,一次加载 20 个 SoundBank 会提高上层引擎内存占用,而不会影响底层引擎内存池的占用。因此,我们建议不要只选择一种最坏情况用来执行所有测试,因为在其他情形中内存占用可能会不同。

一个特别需要测试的情形是在不同关卡之间加载和卸载 SoundBank。这是因为它会导致上层内存池的占用达到峰值。例如,如果在短暂的间隔中可同时加载游戏关卡 1 和 2 的库,就有可能达到峰值。

Warning.gif
警告: 在执行测试来考察 PC 的内存峰值占用时,必须确保运行游戏的 PC 的扬声器设备配置为 5.1 或更高。这非常必要,因为当扬声器设置为立体声时,声音引擎会执行一些优化,所以可能内存占用比在 5.1 中更少。

运行内存不足

根据“内存不足”(out of memory)条件发生的时机,声音引擎会做出不同的反应。例如,在以下场景中内存不足时会发生以下情况:

  • 声音引擎初始化:初始化失败。
  • 加载 SoundBank : SoundBank 加载失败。
  • 某个参数开始过渡,例如音量:参数直接跳到目标值,不经过任何过渡。
  • 播放声音:播放失败或者停止了另一个低优先级的播放,为新的播放释放内存。

检测内存问题

在使用 Wwise Profiler 时,游戏中每发生一次分配失败就会向捕获日志中发送一条警告通知。您可以经常检查该通知列表,以找到游戏中不同场合下缺少内存的内存池。

内存占用高的原因

以下原因可导致内存占用高:

  • 加载 SoundBank 会导致默认内存池占用升高。注意,各个 SoundBank 使用的内存量不同。默认内存池中的 SoundBank 所使用的内存不取决于 SoundBank 的物理大小,而是它所包含的声音和事件的数量。
  • 某些效果器(包括混响和延时)在播放时要消耗一定量的内存。
  • 一次播放多个声音将极大地提高 Lower Engine 池中的内存占用量。
  • 在较短的时间内发送多个事件动作(action)会提高 Default 池的内存占用。
  • 注册游戏对象、设置“对象相关”参数和设置对象位置全部都会占用少量 Default 池内存。然而,请注意必须注销未使用的游戏对象,以腾出内存。否则内存占用量会持续上升。

以下各节中提供了更多的详情:

定义内存阈值

在初始化声音引擎时,您可以选择为若干个声音引擎内存池定义内存阈值。

您可以通过修改声音引擎的初始化参数值来为内存池定义阈值: AkInitSettings::fDefaultPoolRatioThresholdAkPlatformInitSettings::fLEngineDefaultPoolRatioThreshold

在默认情况下,内存阈值被禁用,默认值为 1(代表 100)。您可以通过将值设置为 0 和 1 之间的任意数来启用它。

在禁用内存阈值后,内存分配器将正常工作。启用后,引擎会定期检查内存占用百分比,确认其低于指定的阈值。如果超出阈值,系统则将开始放弃播放(dropping)最低优先级的声音。

在未使用内存阈值的情形中,引擎将遵守声音的优先级,但是在低内存条件下,引擎可能会没有足够的内存来播放高优先级的声音,这意味着该声音将被放弃。当使用内存阈值时,低优先级的声音将被放弃,以为高优先级的声音腾出空间。

一般您将为AkPlatformInitSettingsfLEngineDefaultPoolRatioThreshold 参数定义阈值。对 AkInitSettings::fDefaultPoolRatioThreshold 参数设置阈值可导致意外行为,因为此参数还用于加载 SoundBank。

参见: