Wwise SDK 2018.1.11
Audiokinetic Stream Manager 初始化设置

Default Streaming Manager Information

本章专门介绍高级 Stream Manager API 的默认实现。

Stream Manager 和 AK::StreamMgr::Create() 方法的初始化设置专门针对 Audiokinetic 的实现,在 AkStreamMgrModule.h 中定义。

以下是 Stream Manager 默认实现的初始化设置描述。 您一定需要调整游戏的这些设置,才能充分利用 I/O 和内存资源。

Stream Manager 设置

AkStreamMgrSettings 结构定义整个 Stream Manager 所需的设置。每个小节中指定的默认值即为 AK::StreamMgr::GetDefaultSettings() 返回的值。这些默认值可能并不适用于您的系统。I/O 技巧、故障排除和优化 中包含的信息可以帮助您选择最佳值。

内存大小

AkStreamMgrSettings::uMemorySize 指定了 Stream Manager 为它本身以及其下所有小对象所创建的内存池的大小:流播放设备、流对象、待处理传输对象、流缓冲区引用、性能分析器流名称、延迟文件打开命令等。即除了自动流 I/O 内存外的一切对象,自动流的内存池是针对各个流播放设备的(通过 AkDeviceSettings::uIOMemorySize 指定)。它应为最小的可能值,但又足够大,不会限制允许播放的流数量。您可以使用 Wwise Advanced Profiler 视图中的 Memory 选项卡来评估(Stream Manager 池中的)小型流对象的内存占用情况。

此内存池所需的大多数内存会在创建流播放设备时分配。运行时分配主要包括流对象本身、其性能分析名称(仅在 DEBUG 和 PROFILE 配置中),以及(如果适用)处理延迟文件打开所需的临时结构(请参阅 延迟打开 )。

默认值:64 KB。

流播放设备设置

AkDeviceSettings 结构定义了使用 AK::CreateDevice() 创建的各个设备所需的设置。每个小节中所示的默认值即为 AK::StreamMgr::GetDefaultDeviceSettings() 返回的值。这些默认值可能并不适用于您的系统。

I/O 内存大小

AkDeviceSettings::uIOMemorySize 是为设备的自动流所保留的内存总大小。设备创建一个专用内存池,自动流 I/O 数据将写入其中。如果您不打算使用自动流,则可以将值指定为零。但请注意,声音引擎会需要使用自动流来播放流音频文件。AkDeviceSettings::pIOMemory、AkDeviceSettings::uIOMemoryAlignment 和 AkDeviceSettings::ePoolAttributes 是直接传递到内存池创建方法 AK::MemoryMgr::CreatePool() 的额外参数。

默认值:

粒度

粒度由 AkDeviceSettings::uGranularity 指定。它定义发送到 Low-Level I/O 的标准请求大小,无论其来自标准流(分片操作)还是自动流(单一流缓冲区的大小)。自动流使用的缓冲区数量不定,具体数量取决于可用的内存量。可用于自动流的缓冲区总数等于
AkDeviceSettings::uIOMemorySize / AkDeviceSettings::uGranularity。

Tip: 为避免内存原因而导致干涸,应至少将流缓冲区数量加倍。因此,I/O 内存池应至少设置为
2 * uGranularity * nominal_number_of_streams
注意,每个流所需的实际缓冲区数量是变动的,具体取决于流启发式算法和设备的目标缓冲长度(请参阅 AkDeviceSettings::fTargetAutoStmBufferLength)。确定您所需要的 I/O 内存大小的正确方式是计算最极端场景中所有流所需的吞吐量之和,然后乘以 fTargetAutoStmBufferLength。在实践中,更简单的方法是首先选取一个大值,通过 Wwise Profiler 分析您的游戏,然后使用 Streaming Devices 选项卡中报告的 I/O 占用率最大值。

默认值:16 KB

调度程序类型

流播放设备调度程序的类型取决于 AkDeviceSettings::uSchedulerTypeFlags。它决定与 Low-Level I/O 沟通的握手模式。带有 AK_SCHEDULER_BLOCKING 标志的流播放设备通过同步握手机制来使用 AK::StreamMgr::IAkIOHookBlocking。带有 AK_SCHEDULER_DEFERRED_LINED_UP 标志的流播放设备通过异步握手机制来使用 AK::StreamMgr::IAkIOHookDeferred。请参阅 高级设备特性 了解有关高级设备调度程序的讨论。

Caution: 将延迟型 I/O 挂钩与 AK_SCHEDULER_BLOCKING 阻塞设备结合使用将导致系统在运行时崩溃。

默认值:AK_SCHEDULER_BLOCKING

I/O 线程属性

所有高层设备都使用单独的线程将传输请求发布给名为“AK::IOThread”的 Low-Level I/O。您可以使用 AkDeviceSettings::threadProperties 来为此线程指定属性。每个平台的 AkThreadProperties 在 SDK/include/AK/Tools/{Platform name}/AkPlatformFuncs.h 中定义。此方法通常指定线程优先级和处理器。

Tip: I/O 调度程序线程应具有高优先级,因为它不会使用大量 CPU:大部分时间它都在等待为流服务,或者等待磁盘控制器。然而,当需要选择任务并将其发布给 Low-Level I/O 时,应保证它能够快速执行,以使存储设备吞吐量最大化。

