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(工作态、空闲态、休眠态)以及特殊业务子系统进行硬件功耗优化、软件算法优化、耗电策略改善等,提升用户灭屏耗电体验。

  • 相关阅读:
    洛谷P1306 斐波那契公约数
    Codevs 1688 求逆序对(权值线段树)
    poj1006 Biorhythms
    2017-9-2 NOIP模拟赛
    洛谷P1633 二进制
    洛谷P2513 [HAOI2009]逆序对数列
    洛谷P2687 [USACO4.3]逢低吸纳Buy Low, Buy Lower
    洛谷P2285 [HNOI2004]打鼹鼠
    2017-8-31 NOIP模拟赛
    洛谷P2134 百日旅行
  • 原文地址:https://www.cnblogs.com/linhaostudy/p/14998234.html
Copyright © 2011-2022 走看看