Android 8.0 以后 CPU 使用率的方案研究

栏目: IOS · Android · 发布时间: 5年前

内容简介:由于Android 8.0以后Google的权限限制,SDK再也拿不到进程CPU的实时占用率,只能拿到自己本身进程的Jiffies,而由于拿不到系统整体Jiffies的情况下,就没办法衡量CPU当前的消耗状况了,也没办法根据当前CPU状态实时做一些策略调整。因此进行深入研究以后,给出Android 8.0以后判断CPU状态的几个参考方案(非标准答案)。1)Jiffies2)Tick

由于Android 8.0以后Google的权限限制,SDK再也拿不到进程CPU的实时占用率,只能拿到自己本身进程的Jiffies,而由于拿不到系统整体Jiffies的情况下,就没办法衡量CPU当前的消耗状况了,也没办法根据当前CPU状态实时做一些策略调整。因此进行深入研究以后,给出Android 8.0以后判断CPU状态的几个参考方案(非标准答案)。

方案1 - 通过单位时间汇编指令数获取CPU频率

(1)基础概念:

1)Jiffies
全局变量jiffies用来记录自系统启动以来产生的节拍的总数。启动时,内核将该变量初始化为0,此后,每次时钟中断处理程序都会增加该变量的值。一秒内时钟中断的次数等于Hz,所以jiffies一秒内增加的值也就是Hz。

2)Tick
HZ的倒数,意即timer interrupt每发生一次中断的时间。如HZ为250时,tick为4毫秒。

(2)原理:

由于我们可以控制一条汇编指令,在任意型号CPU上是都是在一个时钟周期内完成的(原子化操作),比如:

因此,在这里每一次CPU数据采样都是传循环参数10000次,也就是执行add指令130*10000次,然后我们循环执行20轮,计算出执行130*10000指令花费的最小一轮(130*10000条指令)时间min_time_s

Android 8.0 以后 CPU 使用率的方案研究

每一条指令消耗的时间为:

而cpu频率则是cost的倒数,也就是单位时间(s)内执行cycles的数量

执行130*10000次

Android 8.0 以后 CPU 使用率的方案研究

Android 8.0 以后 CPU 使用率的方案研究

Android 8.0 以后 CPU 使用率的方案研究

Android 8.0 以后 CPU 使用率的方案研究

方案2 - 通过在代码内部执行TOP获取CPU占比

我们可以看看top命令的源码

Android 8.0 以后 CPU 使用率的方案研究

Android 8.0 以后 CPU 使用率的方案研究

可以看到TOP本身也是拿到/proc/stat后统计的。在这里我有一个问题也没弄明白,就是在代码内部我有权限执行top命令,此时top命令是当前进程fork出来的,应该理论上是继承了父进程的权限才对,但实际上父进程没有权限访问/proc/stat。所以本想把top的具体实现挪出来,目前只能直接驱动top命令。因此这种方案应用于实时性以及性能开销要求不高的监控程序。

Android 8.0 以后 CPU 使用率的方案研究

方案3 - 直接看/proc/$pid/stat的Jiffies值

这种方案使用场景比较受限,用来判断当前进程的性能消耗比较准确。但是如果该设备别的应用程序导致CPU占比很高,但是自己程序的Jiffies值很小,就误以为设备不繁忙然后开了一堆线程过去,那可能设备就会挂掉。具体可以看后续的实验,在这里也给出一段参考代码:

Android 8.0 以后 CPU 使用率的方案研究

方案4 - 读取CPU各个核的当前频率

由于CPU的频率档位是离散的,因此各个核的频率变化不是连续的,而是一个离散的值,而且由于Android为了 Linux 系统稳定运行,会对几个核锁频。那怎么计算CPU的频率呢?
有下面几个步骤:

1)拿到各个核心的当前频率

2)拿到CPU的频率档位

3)解析当前进程/线程被系统分派到哪几个核上