默认值:针对平台的默认线程属性(由 AKPLATFORM::AkGetDefaultThreadProperties() 返回)的优先级等于 AK_THREAD_PRIORITY_ABOVE_NORMAL(在 AkPlatformFuncs.h 中定义)。

目标缓冲长度

AkDeviceSettings::fTargetAutoStmBufferLength 是设备 I/O 调度程度的启发式算法,仅适用于自动流。它为每个流指定了应该达到的理想缓冲时间,单位:毫秒。Stream Manager 为指定流执行 I/O,直至达到该缓冲长度。会使用流的吞吐量启发式算法,将时间值转换成缓冲区大小。例如,以 44.1 KHz 采样的 16 位立体声需要 172.3 KB/s 的吞吐量。如果目标缓冲长度设为 380 毫秒,则该流的目标缓冲大小约为 64 KB。缓冲越多,流干涸的可能性越小。另一方面,I/O 调度程序会更繁忙,并占用更多的 CPU 和更大的流 I/O 池内存。最佳值主要取决于底层存储设备带宽和可用于流播放的内存量。高速设备应使用较小的缓冲长度,而慢速设备或吞吐量有较大标准差(例如由寻址导致)的设备应使用较大长度。当所有自动流达到它们的目标缓冲长度,而且没有待执行的标准流操作时,I/O 调度程序将闲置。

Tip: 理想的目标缓冲长度与底层设备传输数据的时间成正比。在合理的条件下,可以尝试先使用足够大的 I/O 内存大小,并指定能够保证 Wwise Profiler 中不出现源干涸通知的最小缓冲长度值。确定后,您就可以继而将 I/O 内存大小降低到峰值占用值。

默认值:380 毫秒。

并行 I/O 传输的最大数量

AkDeviceSettings::uMaxConcurrentIO 仅涉及异步底层设备(AK_SCHEDULER_DEFERRED_LINED_UP 调度程序标志)。它是流播放设备在同时并行发布给 Low-Level I/O 传输的最大数量。达到这一极限时,即使流缓冲低于其目标,I/O 线程也将停止向 Low-Level I/O 发布请求。您可以使用此值来安全地分配跟踪各待执行传输所需的静态结构数组。

Tip: 如果指定 1,将通过异步握手机制获得与同步设备相同的行为(AK_SCHEDULER_BLOCKING 调度程序标志)。如果您的 I/O 管理器仅提供异步 API,这可能非常有用。

您也许想将此参数开大,但这样做存在缺点。流播放设备的调度程序会根据检查底层请求时每个流的状态来发布底层请求。如果您让它发送大量请求,并让它们长时间保留在 Low-Level I/O 中,那么期间情况发生改变的可能性较大。例如,流声音可能停止播放或者停止循环。这些情况下,传输将被取消,并且 I/O 数据一旦接收到就会被刷新,这可能导致大量的带宽浪费。

大量的并行请求只可用于吞吐量与请求量不呈线性关系的设备。例如,某些 DMA 控制器可以编程为处理大量传输,但它们的完成时刻通常与编程设定的传输量无关。

默认值:8(将被 AK_SCHEDULER_BLOCKING 调度程序忽略)。

最大缓存比

AkDeviceSettings::fMaxCacheRatio 决定是否启用数据缓存:使用大于 1 的值则启用缓存。

流播放设备支持将数据缓存到它们的流播放池中。对内存块执行 I/O 操作时,文件元数据将被附加。如果同一流或内容相同的流需要数据块在差不多在同一位置对应于同一文件的相同位置,则将直接使用原有数据块,从而避免从 Low-Level I/O 传输。

须知,关键数据结构在创建设备时就已经预先分配(从 Stream Manager 内存池中分配)。在运行时用完内存将导致 I/O 线程以高优先级空转,从而对游戏性能带来灾难性的影响。

通过流数据缓存,特定内存块可能同时具有多个引用。内存块引用是预分配关键数据结构的一个例子。

AkDeviceSettings::fMaxCacheRatio 指定相对于内存块数量最多能有多少个引用。当 AkDeviceSettings::fMaxCacheRatio 为 1 时,则每个内存块只能有一个引用,因此不能进行数据缓存。如果您认为该设备不需要缓存,则应保留 AkDeviceSettings::fMaxCacheRatio 为 1。在此设置下将完全跳过数据查询过程。

如果您将 AkDeviceSettings::fMaxCacheRatio 设为 2,则引用数量是内存块的两倍,并且将进行缓存。在使用此设备创建 Stream Manager 内存池时,流播放设备在内存池中的内存占用率将稍高一些。为了确定此缓存比率能否满足您的需要,请使用 Wwise Profiler 分析您的游戏。在 Profiler 的 Streaming Devices 选项卡中,Caching Available 列中的值指示了还剩多少额外引用。当值为 0 时,将不再缓存,因为设备必须遵守预分配引用的数量规定。此时,即使流缓存中存在有效数据, Low-Level I/O 也会重新填充新的流缓冲区。因此,如果您注意到 Caching Available 在性能分析期间经常下降到接近 0 时,应考虑将 AkDeviceSettings::fMaxCacheRatio 提高到 2 以上,以优化数据缓冲功能的使用。

默认值:1(缓存已被禁用)。