众所周知,在android系统的耗电量排行里,cpu的耗电占了比较大的一部分比例,也就是说,cpu的使用率和使用频率将直接或间接的影响电量的分配和使用,但很遗憾,android-sdk中没有为android的开发者提供类似cpu管理的功能,但是当下很多省电类应用或专业的cpu管理软件都提供了cpu的降频甚至是超频的功能,那么这样的功能是如何实现的,本文将详细说明在android环境下调整cpu频率的一些方法,仅供参考。

按照我写文章的风格,在阐述过程和结论之前,都不得不对关键性的概念做一下解释,本文也不例外。

1.CPU的工作频率

单位赫兹或者兆赫兹,具体含义不解释,说实话也不太清楚,不过可以确认一点的是,CPU的工作频率越高,耗电量越大,反之亦然。我们做这个模块省电的终极目标就是降低cpu的工作频率。

2.CPU的调控模式

英文词为:Governor,解释为调速器,控制器。大家都指导android的framework是基于linux平台的,那么cpu的管理体系这块也跟linux基本上一样,其中包括cat命令,和一些文件的读写配置都是基本上差不多的。Linux在管理CPU方面,提供了如下集中调控模式,分别为:

Governor Select this governor if How it works
performance Performance is the only consideration. Sets the CPU to run at the highest frequency (scaling_max_freq)
powersave Efficiency is the only consideration Sets the CPU to run at the lowest frequency (scaling_min_freq)
ondemand Adaptation to the current load is the main consideration. Checks the load regularly. When the load rises aboveup_threshold, sets the CPU to run at the highest frequency (scaling_max_freq). When the load falls below the same threshold, sets the CPU to run at the next lowest frequency. Causes less latency than the conservative governor.
conservative Close adaptation to the current load is the consideration. Checks the load regularly. When the load rises aboveup_threshold, sets the CPU to run at the next highest frequency. When the load falls belowdown_threshold, sets the CPU to run at the next lowest frequency. Has more latency than the ondemand governor.
userspace Control by other user space program is preferred. Sets the CPU frequency to the value specified by the user space program (through the use of thescaling_setspeed parameter).

这个表格的出自:http://publib.boulder.ibm.com/infocenter/lnxinfo/v3r0m0/index.jsp?topic=%2Fliaai%2Fcpufreq%2FTheCPUFreqGovernors.htm

按照原文给出的解释,我大概把这5种调控模式理解为一下几种观点,如有不足,还请指正!

1.performance,这个不多说,就是将cpu的工作频率调整到最大模式,让cpu充分的工作。

2.powersave,将cpu的工作频率调整到节能模式,也就是这个模式下的cpu平率是最低的。

3.ondemand,定期检查负载。当负荷超越了阈值,设置的CPU运行以最高的频率。当负载低于相同的阈值,设置的CPU运行在下一个的最低频率。导致更少的延迟比。这个理解起来可能比较困难,我用白话大概解释一下,ondemand从字面翻译是“根据需求,按照需要”,cpu在工作的时候频率会在一个最大值和最小值之间波动,当负载提高时,该调控期会自动提高cpu的频率,反之亦然。“Causes less latency than the conservative governor.”这句话的意思是,该模式跟conservative相比,会导致更少的延迟。ok,那让我们再看看conservative是如何解释的。

4.conservative,改词用来形容保守的,守旧的。该模式与ondemand的最大区别在于,conservative模式不会立刻在负载增加的情况下将cpu频率调整到最大,他会调整到比目前频率稍微大的频段去工作,保守,实在是保守!所以换来的结果是,在某种极端情况下,该模式的延迟会大于ondemand。

5.usersapce,该模式将cpu的掌控权交给了用户态,也就是交给了应用程序,应用程序可以通过配置文件的方式修改cpu的频率信息,上面3种模式好比linux已经给你定义好的4种模式,userspace好比上面4种模式无法满足我的需求,我需要自定义!(由于第四种方式需要进行大量的文件操作和配置,本文不阐述了,与省电的目标相差比较远)

ok!我们了解了这5种省电模式,那么如何查看你的android手机当前运行在哪种模式下呢?当前的cpu运行的工作频率是多少呢?最大最小频率是多少?我如何修改模式呢?

