1。背景 某次嘉宾直播重保项目中,直播中出现了声音卡顿、爆音问题,经过排查得出一个结论:嘉宾直播时手机处于充电状态,手机出现发热导致降频,发热降频导致系统采集线程调度出现问题,属于系统行为,影响到系统采集的输入输出,最终出现声音异常问题。 该结论乍一听似乎没什么说服力,很容易让人不认同这个结论,并且有一些质疑问题,比如:问题一:如果是性能问题,为什么她说话感觉不卡,而是爆音的现象?问题二:通过对音视频采集的埋点等信息能更精确的定位吗?发热降频导致的系统采集线程调度出问题,属于系统行为是明确结论还是推断?怎么判定的?问题三:CPU为什么异常变高? 很多同学都知道iOS发热降频这个事情,但是可能不太清楚如何量化影响、如何系统化或者说量化去分析。 本文将基于这个典型案例,做一个系统性的分析,分享iOS发热降频的基本概念与处理经验,希望能够解决大家对iOS发热降频的一些疑惑,帮助大家在下次遇到类似问题时,能够知道如何分析问题、如何发现证据、如何解决问题。2。基本概念2。1。AURemoteIO线程 AURemoteIO:IOThread是系统创建专门用于采集和播放或者说是输入、输出的线程,有两个特点:输入输出是串行的,所以相互之间会受到影响;线程回调时间是稳定的,且要求实时性非常高,如果存在阻塞,会导致输入输出都受到影响,出现声音异常。异常现象会根据阻塞程度不同而不同,轻微阻塞采集数据不连续,严重一些会明显感觉卡顿、爆音,极其严重的情况会直接导致采集线程关掉出无声数据,这一点解释了背景中提到的问题一。2。2。iOS的线程调度2。21。概述 由于Mach具有处理器集的抽象,所以从某个角度说,Mach比Linux和Windows更擅长管理多核处理器。2。22。上下文切换 暂停某个线程的执行,并且将其寄存器状态记录在某个预定义的内存位置中。当一个线程被抢占时,CPU寄存器中会记住另一个线程保存的线程状态,从而恢复那个线程的执行。 一个线程在CPU上可以执行任意长的时间。CPU寄存器中填满了线程的状态,这个执行过程一直在延续,直到发生下面某种情况:线程终止线程自愿放弃外部中断打断了线程的执行,外部中断要求CPU保存线程状态并且立即执行中断处理代码2。23。优先级 每一个线程都被分配了优先级,优先级直接影响线程被调度的频率。每一个操作系统都提供了一个这种优先级的范围:Windows有32个优先级,Linux有140个优先级,Mach有128个优先级。 内核线程的最低优先级为80,比用户态线程的优先级要高。可以保证内核以及用户维护管理的线程能够抢占用户态的线程。2。3。iPhone性能与电池的关系 苹果系统在进入低电量模式时都会回收一部分系统资源,降低处理器主频来保证系统的稳定性,也就是我们俗称的降频。 在需要更极端的性能管理的情况下,用户可能会发现以下影响:App启动时间变长滚动时帧速率降低背光灯变暗(可在控制中心手动调整)扬声器音量降低幅度高达3dB部分App的帧速率逐渐降低在最极端的情况下,相机闪光灯会被停用(会显示在相机用户界面上)在后台刷新的App在启动时可能需要重新载入 iOS11。1以上系统都有降频策略;系统iOS13。1,默认开启降频功能,但用户可以手动选择关闭。iOS系统常见的降频策略有:如果主动设置了省电模式,系统会主动降频。如果硬件设备老化,如电池老化(设置电池容量峰值80),也会出现降频。CPU占用上升较快时,会加快降频。2。4。能效 苹果系统在发热严重时同样会降频甚至降核。 Stateconstant Impact Recommendedaction NominalNSProcessInfoThermalStateNominal Thedevicestemperaturerelatedconditions(thermals)areatanacceptablelevel。Thereisnonoticeablenegativeimpacttotheuser。 Nocorrectiveactionisnecessary。Asalways,allappsshouldbeproactiveaboutoptimizingenergyuse,inordertohelpensurethatthermalsdonotbegintorise。Forexample,discretionarybackgroundworkshouldbeassignedqualityofservicelevelsandscheduledforexecutionatoptimaltimesusingNSBackgroundActivityScheduleroranNSURLSessionbackgroundsession。 FairNSProcessInfoThermalStateFair Thermalsareminimallyelevated。Ondeviceswithfans,thosefansmaybecomeactive,audible,anddistractingtotheuser。Energyusageiselevated,potentiallyreducingbatterylife。 Althoughnocorrectiveactionisrequired,reachingthislevelprovidesanopportunityforgreaterproactiveaction。AnappcanbeginreducingCPUusageandenactingotherenergysavingmeasurestohelpensurethatthethermalstatedoesn’triseanyfurther。 SeriousNSProcessInfoThermalStateSerious Thermalsarehighlyelevated。Fansareactive,runningatmaximumspeed,audible,anddistractingtotheuser。Systemperformancemayalsobeimpactedasthesystembeginsenactingcountermeasurestoreducethermalstoamoreacceptablelevel。 Appsshouldbegintotakecorrectiveactiontohelpthesystemreducethermalsandcreateamoreoptimaluserexperience。Toachievethis,whereverpossible,appsshould:ReduceCPUusage。ReduceGPUusage。ReduceIO。Reduceframerates。Uselowerqualityvisualeffects。 CriticalNSProcessInfoThermalStateCritical Thermalsaresignificantlyelevated。Thedeviceneedstocooldown。 AppscanhelpthesystembytakingimmediatecorrectiveactiontoreduceusageoftheCPU,GPU,andIOtotheabsoluteminimumlevelnecessaryinordertorespondtouseractions。Whereverpossible,appscanstopusingperipherals,suchasthecamera。3。某嘉宾直播中iOS发热降频案例分析 某次嘉宾直播重保项目中,发现直播中出现了声音卡顿爆音问题。 排查沟通中,获得反馈: 在开播时没有出现相关问题,开播一段时间后,大概从20:36开始出现声音卡顿、爆音等问题。现象持续到iPhone手机换Android手机之前一直存在。过程中,强杀APP重开也不行。 过程中,存在充电和发热情况。 团队通过业务埋点发现,对应时刻(20:36),嘉宾的电池状态显示在充电(state2),但不是低电量模式,CPU占比131。 C音视频学习资料免费获取方法:关注音视频开发T哥,点击链接即可免费获取2023年最新C音视频开发进阶独家免费学习大礼包!3。1经验分析 从嘉宾侧反馈的信息中,可以抽出几个关键信息:开播时没有出现问题,从20:36开始,说明:直播持续了一段时间后才出现;强杀APP重开也不行,说明:出现异常后,无法恢复,都说重启大法好,其实就是为了排除或者说是恢复命中的异常条件导致的问题,结果这次不好用了;存在充电和发热情况,且CPU占比达131; 从前两个点可以分析出,大概率原因不在代码里。第三点采集到的CPU数据异常高,过往经验正常的值应该在5060左右。由此推测是命中降频了。 那怎么拿出证据呢?3。2系统分析3。2。状态上报 通过观测系统通知,获取电流状态和发热情况,上报埋点可以判断设备及系统情况,也可以响应通知做一些降级策略。注册电流状态通知〔〔NSNotificationCenterdefaultCenter〕addObserver:selfselector:selector(yourMethodName:)name:NSProcessInfoPowerStateDidChangeNotificationobject:nil〕;if(〔〔NSProcessInfoprocessInfo〕isLowPowerModeEnabled〕){LowPowerModeisenabled。Startreducingactivitytoconserveenergy。}else{LowPowerModeisnotenabled。};注册发热情况通知〔〔NSNotificationCenterdefaultCenter〕addObserver:selfselector:selector(yourMethodName:)name:NSProcessInfoThermalStateDidChangeNotificationobject:nil〕;NSProcessInfoThermalStatestate〔〔NSProcessInfoprocessInfo〕thermalState〕;if(stateNSProcessInfoThermalStateFair){Thermalsarefair。Considertakingproactivemeasurestopreventhigherthermals。}elseif(stateNSProcessInfoThermalStateSerious){Thermalsarehighlyelevated。Helpthesystembytakingcorrectiveaction。}elseif(stateNSProcessInfoThermalStateCritical){Thermalsareseriouslyelevated。Helpthesystembytakingimmediatecorrectiveaction。}else{Thermalsareokay。Goaboutyourbusiness。}; 此外,在介绍AURemoteIO线程时讲到过,线程回调时间是稳定且要求实时性非常高,如果存在阻塞,会导致输入输出都受到影响。出现声音异常,我们利用内部SDK工具针对io线程的耗时做了上报,通过耗时的异常增加可以判断出线程时间片被抢占后的挂起现象。 下图中,三列数据,左侧是事件时间点,中间是输入,右侧是输出。可以看到,20:34:0720:34:37这段时间中,输入是正常状态,维持在1。421。64区间。从20:34:47开始的1秒时间内,输入出现了大幅提升,最低为3。60,最高甚至达到了50。89,超出了正常数值的很多倍。20:34:4720:35:47这个时间点,也和嘉宾侧反馈的问题出现时间相近。 3。3工具分析 降频情况: 正常情况: 从Systemload看降频下的黄色占了绝大部分,可以从中判断出,降频后绝大多数时刻线程负载都超出了CPU性能,接下来我们再看看线程调度情况。 降频情况: 正常情况: 从audioMixerThread线程看,发热情况下黄色被抢占的时间明显增多,在资源紧缺(发热降频、低端机、耗时任务数较多)的时候,低优先级线程会被高优先级的线程抢占的比较严重,比如,系统开辟的高优先级线程(UI线程、coreanimation、AppleBCMWLANBusInterfacePCIe等等)。当然,Mach系统并不会让低优先级的线程一直处于饥饿状态,会根据系统实际情况去调整优先级,audioMixerThread在后面从27的优先级调高到了31。 正常情况: 降频情况: 另外,虽然AURemoteIO有较高的线程优先级,但依然有可能被更高优先级的线程抢占,且在资源紧缺的情况下,线程的执行时间明显减少至正常情况的三分之一。正常情况:1600us左右降频情况:500us左右。(注:此次截图是基于demo模拟测试,如果在抖音上测试会更严重)4。如何避免iOS发热降频导致直播声音卡顿、爆音问题4。1重保增加约束项目重保时,约束用户手机至少保持80以上的电量,最好是充满。如果无法保证电量充足的条件,则需要指导用户手动设定低电流时禁止开启低电量模式(节能模式),建议用户不要一边直播一边充电。部分重保场景,推荐主播用水冷,降低手机发热出现几率;采用性能更好的iPhone机型,这里的性能更好并不完全等价于更高端,而是跟系统版本和特定机型都有关系,比如14。5。1版本系统就被吐槽降频严重,以及过往经验显示iPhoneX发热后降频非常严重。4。2优化降低能耗 在正常情况下,我们可以进一步优化能耗,从而降低发热的可能性,或让发热来的更慢一些。这里提几点:为需要保证实时性的任务提供更高优先级的线程。有效地使用网络至关重要,尽可能通过减少调度事务以及使用高效的API来消除开销成本。网络传输是直播场景的能耗大头。对繁重开销大的线程任务进行分析,尝试优化线程执行任务的复杂度。例如避免不必要的数据拷贝,降低算法逻辑的时间控件复杂度(算法实时性简化),或者利用SIMD指令集进行并行化处理;以上这些手段的最终目的就是降低CPU在单个函数线程上的执行周期。结语 遇到这类案例,通常情况下解释难度较大,给出直播声音卡顿、爆音是由于iOS发热降频造成的这类结论,天然会给人一种甩锅的感觉。 所以,我们更应该充分分析、拿出证据,在分析的过程中自身可以获得很多,也解决了实际问题,从一个小点展开去分析,发现越深入越有意思,很多点都可以深入挖掘。 音视频开发把地球的故事讲给宇宙 作者:字节跳动技术团队链接:https:juejin。cnpost7140535538901073928