android省电开发之cpu降频

本文详细介绍在Android环境中调整CPU频率的方法,包括5种调控模式及其应用。通过命令行及Java代码实现CPU频率的调整,达到省电目的。
部署运行你感兴趣的模型镜像

众所周知,在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方面,提供了如下集中调控模式,分别为:

 

GovernorSelect this governor ifHow it works
performancePerformance is the only consideration.Sets the CPU to run at the highest frequency (scaling_max_freq)
powersaveEfficiency is the only considerationSets the CPU to run at the lowest frequency (scaling_min_freq)
ondemandAdaptation 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.
conservativeClose 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.
userspaceControl 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端的开发中,我们如何使用呢?

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

[java]  view plain copy
  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.   
  26.     private final static String PERFORMANCE_GOVERNOR = "performance";  
  27.     private final static String POWER_SAVE_GOVERNOR = "performance";  
  28.     private final static String ONDEMAND_GOVERNOR = "performance";  
  29.     private final static String CONSERVATIVE_GOVERNOR = "performance";  
  30.     private final static String USERSAPCE_GOVERNOR = "performance";  
  31.   
  32. //  public void powerSaveGovernor() {  
  33. //      List<String> governors = readCpuGovernors();  
  34. //      if (governors.contains(object)) {  
  35. //  
  36. //      }  
  37. //  }  
  38.   
  39.     /** 
  40.      * 获得当前CPU调控模式 
  41.      */  
  42.     public void getCpuCurGovernor() {  
  43.         try {  
  44.             DataInputStream is = null;  
  45.             Process process = Runtime.getRuntime().exec("cat " + cpuFreqPath + "/scaling_governor");  
  46.             is = new DataInputStream(process.getInputStream());  
  47.             String line = is.readLine();  
  48.         } catch (IOException e) {  
  49.             e.printStackTrace();  
  50.         }  
  51.     }  
  52.   
  53.     /** 
  54.      * 重写CPU调控模式 
  55.      * @param governor 
  56.      * @return 
  57.      */  
  58.     private boolean writeCpuGovernor(String governor) {  
  59.         DataOutputStream os = null;  
  60.         byte[] buffer = new byte[256];  
  61.         String command = "echo " + governor + " > " + cpuFreqPath + "/scaling_governor";  
  62.         Log.i(TAG, "command: " + command);  
  63.         try {  
  64.             Process process = Runtime.getRuntime().exec("su");  
  65.             os = new DataOutputStream(process.getOutputStream());  
  66.             os.writeBytes(command + "\n");  
  67.             os.writeBytes("exit\n");  
  68.             os.flush();  
  69.             process.waitFor();  
  70.             Log.i(TAG, "exit value = " + process.exitValue());  
  71.         } catch (IOException e) {  
  72.             Log.i(TAG, "writeCpuGovernor: write CPU Governor(" + governor + ") failed!");  
  73.             return false;  
  74.         } catch (InterruptedException e) {  
  75.             e.printStackTrace();  
  76.         }  
  77.         return true;  
  78.     }  
  79.   
  80.     /** 
  81.      * 获得CPU所有调控模式 
  82.      * @return 
  83.      */  
  84.     private List<String> readCpuGovernors() {  
  85.         List<String> governors = new ArrayList<String>();  
  86.         DataInputStream is = null;  
  87.         try {  
  88.             Process process = Runtime.getRuntime().exec("cat " + cpuFreqPath + "/scaling_available_governors");  
  89.             is = new DataInputStream(process.getInputStream());  
  90.             String line = is.readLine();  
  91.   
  92.             String[] strs = line.split(" ");  
  93.             for (int i = 0; i < strs.length; i++)  
  94.                 governors.add(strs[i]);  
  95.         } catch (IOException e) {  
  96.             Log.i(TAG, "readCpuGovernors: read CPU Governors failed!");  
  97.         }  
  98.         return governors;  
  99.     }  
  100. }</span>  
转自:http://blog.youkuaiyun.com/matrix_xu/article/details/8509319

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