Android 8.0 以后 CPU 使用率的方案研究

如果想看线程纬度的,可以执行cat /proc/$pid/task/$tid/status。

在这里需要了解一个概念叫CPU亲和性,CPU 亲和性(affinity) 就是进程要在某个给定的CPU上尽量长时间地运行而不被迁移到其他处理器的倾向性。其实Cpus_allowed或者Cpus_allowed_list都可以看出CPU的分配。比如Cpus_allowed: 0f,这里十六进制0f转换成二进制是1111,由于最低位到最高位均为1代表系统给这个进程分派的CPU是0-3;以此类推,Cpus_allowed: 20二进制是100000,因此高位在第6位,也就是分配了CPU5。

Android 8.0 以后 CPU 使用率的方案研究

1)再算这几个核的频率使用情况

2)进程PID所在核,通过 cat /proc/$pid/task/$tid/status查看

Android 8.0 以后 CPU 使用率的方案研究

具体计算方式可以看下面代码的注释

Android 8.0 以后 CPU 使用率的方案研究

实验验证:

由于top的cpu比例是可以用来作为参考标准的,但由于top执行的时延,可能会导致top拿到的数据跟汇编拿到的数据时间上有偏移导致不准确,因此想到一个方案就是写一个死循环,让CPU每时每刻跑满,这样来验证一下数据获取的稳定性问题。
下面做了几组实验,看看实验数据,数据标示统一说明:

1)top Cpu值: 采用top命令获取的进程cpu占比(方案2)

2)当前进程cpu时间片累计:/proc/$pid/stat的Jiffies在时间段内的消耗的时间片(方案3)

3)当前cpu频率:使用汇编指令计算频率,1.612903168E9为1.613Ghz(方案1)

4)CPUWeightUsage:读取CPU各个核的当前频率来计算频率占用率(方案4)

实验1 - 进程内部CPU开销很小时(0%)

当CPU没有占用资源开销时,TOP值执行准确,当前进程cpu时间片累计数也很低,Process CPUWeightUsage反应的是当前这个CPU核繁忙程度,因此可以看到CPU空闲率偏高。

Android 8.0 以后 CPU 使用率的方案研究

Android 8.0 以后 CPU 使用率的方案研究

Android 8.0 以后 CPU 使用率的方案研究

Android 8.0 以后 CPU 使用率的方案研究

实验2 - 进程内部CPU开销偏大时(40%)

通过这组实验可以看出进程所在CPU开销波动很大,为什么不像top值那么准呢?
其实这个是最准确的,因为我在写进程占用程序时,是用sleep来控制CPU占用,因此呈现周期性,从0%~100%才是正常的,但是TOP指令是一个时间段内均匀的数值。另一个佐证的办法就是看当前cpu频率,可以看到通过汇编取到的整机CPU频率是很高的,基本到达了最高频率,但TOP值监控不到。

Android 8.0 以后 CPU 使用率的方案研究

Android 8.0 以后 CPU 使用率的方案研究

Android 8.0 以后 CPU 使用率的方案研究

实验3 - 进程内部CPU开销很大时(100%)

在这里可以看到时间片消耗特别多,Process CPUWeightUsage跟top均能反应当前进程的性能状况

Android 8.0 以后 CPU 使用率的方案研究

Android 8.0 以后 CPU 使用率的方案研究

实验4 - 该设备其他应用进程CPU正常开销时(15%)

经查看,两个应用进程被系统分配到不同的CPU上,因此理论上来说,测试APP的资源占用跟实验1应该比较一致,事实上也的确如此。top跟Process CPUWeightUsage可以很好的反应当前状态。

Android 8.0 以后 CPU 使用率的方案研究

Android 8.0 以后 CPU 使用率的方案研究

Android 8.0 以后 CPU 使用率的方案研究

Android 8.0 以后 CPU 使用率的方案研究

实验5 - 该设备其他应用进程CPU开销很大时(100%)