其实很简单,android的cat命令都为我们解决了这些问题,首先要强调的是,必须要获得系统的root权限,才能进行以下操作。

第一步:adb shell 进入root 命令行模式

第二步 cd /sys/devices/system/cpu/cpu0/cpufreq 进入这个目录下面

第三步 ls

第四步 你能看见很多的文件

第五步 参考下面的命令,打一遍就清楚了,不过为了给傻瓜提供更好的服务,我还是尽可能的将命令的使用和作用写的详细。

/**
  * cpu cat命令大全
  * cat [%cpuFreqPath%]/cpuinfo_cur_freq   (当前cpu频率)
  * cat [%cpuFreqPath%]/cpuinfo_max_freq  (最大cpu频率)
  * cat [%cpuFreqPath%]/cpuinfo_min_freq  (最小cpu频率)
  * cat [%cpuFreqPath%]/related_cpus  (cpu数量标号,从0开始,如果是双核,结果为0,1)
  * cat [%cpuFreqPath%]/scaling_available_frequencies  (cpu所有可用频率)
  * cat [%cpuFreqPath%]/scaling_available_governors  (cpu所有可用调控模式)
  * cat [%cpuFreqPath%]/scaling_available_governors  (cpu所有可用调控模式)
  * cat [%cpuFreqPath%]/scaling_cur_freq  (?????)
  * cat [%cpuFreqPath%]/scaling_driver (调控驱动)
  * cat [%cpuFreqPath%]/scaling_governor (当前使用哪种调控模式)
  * cat [%cpuFreqPath%]/scaling_max_freq (?????)
  * cat [%cpuFreqPath%]/scaling_min_freq (?????)
  * cat [%cpuFreqPath%]/scaling_setspeed (?????)
  * cat [%cpuFreqPath%]/cpuinfo_transition_latency (变频延迟)
  */

熟悉了这些语法和密令之后,我们就可以很轻松的明白,如何省电了,无非就是将cpu降频嘛,把当前的调控模式调整为powersave就可以了嘛,不错,但是还不完全正确。

首先我先讲一下如何通过命令行改写当前的调控模式,很简单,一句命令:

echo "你想使用的调控模式" /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

但是因为手机出场适配等问题,有些机器上是没有powersave这个模式的,对了,你一定要确认当前手机是否有powersave这个模式,具体怎么看就在我上面给的命令大全里面,自己找!在没有powersave模式的情况下,我们只好通过更狠的方法修改cpu的频率,那就是直接改写cpu的频率,命令:

echo 2331000 > cpu0/cpufreq/scaling_min_freq  设置最小的工作频率,同时也可以设置最大的工作频率。

ok!设置cpu的频率的两种方式我基本上说清楚了,本质没什么差别。那么在实际java端的开发中,我们如何使用呢?

