当前位置: 首页 > 科技观察

Android设备CPU锁频

时间:2023-03-11 23:20:11 科技观察

本文详细介绍了查看Android设备CPU状态的方法和锁频(lockfrequency)的方法。这有什么用?作为测试工程师,您应该知道。CPU频率首先,让我们谈谈CPU的频率。众所周知,CPU的运行频率越高,计算速度越快,但能耗也越高。然而,在很多情况下,设备并不需要这么高的计算性能。这时候我们就希望降低CPU的运行频率,追求更低的能耗,从而达到更长的待机时间。基于这种需求,目前电子设备的CPU具有多种工作频率,可以根据实际场景自动切换CPU频率,从而达到平衡计算性能和能耗的目的。锁频的目的那么为什么需要锁频呢?对于普通用户来说,这些场景你可能并不陌生:在家用笔记本玩游戏,电脑连着电源,根本不在乎能耗。他们只是想要尽可能高的性能,这时候就选择高性能模式,也就是让CPU一直工作在最高频率。在旅行时使用笔记本电脑时,它由电池供电。我希望计算机可以尽可能长时间处于待机状态。这时候我选择的是省电模式,也就是CPU一直运行在最高频率。作为测试工程师,我们在进行软件测试时,为了让测试结果真实的反映软件本身的效率,从控制变量法的角度,我们希望测试结果不受硬件本身的影响越多越好。这时候我们可以尝试锁定设备的CPU频率,即保证硬件设备的CPU在测试过程中运行在一个恒定的频率。说到这里,我先来个伏笔。在chromium官方测试库中,一些测试场景在初始化测试环境时,会把设备所有CPU的频率调到最高状态。稍后我会单独写一篇博文。分析了那部分源代码。等不及的朋友可以先去看源码,源码路径为pylib/perf/PerfControl.SetHighPerfMode。查看CPU状态信息在修改CPU状态之前,我们需要查看CPU的属性和状态信息,这样才能有的放矢地进行正确的设置。对于CPU的状态,我们通常会关注两类信息,一类是整体水平,即CPU运行的核心数;另一个是详细级别,即每个CPU的工作状态,包括工作模式和频率。在Android系统中,CPU相关信息存放在/sys/devices/system/cpu目录下的文件中。我们可以通过读取该目录下的特定文件来获取当前设备的CPU状态信息,也可以通过向特定文件写入值来改变CPU频率等状态信息。本文以Nexus5(系统版本5.1.1)为例,以下示例均以该设备为例。请注意,不同型号和安卓系统版本之间可能存在一些差异。在/sys/devices/system/cpu目录下,文件结构如下。shell@hammerhead:/sys/devices/system/cpu$lldrwxr-xr-xrootroot2016-01-2001:36cpu0drwxr-xr-xrootroot2016-01-2021:06cpu1drwxr-xr-xrootroot2016-01-2021:07cpu2drwxr-xr-xroot-0root2016-2021:07cpu3-rw------rootroot40961970-01-1710:27cpuctldrwxr-xr-xrootroot1970-01-1710:27cpufreqdrwxr-xr-xrootroot1970-01-1710:27cpuidle-r--r--r--rootroot40961970-01-1710:27kernel_max-r--r--r--rootrootroot40961970-01-1710:27offline-r--r--r--rootroot40961970-01-1710:27online-r--r--r--rootroot40961970-01-1710:27possibledrwxr-xr-xrootroot1970-01-1710:27power-r--r--r--rootroot40961970-01-1710:27present-rw-r--r--rootroot40961970-01-1710:27uevent1,查看整体cpu信息在可能的文件中,存储了当前设备可用的CPU,显示形式为数字形式。例如0-3表示当前设备共有4个核心,编号分别为0、1、2、3。shell@hammerhead:/sys/devices/system/cpu$catpossible0-3在线文件中存储了当前设备运行的CPU。因为有时设备不需要高性能,可以关闭部分CPU。但需要注意的是,无论何时,CPU0始终处于运行状态。在线文件的存储格式与可能的类似。如果只有部分CPU在运行,CPU编号不连续,则用逗号隔开;例如0,2表示当前CPU0和CPU2正在运行。shell@hammerhead:/sys/devices/system/cpu$catonline0,2对应,offline文件表示当前设备处于off状态的CPU,与online互补,union正好是所有的设备的CPU,即内容中可能的文件。shell@hammerhead:/sys/devices/system/cpu$catoffline1,32,查看指定cpu信息接下来如果我们要获取具体CPU的信息,需要进入对应的文件夹,比如cpu0/对应CPU0信息。在/sys/devices/system/cpu/cpu0目录下,文件结构如下。shell@hammerhead:/sys/devices/system/cpu$llcpu0drwxr-xr-xrootroot2016-01-2001:37cpufreqdrwxr-xr-xrootroot1970-01-1710:27cpuidle-r------rootroot40961970-01-1710:27crash_notes-rw-r--r--rootroot40962016-01-2001:36onlinedrwxr-xr-xrootroot1970-01-1710:27powerdrwxr-xr-xrootroot1970-01-1710:27rq-statslrwxrwxrwxrootroot1970-01-1710-rootrwx70217子系统拓扑101919rw-r--r--rootroot40961970-01-1710:27uevent其中在线文件内容表示当前CPU是否运行。如果正在运行,内容为1,否则为0;这个可以对应上面提到的/sys/devices/system/cpu/online。shell@hammerhead:/sys/devices/system/cpu$catcpu0/online1存放在cpu0/cpufreq/目录下,里面存放了CPU0频率相关的信息。文件结构如下。shell@hammerhead:/sys/devices/system/cpu$llcpu0/cpufreq/-rw-r--r--rootroot40962016-01-2001:57UV_mV_table-r--r--r--rootroot40962016-01-2001:57affected_cpus-r--r--r--rootroot40962016-01-2001:57cpu_utilization-r--------rootroot40962016-01-2001:57cpuinfo_cur_freq-r--r--r--rootroot40962016-01-2002:00cpuinfo_max_freq-r--r--r--rootroot40962016-01-2001:39cpuinfo_min_freq-r--r--r--rootroot40962016-01-2001:57cpuinfo_transition_latency-r--r--r--rootroot40962016-01-2001:57related_cpus-r--r--r--rootroot40962016-01-2001:39scaling_available_frequencies-r--r--r--rootroot40962016-01-2001:57scaling_available_governors-r--r--r--rootroot40962016-01-2001:50scaling_cur_freq-r--r--r--rootroot40962016-01-2001:57scaling_driver-rw-r--r--rootroot40962016-01-2001:50scaling_governor-rw-r--r--rootroot40962016-01-2008:29scaling_max_freq-rw-r--r--rootroot40962016-01-2008:29scaling_min_freq-rw-r--r--rootroot40962016-01-2002:52scaling_setspeed在这个目录中,我们需要更多关注的文件比对。第一个是scaling_available_governors和scaling_governor。这里的governor可以理解为CPU的工作模式。scaling_available_governors存储了当前CPU支持的所有工作模式,scaling_governor存储了CPU当前的工作模式。shell@hammerhead:/sys/devices/system/cpu$catcpu0/cpufreq/scaling_available_governorsimpulsedancedancesmartmaxinteractiveconservativeondemanduserspacepowersaveLionheartbioshockperformanceshell@hammerhead:/sys/devices/system/cpu$catcpu0/cpufreq/scaling_governorperformance可以看这里简单描述几种常见的模式。performance:最大性能模式,即使系统负载很低,cpu也以最大频率运行。powersave:省电模式,与性能模式相反,cpu始终运行在最大频率。ondemand:CPU频率根据系统负载而变化。userspace:可以简单理解为自定义模式,可以设置频率。各种模式对应的含义和策略这里就不展开了,有兴趣的可以自行搜索。然后是CPU的工作频率范围。对应的文件有cpuinfo_max_freq、cpuinfo_min_freq、scaling_max_freq、scaling_min_freq。cpuinfo_前缀表示CPU硬件支持的频率范围,反映了CPU本身的特性,与CPU的工作模式无关。并以scaling_为前缀表示CPU在当前工作模式下的频率范围。那么,当前CPU的运行频率是多少,我们如何查看呢?检查cpuinfo_cur_freq或scaling_cur_freq。cpuinfo_cur_freq表示硬件实际读取的频率值,scaling_cur_freq是软件当前的设置值。在大多数情况下,这两个值是一致的,但由于硬件原因可能会略有不同。root@hammerhead:/sys/devices/system/cpu/cpu0/cpufreq#catcpuinfo_cur_freq1574400root@hammerhead:/sys/devices/system/cpu/cpu0/cpufreq#catscaling_cur_freq1574400更改CPU状态信息***回到我们的主题文章,如何设置CPU的频率呢?这也对应CPU信息的查看,分为CPU整体运行的设置和具体CPU工作模式的设置。这里,有两点需要特别说明。首先,对于高通的CPU,有一个系统服务叫做mpdecisionservice。当这个系统服务运行时,我们不能改变CPU的状态信息。因此,如果我们要改变高通CPU的工作模式,首先要做的就是终止mpdecision系统服务。操作也很简单,在Androidshell中执行如下命令即可。关于stopmpdecision的第二个需要注意的是,如果我们要设置特定CPU的工作状态,我们必须将scaling_governor设置为userspace。这样才能设置scaling_setspeed。root@hammerhead:/sys/devices/system/cpu/cpu0/cpufreq#catscaling_setspeed/cpufreq#catscaling_setspeed15744001,设置整体cpu信息从宏观上,我们可以设置CPU上运行的核心数,以启用和禁用特定的CPU。当然,正如我们之前所说,CPU0会一直运行,所以我们不能关闭CPU0。设置方法很简单,在/sys/devices/system/cpu/cpu[i]/online文件中写入值即可,写入1时开启指定CPU,写入0时关闭指定CPU.#turnoffcpu1root@hammerhead:/sys/devices/system/cpu/cpu1#echo0>onlineroot@hammerhead:/sys/devices/system/cpu/cpu1#catonline02、setspecifiedcpuinfo在设置特定CPU的频率之前,我们需要知道的是CPU不能工作在任何频率,我们只能将CPU的频率设置为它支持的值。通过查看scaling_available_frequencies,我们可以得到当前CPU支持的频率值。root@hammerhead:/sys/devices/system/cpu/cpu0/cpufreq#catscaling_available_frequencies3000004224006528007296008832009600001036800119040012672001497600接下来我们可以设置CPU的运行频率。如何设置?一开始我以为把具体的频率值写入scaling_setspeed或者scaling_cur_freq就可以了,和google搜索得到的方法是一样的。但是尝试过后发现不可行。为什么是这样?目前还没有找到答案,希望知道原因的大神告诉我。***经过尝试,发现通过同时设置scaling_max_freq和scaling_min_freq为目标频率值,可以成功设置CPU频率。#beforesettingshell@hammerhead:/sys/devices/system/cpu/cpu0/cpufreq$catscaling_cur_freq1574400#settingshell@hammerhead:/sys/devices/system/cpu/cpu0/cpufreq$echo1728000>scaling_min_freqshell@hammerhead:/sys/devices/system/cpu/cpu0/cpufreq$echo1728000>scaling_max_freq#aftersettingshell@hammerhead:/sys/devices/system/cpu/cpu0/cpufreq$catscaling_cur_freq1728000