在这个实验中,启用了一个CPU占用100%的其他应用(图中上面的进程),同时启用了测试APP(图中下面的进程)
![IMAGE](docs/205D7EBDF0FBF84AF267950EDD1231B2.jpg =1697x137)
可以看到两个进程,系统分在不同的CPU上,因此不会发生资源抢占的情况,但此时设备的性能状态是比较繁忙的。在这种情况下,top命令是检测不到的,
而CPUWeightUsage则能看出空载率不是很高,时不时会出现CPU满载的情况,但整体自身CPU影响不太大。经实测,在测试APP上也没有卡顿现象发生。

Android 8.0 以后 CPU 使用率的方案研究

Android 8.0 以后 CPU 使用率的方案研究

Android 8.0 以后 CPU 使用率的方案研究

Android 8.0 以后 CPU 使用率的方案研究

实验结论:

通过几组实验可以发现TOP整体来说是比较准确的,但是耗时太大,资源消耗也大;汇编指令方案并不能很好的反应当前应用APP所在CPU核心的繁忙程度,但可以反应整机CPU繁忙程度;Process CPUWeightUsage可以基本上可以实时反应当前设备以及进程所在CPU核的繁忙程度。

综合来说方案4的场景覆盖能力比较强,因此建议用方案4结合方案3一起综合评价:

1)当Process CPUWeightUsage使用率频繁在80%以上时(5次有3次),可以认定为高繁忙状态;

2)当Process CPUWeightUsage使用率频繁在50%~80%之间时,可以认定为普通状态;

3)当Process CPUWeightUsage使用率有较多次出现0%的情况或者50%以下较多时,可以多分配一些任务,CPU基本上比较空闲。

此外需要说明的是:

(1)使用CPU频率的方式来评估设备以及程序繁忙程度,只能用与以前不一样的惯性思维去做。原来CPU可能在占用40%左右,发热就很明显了,而用频率监控的方案,由于CPU自身的调节机制,频率无时无刻都在改变,因此,我们需要看CPU低频跟高频比例,当CPU处于低频状态多,那就可以多分配任务,当CPU处在高频状态多,那就少分配任务。另外还可以结合进程单位时间消耗的时间片增长率变化来评估自身APP是不是处于任务过多的状态。
(2)尽量不要以CPU绝对占用率来做任务分派,只要评估执行任务执行时间可以在较短的时间内完成,不出现死循环的情况,一般CPU都有自己的策略方案,例如interactive或者ondemand等,都会根据当前任务自动调整。
(3)有时候可能自己进程什么事情都没干,但有可能出现测试频率很高的情况,因为CPU的核不一定只跑当前应用,还有很多其他任务需要执行,尤其是当系统将应用分派到一个大核上时,这种波动上下限会更多。

后期我们会根据每个维度陆续写相关的测试文章,如果你有兴趣,请关注我们哦。

长按指纹识别图中的二维码,获取更多测试干货分享!

Android 8.0 以后 CPU 使用率的方案研究
Android 8.0 以后 CPU 使用率的方案研究

Android 8.0 以后 CPU 使用率的方案研究   将我们公众号置顶   不会漏掉我们的原创干货哦!


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

程序员的自我修养

程序员的自我修养

陈逸鹤 / 清华大学出版社 / 2017-5 / 49.00

程序员作为一个职业、也作为一个群体,正逐渐从幕后走向前台,并以他们自己的能力加速改变着世界,也改变着人们生活的方方面面。然而,对于程序员,特别是年轻程序员们来说,如何理解自己的职业与发展,如何看待自己的工作与生活,这些问题往往比那些摆在面前的技术难题更让他们难以解答。 这本书从一个成熟程序员、一名IT管理者的角度,以杂记的形式为大家分享关于国内程序员职业生涯、个人发展、编程中的实践与认知乃至......一起来看看 《程序员的自我修养》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

URL 编码/解码
URL 编码/解码

URL 编码/解码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具