贴贴代码吧,不做过多的解释了,相信大家多能读懂!

  1. <span style="font-family:Microsoft YaHei;">/**
  2. * @author matrixxu
  3. *
  4. */
  5. public class CPUFreqSetting {
  6. /**
  7. * cpu cat命令大全
  8. * cat [%cpuFreqPath%]/cpuinfo_cur_freq   (当前cpu频率)
  9. * cat [%cpuFreqPath%]/cpuinfo_max_freq     (最大cpu频率)
  10. * cat [%cpuFreqPath%]/cpuinfo_min_freq     (最小cpu频率)
  11. * cat [%cpuFreqPath%]/related_cpus     (cpu数量标号,从0开始,如果是双核,结果为0,1)
  12. * cat [%cpuFreqPath%]/scaling_available_frequencies    (cpu所有可用频率)
  13. * cat [%cpuFreqPath%]/scaling_available_governors  (cpu所有可用调控模式)
  14. * cat [%cpuFreqPath%]/scaling_available_governors  (cpu所有可用调控模式)
  15. * cat [%cpuFreqPath%]/scaling_cur_freq     (?????)
  16. * cat [%cpuFreqPath%]/scaling_driver   (?????)
  17. * cat [%cpuFreqPath%]/scaling_governor (?????)
  18. * cat [%cpuFreqPath%]/scaling_max_freq (?????)
  19. * cat [%cpuFreqPath%]/scaling_min_freq (?????)
  20. * cat [%cpuFreqPath%]/scaling_setspeed (?????)
  21. * cat [%cpuFreqPath%]/cpuinfo_transition_latency   (?????)
  22. */
  23. private final String TAG = "SetCPU";
  24. private final String cpuFreqPath = "/sys/devices/system/cpu/cpu0/cpufreq";
  25. private final static String PERFORMANCE_GOVERNOR = "performance";
  26. private final static String POWER_SAVE_GOVERNOR = "performance";
  27. private final static String ONDEMAND_GOVERNOR = "performance";
  28. private final static String CONSERVATIVE_GOVERNOR = "performance";
  29. private final static String USERSAPCE_GOVERNOR = "performance";
  30. //  public void powerSaveGovernor() {
  31. //      List<String> governors = readCpuGovernors();
  32. //      if (governors.contains(object)) {
  33. //
  34. //      }
  35. //  }
  36. /**
  37. * 获得当前CPU调控模式
  38. */
  39. public void getCpuCurGovernor() {
  40. try {
  41. DataInputStream is = null;
  42. Process process = Runtime.getRuntime().exec("cat " + cpuFreqPath + "/scaling_governor");
  43. is = new DataInputStream(process.getInputStream());
  44. String line = is.readLine();
  45. } catch (IOException e) {
  46. e.printStackTrace();
  47. }
  48. }
  49. /**
  50. * 重写CPU调控模式
  51. * @param governor
  52. * @return
  53. */
  54. private boolean writeCpuGovernor(String governor) {
  55. DataOutputStream os = null;
  56. byte[] buffer = new byte[256];
  57. String command = "echo " + governor + " > " + cpuFreqPath + "/scaling_governor";
  58. Log.i(TAG, "command: " + command);
  59. try {
  60. Process process = Runtime.getRuntime().exec("su");
  61. os = new DataOutputStream(process.getOutputStream());
  62. os.writeBytes(command + "\n");
  63. os.writeBytes("exit\n");
  64. os.flush();
  65. process.waitFor();
  66. Log.i(TAG, "exit value = " + process.exitValue());
  67. } catch (IOException e) {
  68. Log.i(TAG, "writeCpuGovernor: write CPU Governor(" + governor + ") failed!");
  69. return false;
  70. } catch (InterruptedException e) {
  71. e.printStackTrace();
  72. }
  73. return true;
  74. }
  75. /**
  76. * 获得CPU所有调控模式
  77. * @return
  78. */
  79. private List<String> readCpuGovernors() {
  80. List<String> governors = new ArrayList<String>();
  81. DataInputStream is = null;
  82. try {
  83. Process process = Runtime.getRuntime().exec("cat " + cpuFreqPath + "/scaling_available_governors");
  84. is = new DataInputStream(process.getInputStream());
  85. String line = is.readLine();
  86. String[] strs = line.split(" ");
  87. for (int i = 0; i < strs.length; i++)
  88. governors.add(strs[i]);
  89. } catch (IOException e) {
  90. Log.i(TAG, "readCpuGovernors: read CPU Governors failed!");
  91. }
  92. return governors;
  93. }
  94. }</span>

完!