<think>我们正在处理一个关于限制Android设备上应用或系统整体CPU使用率的问题。根据用户的问题,我们需要提供可行的解决方案。 首先,我们需要理解Android系统本身并没有直接提供限制单个应用或系统整体CPU使用率的功能。但是,我们可以通过一些间接的方法来实现类似的效果。 参考我们已有的知识: - 引用[1]提到了Android中抓取CPU数据的命令`dumpsys cpuinfo`,这可以帮助我们监控CPU使用情况。 - 引用[4]提供了查看内存和CPU信息的命令,其中包含了一些内存和CPU的统计数据。 然而,用户的需求是“限制”而不是“监控”。因此,我们需要寻找限制CPU使用率的方法。 可能的解决方案包括: 1. **使用cgroups**:Android基于Linux内核,而Linux内核提供了cgroups(控制组)功能来限制进程的资源使用。我们可以尝试将目标进程放入一个cgroup中,并设置该cgroup的CPU配额。 2. **调整CPU频率(降频)**:通过降低CPU的最大运行频率,可以间接限制整个系统的CPU使用率,但这会影响所有应用。 3. **使用性能调节工具**:如使用`cpulimit`这样的工具(在Linux上常用),但需要确认Android上是否可用。 4. **使用Android的API或系统设置**:在开发者选项或系统设置中,可能有一些选项可以限制后台进程的CPU使用。 由于Android系统通常没有直接提供这样的功能,因此可能需要root权限或修改系统。 具体步骤: ### 方法1:使用cgroups(需要root) 在Android中,cgroups被用于管理进程资源。我们可以通过以下步骤限制某个进程的CPU使用: 1. 找到目标进程的PID(进程ID)。 2. 将该PID写入到指定的cgroup控制文件中。 例如,在Android设备上,cgroups通常挂载在`/sys/fs/cgroup`目录下。我们可以使用`cpu`子系统来限制CPU使用。 具体操作: ```shell # 创建新的cgroup mkdir /sys/fs/cgroup/cpu/tg1 # 设置该cgroup的CPU配额(比如限制为50%) echo 50000 > /sys/fs/cgroup/cpu/tg1/cpu.cfs_quota_us # 周期为100000us(100ms),配额为50000us(50ms),即50% # 将进程PID加入到该cgroup echo [PID] > /sys/fs/cgroup/cpu/tg1/tasks ``` 注意:这需要root权限,并且每次重启后需要重新设置。 ### 方法2:调整CPU频率 通过降低CPU的最大频率,可以限制整个系统的CPU使用率。但这会影响所有应用,并且可能导致性能下降。 ```shell # 查看可用的CPU频率 cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies # 设置最大频率(例如设置为最低频率) echo [最低频率] > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq ``` 同样需要root权限。 ### 方法3:使用cpulimit工具(需要安装) 如果Android设备上可以运行Linux工具,我们可以尝试交叉编译`cpulimit`并推送到设备上使用。使用示例: ```shell cpulimit -p [PID] -l 50 # 限制PID进程的CPU使用率为50% ``` ### 方法4:使用Android系统设置 在“开发者选项”中,有一个“后台进程限制”设置,可以限制后台进程的数量,间接减少CPU使用。另外,在“电池优化”设置中,可以限制应用在后台的活动,从而减少CPU使用。 ### 针对系统整体 对于系统整体,我们可以通过调整CPU调度器参数或使用节能模式来降低CPU使用率。例如,在设置中开启“省电模式”会降低CPU性能以节省电量。 ### 注意事项 - 上述方法中,很多需要root权限,普通用户可能无法使用。 - 限制系统整体CPU使用率可能会影响设备性能,导致卡顿。 - 对于单个应用,如果该应用有后台服务,可以考虑通过“设置”->“应用”->“强制停止”来停止其运行,但这只是临时措施。 ### 总结 根据用户的需求,我们可以提供多种方法,但需要根据用户设备的实际情况(是否root)来选择。对于普通用户,建议使用系统自带的省电模式或后台限制功能。对于root用户,可以使用cgroups或调整CPU频率的方法。 §§相关问题§§ 1. 如何在不root的情况下限制Android应用的CPU使用率? 2. 在Android上使用cgroups限制CPU使用率的具体步骤是什么? 3. 调整CPU频率对设备性能有什么影响? 4. 如何监控Android应用的CPU使用率?</think>### 限制 Android 应用或系统 CPU 使用率的解决方案 #### 一、限制单个应用的 CPU 使用率 1. **使用 Android Profiler 监控与优化** 通过 Android Studio 的 [Profiler 工具](https://developer.android.com/studio/profile) 分析 CPU 占用: ```bash # 命令行监控 CPU 使用 adb shell dumpsys cpuinfo | grep "com.example.app" ``` 优化代码中高 CPU 占用的算法(如减少循环嵌套、避免频繁 GC)[^1]。 2. **后台服务限制** 在 `AndroidManifest.xml` 中声明后台限制: ```xml <service android:name=".MyService" android:foregroundServiceType="location" android:usesCleartextTraffic="true" /> ``` 同时调用 `startForeground()` 提升服务优先级[^3]。 3. **使用 WorkManager 节流** 对后台任务添加 CPU 约束: ```kotlin val constraints = Constraints.Builder() .setRequiresDeviceIdle(true) // 设备空闲时执行 .build() ``` #### 二、限制系统整体 CPU 使用率 1. **调整 CPU 频率(需 Root)** 通过修改内核参数降频: ```bash # 查看可用频率 cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies # 设置最大频率(示例值) echo 1497600 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq ``` 2. **使用 cgroups 限制进程组** Android 利用 cgroups 实现资源隔离: ```bash # 创建 cgroup mkdir /dev/cpulimit echo 50000 > /dev/cpulimit/cpu.cfs_quota_us # 限制 50% CPU # 添加进程 echo [PID] > /dev/cpulimit/tasks ``` 3. **开启省电模式** 系统级限制(无需 Root): ```java // 代码中激活省电模式 PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); if (pm.isPowerSaveMode()) { // 降低后台活动频率 } ``` #### 三、监控工具 | 工具 | 命令/用法 | 监控对象 | |------|-----------|----------| | **dumpsys cpuinfo** | `adb shell dumpsys cpuinfo` | 系统整体 + 进程级[^1] | | **/proc/stat** | `cat /proc/stat` | CPU 核心利用率 | | **Memory Profiler** | Android Studio → Profiler | 实时线程分析 | > **注意事项**: > - 系统级限制需 Root 权限,可能影响设备稳定性 > - 应用级优化优先使用官方约束 API > - 持续高负载可能触发系统自带的[thermal throttling](https://source.android.com/docs/core/power/thermal)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值