内容来源:2018 年 1 月 20 日,华为手机功耗架构师钱华君在“走进网易:移动测试与安全实践”进行《低功耗设计和开发方法探讨》演讲分享。IT 大咖说(微信id:itdakashuo)作为独家视频合作方,经主办方和讲者审阅授权发布。
阅读字数:2756 | 7分钟阅读
摘要
本次演讲将介绍常见的高耗电设计场景,功耗异常的场景举例,并结合Android机制,介绍为何导致耗电,以及推荐的设计方法;接下来讲解编译技术在低功耗开发中的应用,如何基于LLVM编译器来开发构建一个静态代码分析工具,检测常见的错误编码方式,深入浅出介绍如何通过编译器来检测持锁未释放的场景;最后是机器学习在低功耗设计中的应用展望,通过机器学习了解用户的行为,在应用开发中既满足用户体验,又节省功耗。
嘉宾演讲视频及PPT回顾:http://suo.im/4AcBmp
高耗电设计场景举例
Push
Push即notification消息的一个交互,是一种消息推送机制,iOS有唯一的Push通道,所有应用的服务端要与应用交互的消息都必须通过这个Push通道,避免了通知消息唤醒应用。Android则存在多个Push通道,谷歌有GCM;每个厂商也有自己的通道,比如华为Push;除此之外应用有自己的独立通道,如微信。这种情况下就导致应用被频繁唤醒,整个系统其实是没有休眠的,没办法像iOS的通道这样控制行为。
Wakelock长时间持锁
上图是Android的休眠机制,刚开始的时候系统被频繁的唤醒,在息屏后一段时间会进入浅睡眠,这时网路访问就没有了、Syncs以及Jobs Deferred都不推荐使用,但是定期还是会有一个维护窗口,这段时间应用程序是可以被唤醒的。再持续一段时间后就进入了深度睡眠模式,这时不仅没有网络连接,GPS等也被禁止,这其实是理想的睡眠状态,实际是比较难进入这种状态的。
为了不让系统的休眠导致应用进程结束,一般需要设置Wakelock。Wakelock有两种使用形式,一种是采用PowerMananger申请Wakelock锁,这段时间内系统不会进入休眠状态;另一种是直接使用底层的wake_lock或wake_unlock接口来避免系统进入休眠状态。
Wakelock持锁如果忘记释放,会导致系统一直被频繁唤醒无法进入浅睡眠而一直处于异常耗电状态。程序获持锁之后异常退出会导致wake_lock一直被开启,这时也系统也是处于异常耗电状态。
编译技术在低功耗开发中的应用
编译技术的应用
理论上的所有把一种编程语言转换为另一种语言或格式的都叫编译。第一种常见的编译是把编程语言直接编译为机器码,典型的如C/C++的编译器;第二种是把编程语言编译为字节码,由虚拟机执行;第三种是领域特定语言(DSL)的编译器。
在产品中应用编译技术的几种可行方面
- 研究编译器选项,或者通过迭代编译获得最佳选项,从而在产品中获得性能提升。
- 增加编译器扩展(pragma,_attribute_),进行额外的编译检查和辅助代码生成。
- 基于编译器前端生成的抽象语法树(AST)进行代码静态分析,以及基于AST重写进行自动化的代码重构。
- 基于编译器后端输入的中间表达式(IR)进行跨函数/跨TU的分析。
- 基于编译指令修改的运行时错误发现。
CLAN & LLVM
应用编译技术不需要所有从头自己写,可以合理选择已有的编译器基础软件。
LLVM不是虚拟机,而是一套编译优化(全时优化)的基础库,Clang是一个前端,支持C(包括C99/C11、大部分GCC扩展)、C++(已经完全支持到C++14)、Object-C、OpenCL。Clang和LLVM的纽带在于LLVMIR(Intermediate Representation),这也是LLVM的核心。
相对GCC来说Clange&LLVM学习曲线更平缓,并且它们使用的是BSD License,相比GPL更加优化;高度的模块化,比GCC更容易扩展和二次开发;另外它们有设计良好的接口和模式,便于访问内部数据,如:访问抽象语法树(AST)节点、获取控制流图节点(CFG Node)、进行上下文符号获取等等;Clang对C++标准的支持更完整、更快;它们还有良好的GCC兼容性,包括GCC内置扩展语法、内置关键字的支持;无论是编译速度、内存开销、部分平台上代码执行效率Clang和LLVM都超过了GCC。
代码的静态分析
代码的静态分析中被分析程序不需要运行起来,不依赖执行环境,通过对程序的源代码或者某种形式的中间代码进行分析来发现代码中的缺陷,在大型软件分析中,是非常有价值的。
静态分析同样也面临着诸多挑战,首先代码中的各种分支路径均需要分析;而且要根据上下文分析,比如变量的取值范围和条件;另外各种分支组合会带来算法复杂度的指数级增长,尤其是跨函数分析;最后静态分析需要尽可能的清除误报。
符号执行
Symbolic Execution
- 根据AST构造控制流程图CFG
- 从CFG的根节点开始,沿着图的各条边进行语句的虚拟执行,对所有可能的Path都需要进行遍历,使用符号来表示结果,而不是向运行时记录实际的值。
- 在遍历每条路径是,在每个点上收集所有在这个点上可见的符号值。
- 对于“资源泄露”这类问题,就转化为图的可达性判断问题。
在路径的遍历分析中用记录变量的Symbolic Value
- FITE* f在所有路径都可见
- 路径的所有节点(语句)上均记录f的Symbolic Value
- 达到Sink节点时,根据f的Symbolic Value来判断是否残留句柄未关闭
Analysis Checker
- 在CFG遍历过程中,每个stmt访问时触发,是一种典型的控制反转(Ioc)模式。
- 开发者可以在不同的触发点上注册自己的检查。
- Checker会参与并影响到Exloded Graph的创建。
- 为了减少路径爆炸,Checker可以通过创建Sink Node来做路径支剪。
机器学习在低功耗中的应用展望
机器学习应用场景
一般开发中的耗电量统计是基于进程的角度,不能进一步查看到进程下每个函数的耗电量,通过机器学习就能基于线性回归统计函数级别的功耗。
Android即将到来的p版本中机器学习将应用于场景分析,比如智能亮度控制,auto-awesome Battery。而iOS 11集成了机器学习框架Core ML,当前用于视觉和自然语言处理。
有问题可以在评论区讨论,以上为所有分享内容,谢谢大家!