android省电开发之cpu降频的更多相关文章

  1. Android Studio快速开发之道

    概述 现如今开发越来越追求效率和节奏,节省出时间做更多的事情,除了开发技术上的封装等,开发工具的使用技巧也是很重要的,今天就根据自己的经验来给大家介绍一下Android Studio快速开发之道. P ...

  2. Android插件化开发之OpenAtlas生成插件信息列表

    上一篇文章.[Android插件化开发之Atlas初体验]( http://blog.csdn.net/sbsujjbcy/article/details/47446733),简单的介绍了使用Atla ...

  3. cpu降频问题

    cpu做为能耗很高的硬件,最近几年厂商在节能方面做了很多处理,在服务器运行时,基于负载情况可调节成节能模式,节省电能,副作用是cpu的频率会降低,导致应用程序性能降低. 有第三方统计,服务器规模达到万 ...

  4. Android控件开发之Gallery3D效果

    package xiaosi.GalleryFlow; import android.app.Activity; import android.os.Bundle; public class Gall ...

  5. Android控件开发之Chronometer(转)

    (转自:http://blog.csdn.net/sun6255028/article/details/6688349) Chronometr是一个简单的定时器,你可以给它一个开始时间,并以此定时,或 ...

  6. Android 4.0开发之GridLayOut布局实践

    在上一篇教程中http://blog.csdn.net/dawanganban/article/details/9952379,我们初步学习了解了GridLayout的布局基本知识,通过学习知道,Gr ...

  7. CentOS7 CPU 降频问题

    CentOS7 系统默认的 CPUPOWER 策略是 powersave 节能模式,Google 了非常多的资料,一直没有找到解决办法,现在分享一下. 执行: tuned-adm profile th ...

  8. Android即时通讯开发之XMPP (一)初识XMPP协议和asmack

    在讲XMPP和asmck之前 ,我还是先分享一些资源文档,如果你有耐心,可以直接忽略我下面所写的.下面有关XMPP的介绍大部分是摘抄网上的文档,后面我会写一些基于XMPP协议和asmck开源库的聊天室 ...

  9. 【Android】安卓开发之activity如何传值到fragment,activity与fragment传值

    作者:程序员小冰,GitHub主页:https://github.com/QQ986945193 新浪微博:http://weibo.com/mcxiaobing 大家知道,我们利用activity使 ...

随机推荐

  1. 3.1决策树理论--python深度机器学习

    参考彭亮老师的视频教程:转载请注明出处及彭亮老师原创 视频教程: http://pan.baidu.com/s/1kVNe5EJ   0. 机器学习中分类和预测算法的评估:   准确率 速度 强壮行 ...

  2. BAE 环境下配置 struts2 + spring + hibernate(SSH)(三)spring&hibernate

    1.在lib中加入必要的包,导入后结果如下: lib打包下载:SSH-lib.jar  (struts2.3.1.2  spring3.0.5 hibernate3.6.10.Final) 只包含必要 ...

  3. IIC 概述之1

    概述: I²C 是Inter-Integrated Circuit的缩写,发音为"eye-squared cee" or "eye-two-cee" , 它是一 ...

  4. JSP语法

    第3章  JSP语法 [本章专家知识导学] JSP是建立在Java语言基础上的一种Web程序设计语言,具有自己特有的用法和指令.本章首先介绍JSP页面的程序结构,然后讲述JSP程序中经常用到基本的面向 ...

  5. UIControl-IOS开发

    UIControl-IOS开发   UIKit提供了一组控件:UISwitch开关.UIButton按钮.UISegmentedControl分段控件.UISlider滑块.UITextField文本 ...

  6. Unity3D 3D横版跑酷 跳跃

    Unity3d 跑酷动画的控制 首先给个图吧, 我们跑酷里面需要动画的,今天说一下动画的知识! 1.导入骨骼动画模型文件之后,如果使用之前版本的unity的播放动画的方式,需要设置AnimationT ...

  7. Frequent values

    poj3368:http://poj.org/problem?id=3368 题意:给你一个非下降的序列,然后查询[l,r]内出现最多数字的次数. 题解:首先,因为序列是非下降的,所以相同的数字出现在 ...

  8. Linux Shell编程(8)——变量详解

    不同与许多其他的编程语言,Bash不以"类型"来区分变量.本质上来说,Bash变量是字符串,但是根据环境的不同,Bash允许变量有整数计算和比较.其中的决定因素是变量的值是不是只含 ...

  9. Linux企业级开发技术(5)——libevent企业级开发之简介

    Libevent是一个用于编写高速可移植非阻塞IO应用的库,它的设计目标是: 可移植性:使用libevent编写的程序应该可以在libevent支持的所有平台上工作.即使没有好的方式进行非阻塞IO,l ...

  10. 总结linux无线命令wpa

    关于wpa_supplicant: 用到wpa_cli命令 wpa_cli -iwlan0 add_network             // wlan0 是无线网络设备的名字,增加一个网络,会返回 ...