助力音频创造者也意味着将一些资源方面的责任交到他们手中。Wwise作为编辑器和SDK能让您创造一个精益高效的音频环境,遵守最低的CPU预算。另一方面,因为它为用户提供了艺术特色和创作方式的全套武器,所以它也很容易占用很多CPU。因此,为了节约能被游戏用于别处的处理能力,也为了保证流畅的游戏体验,一定要保证高效地使用Wwise。本文旨在帮助程序员和声音设计师找到解决方案,在设计工具或Wwise SDK中赢得宝贵的CPU周期。我们可以确认几个关键要素来确定Wwise是否正以最佳方式使用。本文的重点在于这些关键数据,它们可以在使用Wwise性能分析器时,从Performance Monitor(性能监视器)视图中获取。
第一步是熟悉Wwise Profiling,尤其是Performance Monitor。Profiling, Troubleshooting and Debugging using Wwise 是很好的一篇该主题的文章。
此外,直接在游戏内使用AK::SoundEngine::StartProfilerCapture()是自动创建性能分析会话的好方法。
当使用Performance Monitor时,您可以自定义视图设置来用图像显示需要的数值。这个做法在寻找峰值在何处出现时很有用,也可以与Audio Thread CPU%(音频线程CPU%)图进行相关。
(点击图像放大)
在上面的例子中,我们可以看到Audio Thread CPU(音频线程CPU)峰值似乎和Number of Transitions/Interpolations(转换数/插值数)以及 Number of Voices(Total)(声部数(总数))相对应
Audio thread CPU
Audio thread CPU是做CPU相关决策的主要参考。它应该被视为Wwise渲染要发送给硬件的最终音频帧所需的时间多少。音频帧大小是在通过AkInitSettings::uNumSamplesPerFrame初始化声音引擎时决定的。在Windows平台上,默认长度是1024个采样点。因为原生采样率是48,000 Hz,所以Wwise需要每21.333 ms(就是1,024 / 48,000)提交一个音频帧。如果音频线程花21.333 ms来创建一帧,那么在Performance Monitor上它会显示为100% CPU。一个很好的做法是将Audio thread CPU占用目标定成小于50%,这也就意味着填充一帧的时间少于10.666 ms
丢失一个音频帧(或超出100%占用)可能不是单一音频帧的问题,因为Wwise会提前缓冲不止一帧来保证安全。这个叫做Refills数目,在AkPlatformInitSettings::uNumRefillsInVoice中默认为4。当所有Refills耗尽,并且音频线程没有足够时间在当前帧渲染另一帧时,就会出现Voice Starvation(声部匮乏)错误。如果它的时间超过了好几帧,就会导致听得见的声音断档。请注意,当占比小于100%时,Voice Starvation错误是可以在Capture Log(捕获日志)中显示的。这是因为Performance Monitor刷新率为200 ms,有可能错过CPU峰值。
Voice Starvation有三个主要原因:
1) 音频线程(也叫EventManager线程或LowerEngine线程)被游戏中的另一个线程抢占——在这种情况下,即使Wwise本身处理的内容不多,所显示的百分比依然会很高。音频线程的默认优先级是Above Normal(高于正常) 。让这个线程保持更高的优先级是很重要的。有一种好的做法是通过在AkPlatformInitSettings::threadLEngine 中为支持它的平台强制亲和性来让它保持在同一个CPU核心上。
2) 游戏在Wwise回调函数中处理内容过多。回调中的锁定也会导致音频线程等待,从而显示为更高的CPU占用。
3) Wwise本身处理内容过多。这时,仔细监控不同的性能监视数值就变得尤为重要。
(实)声部数
实声部数对CPU资源有最大的影响。我们应该最先查看这一数值。对于实声部,多少才是一个比较好的目标呢?这个可能更是一个设计问题,更多在于混音听起来应该如何。在记住每个声部CPU占用量不一样的同时,我们也要知道在任何类型游戏中常见的平均数应该在30到70个实声部之间。声道数目,应用的内置属性(如LPF、HPF、音高),以及使用的不同转码设置,都会影响到每声部的CPU占用。比如,解码Vorbis文件会比解码PCM文件使用更多CPU。谨慎选择转码设置就变得很重要了。
有一种直接减少实声部的方式就是使用Playback(回放)限制、优先级、还有虚声部系统。这一点在Wwise help 以及之后的Wwise 101 course material中都有解释。
(虚)声部数
虽然虚声部是用来保存I/O、内存、和CPU周期的,但是该数目小于500是一个很好的信号,表示游戏正在管理活跃游戏对象和“Number of Active Events(活跃事件数)”,后者也是需要注意的数值。虚声部行为的默认选项应是“Kill if finite, else virtual”。这是最简单也是最高效的虚声部选项。它能保证终止掉没有循环播放的听不见的声部,同时让循环播放的声部继续虚拟循环。
插件总CPU
想要在Performance Monitor中和Advanced Profiler(高级性能分析器)里的Plug-ins选项卡中添加Total Plug-in CPU(插件总CPU),需要在性能分析器设置中激活Plug-in Data(插件数据)选项。这一视图会显示目前活跃的实例数,以及它们使用的CPU有多少。这个活跃插件实例的数目会决定Total Plug-in CPU载荷。插入到Actor-Mixer或Interactive Music Hierarchy中的Plug-ins会为每个播放的声音创建一个实例。因为同时播放这么多声音会很快升高CPU占用,所以要考虑渲染复选框,在媒体WEM文件本身中“烘培”Effect。在总线上应用的Plug-ins只会在每条总线上创建一个实例。因此,使用插件的活跃总线数会对CPU产生实质影响,而不是实际播放的声音数。
插件的另一个对CPU有影响的可变选项是处理的声道数。比如,在Actor-Mixer Hierarchy内单声道上活跃Effect的三个实例(三声道),相比7.1总线上活跃Effect的一个实例,消耗资源更低。同样,当我们知道所有实例占用的声道总数小于一条总线的声道数时,将Effect插入到Actor-Mixer会更有好处。对所有Effect插件,CPU成本随着需要处理的声道数增加而线性增加。唯一的例外是Reverbs(混响)——它们的每声道成本接近于一条水平线,而且在大部分情况下最好是在Auxiliary Busses上使用。
已注册游戏对象数
有些游戏对象可能在长时间内未激活。所以一个好的方法就是应用剔除并将其注销。这是为了避免经历很长时间来更新清单上对象的位置或其它参数,不论是由游戏进行还是在声音引擎本身内进行。已注册游戏对象数多少才是最好?有些开放世界游戏能让这个数字保持在80以下,而别的开发者会决定在某个地图/关卡内让所有对象永久保持活跃,在保持良好性能的前提下让数字达到1000以上。尽管如此,在处理一长串游戏对象的清单时,出现性能问题的可能性还是会更高。此外,当游戏的已注册游戏对象清单短一些时,在Profiling布局中定位问题会更简单。
API调用
在游戏中,位置、声笼值、或者游戏同步数值多久更新一次?这些调用是分布于若干游戏帧中还是一帧内会有一连串SDK调用?是不是所有游戏对象都需要每帧更新它们的RTPC值?通过在Profiler Settings(Alt+G)中激活API调用选项,您能确认是否在每一帧对Wwise进行了过多或者无用的API调用。
转换/RTPC插值数
对于Performance Monitor,转换(transition,不要和music transition音乐过渡混淆)是依据特定速率/曲线的属性增加或减少。最常见的转换就是在淡变过程中的Volume(音量)。基本上任何由RTPC可控的属性都可以随着时间产生转换,每个转换都需要声音引擎的少量处理。当这个数值超过500时,我们要把它当成CPU峰值的潜在祸首。有个例子可以展现出当使用Game Parameter插值结合内置参数(如Distance)时,创建转换会变得容易;它会在每次游戏对象或听者移动时生成转换。
低端平台和移动端
利用Wwise子平台系统(见 Managing Platforms),结合linking 和 exclusion 功能,在应对不那么强大的处理器时会变得很重要。因此,对子平台,可能需要更经济地应用以上提到的所有建议。比如对于低端移动设备,您可能想达到的目标是30个实声部而不是70个,活跃的插件实例也更少。我们也会更常见到利用PCM声音来取得质量和低性能成本的优势,尤其对于短声音或频繁重复的声音来说。
结论
总的说,在Wwise内虽然可能有其他因素会对CPU产生影响,但以上提到的数值会在CPU优化时给您最大的回报。
评论