zoukankan      html  css  js  c++  java
  • 我的手机灭屏了,为什么还在耗电

    读者可能会有这种体会和感受,昨晚的睡眠时间和平时相当,但是为何早上起来特别困,如下来自健康手环的睡眠监测数据或许可以给你答案。

    image

    可知整个夜间睡眠时间段,睡眠质量通过深睡、浅睡、清醒三种等级来表征,你记忆中的夜间睡眠,实际情况可能是翻来覆去整个人都处于清醒的状态,这种情况越多,睡眠质量也就越差。该监测数据,可为作息规划与改善提供数据支撑。

    对于手机而言,灭屏状态下的表现其实与人的睡眠大体类似,当系统处于深度睡眠模式时,功耗会低很多;相反,当系统处于唤醒状态时,功耗会大很多,此时手机自然也就耗电快。本文,我们来介绍下手机灭屏耗电这回事。

    当按下电源键时,系统就会触发熄屏与休眠流程,概述如下:

    image

    在该流程中,PhoneWindowManager负责对电源键作出响应,然后通过goToSleepFromPowerButton->goToSleep调用向PowerManger传递休眠动作,作为PowerManger中goToSleep的实现者PowerManagerService,则透过setHalAutoSuspendModeLocked -> mNativeWrapper.nativeSetAutoSuspend间接调用native suspend_control(android.system.suspend@1.0-service) 中的enableAutoSuspend关键函数。而suspend_control(android.system.suspend@1.0-service)则通过kernel pm core提供的各类sysfs节点对系统休眠条件与流程进行检查和控制。在linux kernel pm core中,main这一部分与suspend相关的模块有autosleep、wakeup count、task freeze、wakelock等,主要负责提供相应的用户态接口以及处理与硬件无关的核心逻辑。之后pm driver则负责处理硬件相关的休眠工作,分device driver抽象层的逻辑控制,以及具体的平台休眠实现与设备休眠实现。

    再次转到灭屏耗电这个维度,通过如上的信息,可知影响耗电的几个主要关键维度:是否有触发休眠动作、触发休眠后是否执行成功、是否频繁退出休眠状态、平台级的休眠状态、外围设备的耗电状态等。

    Android框架batterystats模块对系统的耗电表现有相对完整的理解和阐述,其对硬件耗电表现(eg:cpu、wifi、gps、bluetooth)以及软件行为(eg:休眠、持锁、冻结、唤醒、Job)都有丰富的数据统计。以应用软件在cpu上的耗电表现为例,其统计该应用在每个cluster上的cpu执行时间,结合cpu每个频点的功耗数据,加权累计后即可算出该应用的cpu耗电情况,关键代码段以及配置文件摘录如下:

    image

    为了便于开发人员调试分析,Batterystats的数据可以通过dumpsys batterystats命令输出,且谷歌开发了battery-historian工具以图形界面的方式展示batterystats统计的关键信息。源代码以及搭建方法在https://github.com/google/battery-historian官方网站中有阐述,效果示例如下:

    image

    对于手机灭屏下的表现,我们可以从图中得到很多耗电相关的信息,关键信息摘录如下:

    • CPU running:用于表征系统是否有进入休眠状态,并记录唤醒源信息。休眠时间占比越短,耗电会越差。

    • Userspace wakelock:用于表征当前是否存在用户空间申请的wakelock,并且这里会展示系统被唤醒后首次申请的wakelock。值得注意的是,用户空间申请的wakelock的总时长和首次申请的wakelock并不存在必然的联系,如果要进一步确认总时长分别是哪些wakelock引起的,可以执行dumpsys batterystats --enable full-history命令后得到所有wakelock的过程记录功能,从而找到答案。

    • Long wakelocks:表征是否存在长时间持有的wakelock。当持有时间超过1分钟时,则会被标记,此类的情况的出现会对灭屏功耗造成较大影响。

    • Kernel only uptime:当所有用户态的wakelock都释放后,如果kernel未休眠,那么这部分的时间会被记录到这个字段。

    • Screen:表征当前的亮灭屏状态。

    • Doze:表征android doze省电模式的状态。值可为off foze、light doze、full doze这几种,当用户一段时间内没有使用手机且满足进入Doze的条件时,会限制应用的后台活动,以达到减少功耗的目的。具体限制的动作比如暂停网络访问、忽略应用持有的WakeLock、不再进行wifi扫描、不允许sync adapters和JobScheduler运行等。不过为了保证基础功能与用户体验,系统进程、核心应用、前台服务进程并不会受到限制。

    • 其它:gps状态、通话状态、联网状态与类型、wifi状态等,都与灭屏表现息息相关,篇幅有限,不详细阐述。

    上文batterystats模块中”cpu running“指标阐述的是休眠与否这个状态。然而,linux系统可分为三种状态:工作态、空闲态、休眠态。系统工作态与空闲态这两种状态下的运行表现,对灭屏功耗同样起着至关重要的影响。

    image

    如上图所示,灭屏下系统处于唤醒状态时(持有wakelock未休眠或者睡眠后被唤醒),如果cpu没有被关闭,那么处理deadline、real time、fair调度类上的任务时认为cpu处于工作态。为了改善灭屏工作态的功耗,往往通过减少任务量、降低硬件功耗两方面来制定策略,比如冻结与清理非核心的任务、job策略优化、降低cpu的工作频率、关闭能效差的cpu等。此时batterystats模块又充分展示出”对耗电工作的主动与积极性“,对灭屏下的各个应用的cpu使用情况做了详细的统计,这对灭屏耗电分析与调试、优化效果呈现等方面起到一定的辅助作用,结果示例如下:

    image

    当deadline、realtime、fair调度类上无任务需要处理时,kernel则会执行idle调度类上的任务,该任务的职责是走cpu idle流程以节省功耗。另外,可以选择不同的idle governor比如menu governor、ladder governor、平台定制的governor等以满足不同的应用场景。为了快速便捷的了解各cpu的idle执行情况,可通过idlestat开源工具(源码参考网址https://github.com/scheduler-tools/idlestat)来分析、统计各个cpu在每个idle c-state下的停留时间、进入次数等信息,也可通过busybox powertop工具(源码参考网址https://busybox.net/)来分析cpu的irq、timer表现以找出top类的idle唤醒源。

    另外,当cpu的idle级别达到某个级别以上(C1、C2 ….),或者处于idle的cpu数量达到某个条件,亦或者其它特殊的条件(不同平台表现不一)得到满足时,SOC往往会进入深度定制的省电模式以将idle状态下的耗电降低到极致。其中,这里提及的特殊条件的满足,依赖的条件往往比较多,各个设备模块往往充分利用内核提供的runtime pm框架,在合适的时机尽可能的释放相应的资源以提供必要条件。runtime pm状态描述如下:

    image

    关键函数示例如下:

    image

    以i2c控制器为例,在不需要传输数据的时候及时释放clock,代码示例如下:

    image

    如上所述,灭屏情况下的kernel休眠态、工作态、空闲态表现对灭屏功耗均起到关键的影响,因此,策略设计不合理、运行逻辑出现异常,都会造成灭屏耗电不理想。

    回到前面提到的几个维度,kernel是否有触发休眠动作、是否频繁退出休眠状态、触发休眠后是否执行成功等关键信息可以在batterystats模块统计的信息中找到线索。然而,平台级别的休眠状态、外围器件的休眠状态,由于终端设备之间的差异性比较大,batterystas的覆盖还不够。

    对于整机硬件系统,除了cpu之外,modem子系统、sensor子系统、audio子系统、wireless子系统往往也不可或缺,这些子系统对灭屏耗电影响也很大。

    • Modem子系统:负责处理与基站相关的通信业务,承担着电话、短信、上网等业务。造成该子系统休眠差的原因有多种,比如业务联网频繁、小区切换频繁、无服务搜网、RRC连接不释放、弱信号重传多等。

    • Sensor子系统:负责传感器业务需求、基础功能的支撑(比如抬手检测、计步检测、开合检测等),出于耗电的考虑,越来越多的传感器算法会转移到sensor子系统来实现。应用调用sensor是否合理、sensor的采样频率、省电模式的配置、算法实现的复杂度,是影响sensor子系统休眠与耗电表现的重要因素。

    • Audio子系统:处理音频相关业务,比如音频播放、录音、特效算法等。三方应用的不合理使用(例如后台持续播放、录音行为)往往是造成audio子系统异常耗电的主要原因。

    • Wireless子系统:该子系统往往集成了wifi、bt、gps、fm等无线功能模块,相应模块的作业状态直接影响该子系统的耗电表现。

    随着业务需求的发展,手机终端的集成度越来越高,功能也越来越复杂,无论是硬件、底层设备驱动还是应用软件,在设计与实现时都需要充分考虑耗电影响,以本文提及的灭屏为例,围绕AP(工作态、空闲态、休眠态)以及特殊业务子系统进行硬件功耗优化、软件算法优化、耗电策略改善等,提升用户灭屏耗电体验。

  • 相关阅读:
    CodeForces 347B Fixed Points (水题)
    CodeForces 347A Difference Row (水题)
    CodeForces 346A Alice and Bob (数学最大公约数)
    CodeForces 474C Captain Marmot (数学,旋转,暴力)
    CodeForces 474B Worms (水题,二分)
    CodeForces 474A Keyboard (水题)
    压力测试学习(一)
    算法学习(一)五个常用算法概念了解
    C#语言规范
    异常System.Threading.Thread.AbortInternal
  • 原文地址:https://www.cnblogs.com/linhaostudy/p/14998234.html
Copyright © 2011-2022 走看看