CPU是系统非常重要的资源,在Android中,查看CPU使用情况,可以使用top命令和dump cpuinfo。我记得很久以前,就发现这两者存在不同,初步猜测应该是算法上存在差异。最近需要采集应用CPU的使用率,看了一下两种CPU的计算方法。

1、top

top是比较经典的CPU计算方法,top的代码在androidm/system/core/toolbox/top.c下面,输出process的cpu使用率在print_procs里面:

static void print_procs(void) {
...for (i = 0; i < num_new_procs; i++) {if (new_procs[i]) {old_proc = find_old_proc(new_procs[i]->pid, new_procs[i]->tid);if (old_proc) {new_procs[i]->delta_utime = new_procs[i]->utime - old_proc->utime;new_procs[i]->delta_stime = new_procs[i]->stime - old_proc->stime;} else {new_procs[i]->delta_utime = 0;new_procs[i]->delta_stime = 0;}new_procs[i]->delta_time = new_procs[i]->delta_utime + new_procs[i]->delta_stime;}}total_delta_time = (new_cpu.utime + new_cpu.ntime + new_cpu.stime + new_cpu.itime+ new_cpu.iowtime + new_cpu.irqtime + new_cpu.sirqtime)- (old_cpu.utime + old_cpu.ntime + old_cpu.stime + old_cpu.itime+ old_cpu.iowtime + old_cpu.irqtime + old_cpu.sirqtime);...if (!threads) {printf("%5d %2d %3" PRIu64 "%% %c %5d %6" PRIu64 "K %6" PRIu64 "K %3s %-8.8s %s\n",proc->pid, proc->prs, proc->delta_time * 100 / total_delta_time, proc->state, proc->num_threads,proc->vss / 1024, proc->rss * getpagesize() / 1024, proc->policy, user_str, proc->name[0] != 0 ? proc->name : proc->tname);} else {printf("%5d %5d %2d %3" PRIu64 "%% %c %6" PRIu64 "K %6" PRIu64 "K %3s %-8.8s %-15s %s\n",proc->pid, proc->tid, proc->prs, proc->delta_time * 100 / total_delta_time, proc->state,proc->vss / 1024, proc->rss * getpagesize() / 1024, proc->policy, user_str, proc->tname, proc->name);}
...
}

CPU的计算是proc->delta_time * 100 / total_delta_time。

先看total_delta_time由:

    total_delta_time = (new_cpu.utime + new_cpu.ntime + new_cpu.stime + new_cpu.itime+ new_cpu.iowtime + new_cpu.irqtime + new_cpu.sirqtime)- (old_cpu.utime + old_cpu.ntime + old_cpu.stime + old_cpu.itime+ old_cpu.iowtime + old_cpu.irqtime + old_cpu.sirqtime);

而这些变量的值,是在read_procs通过读取/proc/stat的jiffies得到:

static void read_procs(void) {
...proc_dir = opendir("/proc");if (!proc_dir) die("Could not open /proc.\n");new_procs = calloc(INIT_PROCS * (threads ? THREAD_MULT : 1), sizeof(struct proc_info *));num_new_procs = INIT_PROCS * (threads ? THREAD_MULT : 1);file = fopen("/proc/stat", "r");if (!file) die("Could not open /proc/stat.\n");fscanf(file, "cpu  %lu %lu %lu %lu %lu %lu %lu", &new_cpu.utime, &new_cpu.ntime, &new_cpu.stime,&new_cpu.itime, &new_cpu.iowtime, &new_cpu.irqtime, &new_cpu.sirqtime);fclose(file);

而proc->delta_time是两次读取/proc/pid/stat相减得到:

static int read_stat(char *filename, struct proc_info *proc) {
.../* Scan rest of string. */sscanf(close_paren + 1," %c " "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d ""%" SCNu64"%" SCNu64 "%*d %*d %*d %*d %*d %*d %*d ""%" SCNu64"%" SCNu64 "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d ""%d",&proc->state,&proc->utime,&proc->stime,&proc->vss,&proc->rss,&proc->prs);return 0;
}

可见,top是一段时间内,计算process的cpu jiffies与总的cpu jiffies差值得到。

2、dump cpuinfo

dump cpuinfo是Android特有的命令(我一直都android的各种dump、trace非常感兴趣,快玩物丧志了。。。)。dump cpuinfo命令的实现在androidm/frameworks/base/core/java/com/android/internal/os/ProcessCpuTracker.java类里面,方法是printCurrentState:

final public String printCurrentState(long now) {
...int N = mWorkingProcs.size();for (int i=0; i<N; i++) {Stats st = mWorkingProcs.get(i);printProcessCPU(pw, st.added ? " +" : (st.removed ? " -": "  "),st.pid, st.name, (int)st.rel_uptime,st.rel_utime, st.rel_stime, 0, 0, 0, st.rel_minfaults, st.rel_majfaults);if (!st.removed && st.workingThreads != null) {int M = st.workingThreads.size();for (int j=0; j<M; j++) {Stats tst = st.workingThreads.get(j);printProcessCPU(pw,tst.added ? "   +" : (tst.removed ? "   -": "    "),tst.pid, tst.name, (int)st.rel_uptime,tst.rel_utime, tst.rel_stime, 0, 0, 0, 0, 0);}}}...
}

而printProcessCPU输出process CPU的使用情况:

private void printProcessCPU(PrintWriter pw, String prefix, int pid, String label,int totalTime, int user, int system, int iowait, int irq, int softIrq,int minFaults, int majFaults) {pw.print(prefix);if (totalTime == 0) totalTime = 1;printRatio(pw, user+system+iowait+irq+softIrq, totalTime);
...
}

user+system+iowait+irq+softIrq 比totalTime。
看下st个变量的赋值,在collectStats里面:

private int[] collectStats(String statsFile, int parentPid, boolean first,int[] curPids, ArrayList<Stats> allProcs) {int[] pids = Process.getPids(statsFile, curPids);
...final long uptime = SystemClock.uptimeMillis();final long[] procStats = mProcessStatsData;if (!Process.readProcFile(st.statFile.toString(),PROCESS_STATS_FORMAT, null, procStats, null)) {continue;}...if (DEBUG) Slog.v("Load", "Stats changed " + st.name + " pid=" + st.pid+ " utime=" + utime + "-" + st.base_utime+ " stime=" + stime + "-" + st.base_stime+ " minfaults=" + minfaults + "-" + st.base_minfaults+ " majfaults=" + majfaults + "-" + st.base_majfaults);st.rel_uptime = uptime - st.base_uptime;st.base_uptime = uptime;st.rel_utime = (int)(utime - st.base_utime);st.rel_stime = (int)(stime - st.base_stime);st.base_utime = utime;st.base_stime = stime;st.rel_minfaults = (int)(minfaults - st.base_minfaults);st.rel_majfaults = (int)(majfaults - st.base_majfaults);st.base_minfaults = minfaults;st.base_majfaults = majfaults;st.working = true;
...
}

st.rel_utime 和 st.rel_stime还是通过读/proc/pid/stat相减得到,而st.rel_uptime却是通过 SystemClock.uptimeMillis()差值,并不是跟top一样,通过得到总CPU jiffies。

看到这,也就能明白,top跟dump cpuinfo的区别在于:top分母有的是总测CPU jiffies,而dump cpuinfo是uptime,是时间,而并非jiffies,也能解释为什么top出来的cpu,大部分时间会比dump cpuinfo的原因。

Android CPU使用率:top和dump cpuinfo的不同相关推荐

  1. android cpu使用率 代码,实现统计 android手机 CPU使用率

    # -*- coding:utf-8 -*- ''' Created on Sep 10, 2018 @author: SaShuangYiBing ''' import subprocess imp ...

  2. Android CPU使用率

    本文包含以下内容:  1.介绍常见的获取android cpu使用率的方法  2.介绍这些常见方法背后的原理  3.介绍我自己写的一个脚本,这个脚本可以获取各个线程在cpu各个核上的占用率 一.常见的 ...

  3. 花式读取Android CPU使用率

    本文包含以下内容: 1.介绍常见的获取android cpu使用率的方法 2.介绍这些常见方法背后的原理 3.介绍我自己写的一个脚本,这个脚本可以获取各个线程在cpu各个核上的占用率 一.常见的获取A ...

  4. Linux下查看CPU使用率 --- top命令的使用

    在系统维护的过程中,随时可能有需要查看 CPU 使用率,并根据相应信息分析系统状况的需要.在 CentOS 中,可以通过 top 命令来查看 CPU 使用状况.运行 top 命令后,CPU 使用状态会 ...

  5. 【Linux 性能优化】利用perf和CPU使用率定位异常函数

    博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 文章目录 CPU 使用率 进程运行情况查询 使用工具查看CPU使用率 定位导致CPU 使用率过高的函数 perf to ...

  6. CPU使用率达到100%

    CPU使用率居然达到100% http://www.manongjc.com/article/20838.html https://www.yangcs.net/posts/how-to-deal-w ...

  7. Linux —— Ubuntu下C++获取CPU使用率、GPU使用率、GPU温度

      非代码      首先介绍在Ubuntu下不使用代码查看的方式来查看CPU使用率.GPU使用率.GPU温度. 查看CPU使用率:top查看GPU使用率及温度:nvidia-smi   代码     ...

  8. CPU性能篇-CPU使用率

    怎么查看CPU使用率 top 显示了系统总体的CPU和内存使用情况,以及各个进程的资源使用情况 需要关注的内容 us:用户态CPU时间 sy:内核态CPU时间 ni:低优先级用户态CPU时间 id:空 ...

  9. Linux 系统 CPU 使用率简单分析

    CPU 使用率是单位时间内 CPU 使用情况的统计,以百分比的方式展示. CPU 使用率 为了维护 CPU 时间,Linux 通过事先定义的节拍率(内核中表示为 HZ),触发时间中断,并使用全局变量 ...

最新文章

  1. Unity3D常用代码总结
  2. pytorch volatile 和 requires_grad
  3. linux c++开发环境_使用 VM VirtualBox 搭建完善的Linux开发环境
  4. springboot和flowable modeler整合
  5. 2016年,这50家创业公司将真正改变世界
  6. C++中的RAIL风格
  7. IDEA 的文件夹的类型说明
  8. 第6章系统数据文件和信息总结
  9. java oo 封装_javaOO——封装、static、成员内部类
  10. iOS逆向之微信和支付宝修改步数 简洁无脑版
  11. Logism · 八位可控加减法器 实验
  12. 2022-2022阿里巴巴Android面试真题解析,阿里+头条+抖音+百度+蚂蚁+京东面经
  13. Android装备选择实验
  14. python爬取拉钩网招聘信息
  15. LightOJ1197 Help Hanzo(欧拉筛+区间素数)
  16. 超详细如何配置将WAN接入
  17. ckc交易什么意思_股前加r是什么意思?股市kdj线图如何看?
  18. 英文排版(typography)
  19. 今日金融词汇---存货,是什么?
  20. 算法竞赛从入门到进阶pdf_ACMICPC/CCPC算法竞赛入门建议

热门文章

  1. 视频教程-清华-尹成老师-java基础-Day1-Java
  2. 多迪php,多迪PHP项目经理深度解析:PHP应用性能优化指南!
  3. python拥有庞大的计算生态_Python稳基修炼之计算机等级考试易错概念题1(含答案与解析)...
  4. python dataframe的某一列变为list_NumPy中的ndarray与Pandas的Series和DataFrame之间的区别与转换...
  5. 数控车床机械结构_02
  6. 现代谱估计的参数模型
  7. 渗透攻防必备工具(基础篇,收藏起来)
  8. [置顶] 大学生如何让自己强大起来(计算机、电子方向)
  9. 让镜头数量之争终结!Holga iPhone外壳暴力集成10个镜头
  10. winds以管理员身份运行命令提示符