Suspend to RAM和Suspend to Idle分析,以及在HiKey上性能对比
Linux内核suspend状态
Linux内核支持多种类型的睡眠状态,通过设置不同的模块进入低功耗模式来达到省电功能。目前存在四种模式:suspend to idle、power-on standby(Standby)、suspend to ram(STR)和sudpend to disk(Hibernate),分别对应ACPI状态的S0、S1、S3和S4。
Suspend to idle完全是软件相关的并且尽量将CPU维持在深度idle状态。
Power-on standby设置设备进入低功耗模式并且关闭所有non-boot CPU。
Suspend to ram就更进一步,关闭所有CPU并且设置RAM进入自刷新模式。(在HiKey的实际测试中,boot CPU是没有关闭的!实际上这里也没有standby,mem和standby基本上没有区别。)
Suspend to disk是最省功耗的模式,通过尽可能的关闭设备,包括RAM。RAM的数据会被写入磁盘中,在resume的时候读回到RAM。
下面用STR表示Suspend to RAM,STI表示Suspend to Idle。
详情请参考:http://www.linaro.org/blog/suspend-to-idle/
STR 和STI区别
写入/sys/power/state不同字符串,可以让系统进入不同睡眠状态。
|
#define PM_SUSPEND_ON ((__force suspend_state_t) 0) 正常工作状态 |
针对state sysfs节点的写入,最终会进入到state_store这个函数,将字符串转换成上表中不同状态。
| state_store(kernel/power/main.c) -->pm_suspend (kernel/power/suspend.c) 处理除freeze、standby、mem三种类型suspend -->enter_state 在进入睡眠之前,做一些准备工作 -->suspend_devices_and_enter -->suspend_enter 这里才是freeze与standby/mem区别所在。 -->hibernate 进入suspend to disk流程 |
STR和STI的最主要区别就是下面一段代码:
|
static int suspend_enter(suspend_state_t state, bool *wakeup) … /* error = disable_nonboot_cpus(); arch_suspend_disable_irqs(); error = syscore_suspend(); arch_suspend_enable_irqs(); Enable_cpus: Platform_wake: … } |
下面分析一些每个子系统的suspend/resume。
整个suspend可以分为若干阶段,每个阶段函数—>关键节点Trace—>analyze_suspend.py解析Trace—>根据Trace时间画出Timeline图表
这样就可以分析出总的时间差异,每个阶段差异,甚至一个设备suspend/resume、一个子系统suspend/resume的时间差异。
freeze_enter
platform_suspend_begin/patform_resume_end
suspend_console/resume_console
dpm_suspend_start/dpm_resume_end
dpm_suspend_noirq/dpm_resume_noirq
disable_nonboot_cpus/enable_nonboot_cpus
arch_suspend_disable_irqs/arch_suspend_enable_irqs
syscore_suspend/syscore_resume
如何让HiKey进入STR/STI并唤醒?
可以通过配置GPIO作为唤醒源,或者通过RTC作为唤醒源,延时一定时间来唤醒。
检查是否存在/sys/class/rtc/rtc0/wakealarm,入不存在则需要打开CONFIG_RTC_DRV_PL031。
写入wakealarm的参数,表示在多少秒之后resume唤醒,退出suspend。
写mem进入state,是系统进入suspend流程。
| adb root && adb remount adb shell "echo +10 > /sys/class/rtc/rtc0/wakealarm && echo mem > /sys/power/state" |
suspend/resume的latency分析手段
analyze_suspend.py v3.0
在kernel的scripts中,这个工具可以帮助内核和OS开发者优化suspend/resume时间。
在打开一系列内核选项之后,此工具就可以执行suspend操作,然后抓取dmesg和ftrace数据知道resume结束。
这些数据会按照时间线显示每个设备,并且显示占用最多suspend/resume时间的设备或者子系统的调用关系详图。
执行工具后,会根据时间生成一个子目录,里面包含:html、dmesg和原始ftrace文件。
下面简单看一下工具选项:
|
Options: |
在了解了工具使用方法之后,就可以进行相关测试了。
Android
./analysze_suspend.py –modes –adb /usr/bin/adb获取当前系统支持的suspend状态。
|
['freeze', 'mem'] |
1.Android上测试STR,suspend/resume共5次,每次间隔20秒。
| ./analyze_suspend.py -adb /usr/bin/adb -rtcwake 10 -multi 5 20 -f -m mem |
2.Android上测试STI,suspend/resume共10次,每次间隔5秒。
| ./analyze_suspend.py -adb /usr/bin/adb -rtcwake 10 -multi 5 20 -f -m freeze |
测试结果可以在如下获得:
https://github.com/arnoldlu/common-use/tree/master/tools/analyze_suspend/hikey_test
存在的问题:analyze_suspend.py不支持Android的rtcwakeup和callgraph。已经在如下fix:
https://github.com/arnoldlu/common-use/blob/master/tools/analyze_suspend/analyze_suspend.py
总体对比
下面是HiKey上测试结果,可以看出两个数据都不够稳定。mem的suspend和resume平均值都比较高。
freeze相比mem的suspend/resume平均值提高了304.3ms/613.5ms。


是否suspend CPU
对比如下两幅图,明显看出mem类型的suspend关闭了除CPU0之外的所有CPU;而freeze则没有关闭任何CPU。
non-boot CPUs的suspend/resume时间就达到300ms/200ms。


同时从log中也可以看出mem和freeze的主要区别就在于是否disabling/enabling non-boot CPU。其他设备和子系统的suspend/resume时间基本一致。
|
[ 3385.642962] PM: suspend entry 1970-01-01 00:57:30.580909763 UTC |
[ 3471.760265] PM: Syncing filesystems ... done. |
resume_console节省时间
对比resume_console可以发现,mem要比freeze多210ms。
Ubuntu
此工具在Ubuntu上显示了更强大的功能。
支持了callgraph功能之后,更能清晰地分析每个设备或者子系统的suspend/resume占用的时间。
| sudo ./analyze_suspend.py -rtcwake 10 -multi 5 20 -f -m mem sudo ./analyze_suspend.py -rtcwake 10 -multi 5 20 -f -m freeze |
在对比两种不同suspend模式后,发现freeze花费的时间要比mem少。这也符合预期,但是没有功耗数据?_?。


下面着重分析一下如何基于此工具分析。
工具界面总体分析
最上面显示Kernel Suspend Time和Kernel Resume Time,可以从总体上查看是否有回退或者进步。
再下面是一些缩放按钮。
然后就是基于timeline的图表,比对颜色示意图,可以清晰看出suspend prepare、suspend、suspend late、suspend irq、suspend machine、resume machine、resume irq、resume early、resume和resume complete的分布。
最下面是每个模块、子系统的详细函数调用图以及开始时间、消耗时间。

子系统、模块详细分析
选中一个模块,会在最下面显示详细的模块在suspend/resume各个阶段消费的时间,以及函数调用关系图。

缩放查看细节
ZOOM IN放大,ZOOMOUT缩小,ZOOM 1:1恢复原始尺寸。
通过在timeline图表,放大可以查看到更小的模块消耗的时间。从宏观到模块,再到函数消耗时间,逐步细化,很有利于分析。

如果发现某个函数占用时间较大,可以逐级展开。知道发现最终占用较大的函数,发现问题所在。

参考文档
Power Management Support in Hikey (suspend-resume):http://www.96boards.org/forums/topic/power-management-support-in-hikey-suspend-resume/#gsc.tab=0
Suspend to Idle:http://www.linaro.org/blog/suspend-to-idle/
Suspend and Resume:https://01.org/zh/suspendresume
SuspendAndResume github:https://github.com/arnoldlu/suspendresume
Linux电源管理(6)_Generic PM之Suspend功能:http://www.wowotech.net/pm_subsystem/suspend_and_resume.html
Suspend to RAM和Suspend to Idle分析,以及在HiKey上性能对比的更多相关文章
- Suspend to RAM和Suspend to Idle分析,以及在HiKey上性能对比【转】
转自:https://www.cnblogs.com/arnoldlu/p/6253665.html 测试环境:AOSP 7.1.1+Kernel 4.4.17 HW:HiKey Ubuntu 14. ...
- Jconsole与Jmx 分析JVM状况(上) 转
出处:Jconsole与Jmx 分析JVM状况(上) JVM 平台提供 Mbeans 说明 在 Java 2 平台 5.0 以上版本,有一组 API 可以让 Java 应用程序和允许的工具监视和管理 ...
- 浅谈C++之冒泡排序、希尔排序、快速排序、插入排序、堆排序、基数排序性能对比分析之后续补充说明(有图有真相)
如果你觉得我的有些话有点唐突,你不理解可以想看看前一篇<C++之冒泡排序.希尔排序.快速排序.插入排序.堆排序.基数排序性能对比分析>. 这几天闲着没事就写了一篇<C++之冒泡排序. ...
- ArrayList和LinkedList的几种循环遍历方式及性能对比分析(转)
主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性能测试对比,根据ArrayList和LinkedList的源码实现分析性能结果,总结结论. 通过本文你可以 ...
- ArrayList和LinkedList的几种循环遍历方式及性能对比分析
最新最准确内容建议直接访问原文:ArrayList和LinkedList的几种循环遍历方式及性能对比分析 主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性 ...
- HBase在单Column和多Column情况下批量Put的性能对比分析
作者: 大圆那些事 | 文章可以转载,请以超链接形式标明文章原始出处和作者信息 网址: http://www.cnblogs.com/panfeng412/archive/2013/11/28/hba ...
- 使用 Web Tracing Framework 分析富 JS 应用的性能
来自谷歌的 Web Tracing Framework 包含一组工具和脚本,用于 JavaScript 相关代码的性能分析.它是重 JavaScript 应用程序的理想选择,而 JavaScript ...
- ArrayList和LinkedList的几种循环遍历方式及性能对比分析(转载)
原文地址: http://www.trinea.cn/android/arraylist-linkedlist-loop-performance/ 原文地址: http://www.trinea.cn ...
- ArrayList和LinkedList遍历方式及性能对比分析
ArrayList和LinkedList的几种循环遍历方式及性能对比分析 主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性能测试对比,根据ArrayLis ...
随机推荐
- Elasticsearch的CRUD:REST与Java API
CRUD(Create, Retrieve, Update, Delete)是数据库系统的四种基本操作,分别表示创建.查询.更改.删除,俗称"增删改查".Elasticsearch ...
- 全面理解Git
前言 人生贵知心,定交无暮早. 原文博客地址:Git命令总结 知乎专栏&&简书专题:前端进击者(知乎) 前端进击者(简书) 正文 1.Git简介 Git的诞生确实是一个有趣的故事,我 ...
- C#中HttpClient使用注意:预热与长连接
最近在测试一个第三方API,准备集成在我们的网站应用中.API的调用使用的是.NET中的HttpClient,由于这个API会在关键业务中用到,对调用API的整体响应速度有严格要求,所以对HttpCl ...
- 充电时间 Go中的数组、切片、map简单示例
数组是固定长度的,依稀让我想起了VB:切片是动态的:map一般是键值对 package main import ( "fmt" ) func main() { var userna ...
- FunDA(2)- Streaming Data Operation:流式数据操作
在上一集的讨论里我们介绍并实现了强类型返回结果行.使用强类型主要的目的是当我们把后端数据库SQL批次操作搬到内存里转变成数据流式按行操作时能更方便.准确.高效地选定数据字段.在上集讨论示范里我们用集合 ...
- FunDA(0)- Functional Data Access accessible to all
大数据.多核CPU驱动了函数式编程模式的兴起.因为函数式编程更适合多线程.复杂.安全的大型软件编程.但是,对许多有应用软件开发经验的编程者来说,函数式编程模式是一种全新的.甚至抽象的概念,可能需要很长 ...
- c语言实现输入一组数自动从大到小排列
#include <stdio.h>main(){ int x; printf("请输入要排序数字个数:"); scanf("%d" ...
- .NET Core 2.0版本预计于2017年春季发布
英文原文: NET Core 2.0 Planned for Spring 2017 微软项目经理 Immo Landwerth 公布了即将推出的 .NET Core 2.0 版本的细节,该版本预计于 ...
- Android将应用调试log信息保存在SD卡
转载:http://blog.csdn.net/way_ping_li/article/details/8487866 把自己应用的调试信息写入到SD卡中. package com.sdmc.hote ...
- tableView显示第一个cell有偏移问题
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 0 ...