周庭竹:我们了解一下什么是自适应性能,Unity Adaptive Performance (UADP)是开源开放的性能动态调度框架,管理应用设备上的系统状态和性能情况,使开发者主动、及时调整游戏性能和质量设置。
UADP可以帮助开发者利用硬件系统状态、引擎运行瓶颈以及业务输入型号进行深入分析,动态调度负载和应用参数,获得更为可预测的帧率。UADP可以减少热量累积,实现移动端更长的运行时间和更加舒适的玩家体验,保持电池寿命。
为什么需要UADP?我们了解一下移动平台上的几个限制。负载较高的游戏过程中,由于主动冷却系统的缺失导致发热和功耗以及电池带来的电量限制成为手机性能的重要瓶颈。目前手机厂商普遍的方法就是降低CPU和GPU频率,以此降低功耗,但这样就会导致游戏性能直线下降,对游戏体验极为不利。
我们把这种情况叫做温控调频,目前手游开发者是没有办法干预这种情况的。我们通过和各大硬件厂商合作,为开发者提供统一接口,调用系统侧的温控相关信息,方便开发者为自己的游戏定制动态优化的性能方案。
看一看正常情况下温控调频发生的过程。最初是以30FPS帧率开始,由于能源和散热限制,温度上涨到一定程度,就是图中Throttling出现的地方,手机FPS会受到极大的影响,会变得极为不稳定。最后FPS数值只有20,因为刚开始使用高核心频率,这会迅速增加设备温度并发生温控调频,从而导致性能下降。
如何解决这个问题?UADP是否有效?看一看加入UADP前后的性能对比。红色曲线是添加自适应性能之前的游戏频率,蓝色曲线是将UADP添加到游戏中。加入以后游戏稳定在30FPS,即使达到最繁忙的部分仍然不会降低性能并保持相当稳定,不仅可以提供更快的玩家体验,也可以节省电量,让玩家玩得更久。
UADP运作生命周期分为三个阶段:问题探测、定位分析和响应调节。问题探测是收集来自系统侧传感器的信号输入,包括CPU、GPU或者其它模块的温度状态信息。这类系统提供的物理状态信息往往是精度不够的,或者是不直接关联的,所以需要定位分析。定位分析就是引擎内部的运行状态信息,包括CPU、GPU、温度趋势、场景体验,分析定位当前运行的瓶颈所在,再根据分析定位的结果响应调节,动态调度相应的工作负载。
针对问题探测阶段的温度状态信息获取,UADP联合硬件性能厂商向开发者提供温度状态信息,包括温度趋势、温度警告、温度水平。图中就是CPU和GPU结温(结温:冷却器下方未暴露在大气压下的温度,并且会随着工作负载迅速变化,可以获得更为准确的CPU、GPU温度,对改进瓶颈检测很有用)。我们也在积极推动和硬件厂商的合作,希望将来能够把这些更高级的系统API添加进入UADP。
发热指标温度警告信息划分为三个等级:蓝色代表正常,当前温度还比较低,并不需要进行任何调整。黄色代表即将触发温控调频,设备已经上升到一定温度,如果不降低温度很快就会发生热节流,表示目前需要进行调整,不然温度就要撞上温控墙。红色代表调频后节流,时间已经晚了,已经进入温控墙领域。UADP可以让开发人员知道是否处于正常水平,设备节流是否迫在眉睫或者是否已经在节流,帮助开发人员预测热节流时间,允许在游戏逻辑中执行自定义操作以避免节流。
UADP也把温度信息抽象为不同等级,如果当前温度等级持续升高,我们就会考虑做出相应的调整。温度等级是设备温度的归一化值,零代表的是室温,最大值1代表节流任务也就是系统开始干预,这些是后面讲的调度系统的重要输入。
UADP如何做到主动调度性能优化?移动平台上只考虑温度是不够的,刚才提到手机电量有限,维持过高的频率远高出游戏的需要,维持过低的频率会导致游戏性能下降,需要UADP用调整CPU、GPU负载频率实现。我们知道现在游戏优化最大的问题之一就是了解一个游戏是否受到CPU、GPU或者目标频率的限制,UADP检测Unity各个模块运行精确时间以及目标帧率时间,可以直观地分析、判断当前时刻的性能瓶颈,根据当前瓶颈调整相应模块,比如CPU或者GPU工作负载。
看一看UADP的CPU、GPU等级频率调度怎样帮助调整游戏质量。要节省电池电量,降低核心频率是一种方法,同时也可以避免热量聚集。想像一个没有太多事情发生的菜单场景,降低核心频率将减少热量聚集并节省电池,玩家能够玩游戏更长的时间。切换到CPU或者GPU密集区域时可以提高频率,如果热量变高可以将频率降低作为避免节流的一种方法。移动平台复杂变化的环境中,应用会受到很多干扰因素导致性能波动,通过UADP动态调度可以让性能稳定在相对平衡的状态。
除了动态调度性能瓶颈,UADP提供Boost性能模式,让开发者根据业务场景需要设定CPU和GPU 15秒最大频率,包括开团战需要开足马力运行。当然,这会降低电池电量和升高温度,需要谨慎使用该模式。
有了性能瓶颈分析和温度趋势,UADP可以根据这些信息以负反馈的闭环自动控制系统动态调度CPU、GPU的运行状态,从而平衡应用的性能和功耗。
我们来看UADP三个调度组件概念。
Scaler相当于动态调度的输出对象,UADP定义丰富Scaler,有些调整引擎内部参数,有些是系统参数,有些是渲染图形参数,可以让用户根据UADP管线适配Scaler。当然,用户可以在UADP注册自定义的Scaler接受调度的指令,主动调节业务侧的状态数据。
Indexer组件完成自动调度性能优化功能,相当于大脑中枢控制角色,根据调节后反馈的影响因子计算相应的代价函数,实现自适应的调度能力,能够生成温度和性能的行动项代表设备当前的行动状态。所有Scaler动态调度性能代价,综合这些输入和输出的状态信息,Indexer可以判断每个Scaler动态调度性能参数效果和最合适的行动项。UADP会持续完善Indexer动态调度能力,如果用户需要更复杂的调度策略也可以自定义自己的动态调度Indexer,因此UADP是开放开源框架,用户可以自定义几乎每个组件。
了解Scaler和Indexer之后再来看一看Provider,用来对接硬件系统厂商获取暴露的API状态接口,既有输入也有输出。一些状态的输入既可以从系统侧得到,也可以从引擎侧得到,如果系统能够提供更准确的输入,优先使用系统数据,包括GPU Free Time等等。UADP对硬件厂商的接入是开放的,也想和硬件系统厂商紧密合作,给开发者提供系统侧的各种能力,UADP在开发者和硬件系统厂商之间起到的是桥梁和平台的作用。
图中是UADP目前支持的可调节对象,也就是Scaler对象,基本上每个对象都有UADP自己的Sample,欢迎大家下载使用。
这些是我们计划实现的可调节对象,由于时间有限,我这里就不一一展开了。
UADP配置设置菜单可以简单设置每个Scaler对象的开关,当然也可以通过脚本更细致地设置Scaler对象,包括阈值、幅度、等级等等。这里也有Indexer控制参数,包括自动性能模式、Action Delay等等,我们也可以导入不同硬件平台Provider参数,运行时自动加载会合适的Provider调度能力。
一款好的产品相应配套的工具集肯定少不了,UADP配置大量实用工具帮助开发者使用、分析、验证、测试UADP的各种功能。我们已经集成Profiler性能分析器,可以监测GPU、CPU时间、瓶颈、热警告和每个可用缩放其的运行信息,同时也显示温度水平和趋势,很容易看出温度升高还是降低。
我们可以在图中轻松察看当前的性能瓶颈和发热警告,正在运行的性能瓶颈,开始和结束时都有各自的瓶颈,中间还在CPU、GPU以及达到实际目标帧率之间快速切换,这些工具大大方便开发者进行性能分析和验证。
UADP同时支持Device Simulator,就是仿真设备的能力和效果。UADP Recorder可以记录设备的状态信息,然后在Editor模拟、播放每一帧性能变化,同时能够Overwrite更改某个引擎状态和Scaler输出,模拟控制某个时刻的CPU等级或者温度状态。Recorder和Simulator对开发者意义很大,移动设备发热状态和电池电量物理状态在实际情况下很难掌控,通过捕捉记录设备运行数据,并且在仿真器仿真领域可以大大减轻开发者的分析和调试成本。
我们希望有更多的开发者使用UADP,也希望能够多给我们提出意见和建议,让我们把开放框架这件事情越做越好,惠及所有开发者和硬件系统。
看一看UADP的开发计划:
首先是我们正在开发的功能模块,更多的Scaler和Provider是为了更好地完善UnityADP生态系统,也是我们持续不断更新迭代的部分。
利用Unity可视化编程能力,我们快速适配项目可调节对象,该功能雏形已经在UADP5.0使用。
Recorder和Simulator是用户呼声很高的工具链,刚才讲过移动端的物理状态在实际情况下很难获取,我们也在积极和硬件厂商商谈怎样开放相关的API,但我们觉得完善Recorder和Simulator可以大大方便生产效率、降低生产成本、提高产品质量。
游戏应用业务接口会在我们和各大游戏公司合作中不断丰富,争取让开发者快速方便使用UADP。
下面是下一阶段计划开发的功能:
内存自适应调度就是在很多桌面级技术中,经常会有内存和性能的翘翘板,在移动端,内存不仅是有限资源,也会直接关联功耗。大量可调参数可以控制内存使用,为了充分利用内存消耗,我们觉得有必要让UADP自适应调度内存占用。
很多新的手机上已经实现VRS技术,我们认为该技术和UADP是绝配,无论是基于屏幕(模糊周边背景图像)还是基于折扣(模糊不重要物体的渲染)都是UADP Scaler可行的图形参数调度对象。
手机发热和电量有限的情况下往往降低分辨率是更为有效的方法,但直接降低分辨率比较简单粗暴,超分(Super Resolution)保证在不影响最终效果的情况下,通过降低分辨率达到计算负载的目的。
在手机和头显设备动不动就上90-120赫兹的情况下,作为常见的通用优化技术,插帧技术可以显著降低计算负载和功耗。UADP在图形优化技术上有着丰富的工程经验,同时也和很多硬件厂商有深度合作,一起解决这些行业通用问题。我们也会陆陆续续把这些技术能力放如UADP框架解决方案包,欢迎大家使用和咨询。
下面来看几个UADP的长远构想:
传统游戏参数设置往往需要开发者在每个主流硬件平台手动测试和优化,调试出最合适的参数搭配,整个流程烦琐低效,随着游戏内容的升级迭代和硬件平台的更新换代,游戏优化和参数平衡工作量将极大地影响游戏的开发成本和质量。UADP未来希望让参数设置变得自动化,开发者和玩家根据硬件设备调整的各种游戏参数,未来会替代为各种统一的状态输入信号进行精细化调度管理,这些状态信息不再是抽象的硬件型号和固有参数,而是当前环境下的实际计算能力和运行状态,甚至可以通过Benchmark跑分进行大数据统计、云端场景仿真、AI分析获得动态配置,这些配置相当于智能调度系统的输出和输入映射源,让企业能够在负反馈的自动调度系统对各个参数自适应的快速迭代,大大减轻开发者反复迭代优化带来的开发成本。
UADP的长远目标其实是有点宏大的,我们希望游戏应用能够随着硬件能力的不断更新迭代而自适应,尽量延长游戏应用的生命周期。结合UADP Asset Bundle资源流加载功能,游戏主体框架只需要生产一次,游戏内容和元素可以根据设备当前运行状态而不是硬件限制加载和运行。随着新一代硬件的迭代,会有更加适配的游戏内容自适应运行在新的硬件上,使得有更高质量的渲染,运行更加平稳和节省功耗。实现这些并不需要全新构建游戏应用的主体框架,可以说是UADP的理想未来。我们想把游戏生产流程中极为影响生产效率的定制性能优化环节从产品层抽象到引擎层甚至系统层,这些性能优化就会变成自动化、可扩展、自适应的模式,而非Case by Case手工打磨制品。
UADP已经具备强大的跨平台运行生态,升级到跨平台性能优化功能模式,这是我们赋予UADP的一种新的使命。
总结一下:UADP作为一个开放框架,内核是性能优化的动态调度系统,系统输入包括硬件设备系统状态、引擎内部运行状态以及业务层场景信息,系统输出可以是引擎工作负载和各种参数。这些运行参数包括系统层、引擎层和业务层,主要目的是优化应用在长时间使用和变化环境下的平稳高效运行。
UADP框架以插件形式,通过Provider对接各个平台系统接口,充分利用Unity引擎内部运行状态分析调度管理应用的动态参数,也向开发者暴露统一开放的脚本接口和高度定制化的模块、丰富的模板实例,让开发者可以根据自身业务管理引擎和系统各种性能参数与负载,我们也提供一整套工具链方便开发者适配项目和分析仿真验证测试。
以下是包括官方文档在内的资源,欢迎大家使用UADP,加入UADP生态系统,共同构建性能优化的美好未来。
Logo

分享前沿Unity技术干货和开发经验,精彩的Unity活动和社区相关信息

更多推荐