和你一起终身学习,这里是程序员 Android

本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以下内容:

一、CPU 区域图例
二、CPU 核心架构
三、绑核
四、锁频
五、CPU 状态
六、Systrace 中的详细信息

一、CPU 区域图例

下面是高通骁龙 845 Systrace 对应的 CPU Info 区域(底下的一些这里不讲,主要是讲 Kernel CPU 信息)

Systrace 中 CPU Info 一般在最上面,里面经常会用到的信息包括:

  1. CPU 频率变化情况
  2. CPU 任务执行情况
  3. 大小核的调度情况
  4. CPU Boost 调度情况

总的来说,Systrace 中的 CPU Info 这里一般是看任务调度信息,查看是否是频率或者调度导致当前任务出现性能问题,举例如下:

  1. 某个场景的任务执行比较慢,我们就可以查看是不是这个任务被调度到了小核?
  2. 某个场景的任务执行比较慢,当前执行这个任务的 CPU 频率是不是不够?
  3. 我的任务比较特殊,比如指纹解锁,能不能把我这个任务放到大核去跑?
  4. 我这个场景对 CPU 要求很高,我能不能要求在我这个场景运行的时候,限制 CPU 最低频率?

与 CPU 运行信息相关的内容在 Systrace 基础知识 – 分析 Systrace 预备知识 这篇文章里面有详细的讲解,不熟悉的同学可以配合这篇文章一起食用

二、CPU 核心架构

简单来说目前的手机 CPU 按照核心数和架构来说,可以分为下面三类:

  1. 非大小核架构
  2. 大小核架构
  3. 大中小核架构

目前的大部分 CPU 都是大小核架构,当然也有一些 CPU 是大中小核架构,比如高通骁龙 855,也有少部分 CPU 是非大小核架构

下面就来说说各种架构的区别,方便大家后续查看 Systrace

1.非大小核架构

很早的机器 CPU 只有双核心或者四核心的时候,一般只有一种核心架构,也就是说着四个核心或者两个核心是同构的,相同的频率,相同的功耗,一起开启或者关闭;有些高通的中低端处理器也会使用同构的八核心处理器,比如高通骁龙 636

现在的大部分机器已经不使用非大小核的架构了

##2.大小核架构

现在的 CPU 一般采用 8 核心,八个核心中,CPU 0-3 一般是小核心,CPU 4-7,如下图中 Systrace 中就是按照这个排列的

小核心一般来说主频低,功耗也低,使用的一般是 arm A5X 系列,比如高通骁龙 845,小核心是由四个 A55 (最高主频 1.8GHz ) 组成

大核心一般来说最高主频比较高,功耗相对来说也会比较高,使用的一般是 arm A7X 系列,比如高通骁龙 845,大核心就是由四个 A75(最高主频 2.8GHz)组成

下图就是 845 的 CPU

当然大小核架构中还有一些变种,比如高通骁龙 636 (4 小核 + 2 大核)或者高通骁龙 710 (6 小核 + 2 大核),宗旨还是不变,大核心用来支持高负载场景,小核心用来日常使用,至于够不够用,就看你舍不舍得花银子,毕竟一分价钱一分货,高通爸爸也不是做福利的

下面这些高通的主流大小核处理器的参数如下

3.大中小核架构

部分 CPU 比较另辟蹊径,选择了大中小核的架构,比如高通骁龙 855 8 核 (1 个 A76 的大核+3 个 A76 的中核 + 4 个 A55 的小核)和之前的的 MTK X30 10 核 (2 个 A73 的大核 + 4 个 A53 的中核 + 4 个 A35 的小核)以及麒麟 980 8 核 (2 个 A76 的大核 + 2 个 A76 的中核 + 4 个 A55 的小核)

相比大小核架构,大中小核架构中的大核可以理解为超大核(高通称之为 Gold +) ,这个超大核的个数一般比较少(1-2 个),主频一般会比较高,功耗相对也会高很多,这个是用来处理一些比较繁重的任务

下图是 855、845 和麒麟 980 的对比

顺带提一嘴,今年的高通骁龙 865 依然是大中小核的架构,大核和中核用的是 A77 架构,小核用的是 A55,大核和中核最高频率不一样,大核只有一个,主频到 2.8GHz,不知道 865 Plus 会不会搞到 3GHz

三、绑核

绑核,顾名思义就是把某个任务绑定到某个或者某些核心上,来满足这个任务的性能需求

  1. 任务本身负载比较高,需要在大核心上面才能满足时间要求
  2. 任务本身不想被频繁切换,需要绑定在某一个核心上面
  3. 任务本身不重要,对时间要求不高,可以绑定或者限制在小核心上面运行

上面是一些绑核的例子,目前 Android 中绑核操作一般是由系统来实现的,常用的有三种方法

##1.配置 CPUset

使用 CPUset 子系统可以限制某一类的任务跑在特定的 CPU 或者 CPU 组里面,比如下面,Android 中会划分一些默认的 CPU 组,厂商可以针对不同的 CPU 架构进行定制,目前默认划分

  1. system-background 一些低优先级的任务会被划分到这里,只能跑到小核心里面
  2. foreground 前台进程
  3. top-app 目前正在前台和用户交互的进程
  4. background 后台进程
  5. foreground/boost 前台 boost 进程,通常是用来联动的,现在已经没有用到了,之前的时候是应用启动的时候,会把所有 foreground 里面的进程都迁移到这个进程组里面

每个 CPU 架构对应的 CPUset 的配置都不一样,每个厂商也会有不同的策略在里面,比如下面就是一个 Google 官方默认的配置,各位也可以查看对应的节点来查看自己的 CPUset 组的配置

//官方默认配置
write /dev/CPUset/top-app/CPUs 0-7
write /dev/CPUset/foreground/CPUs 0-7
write /dev/CPUset/foreground/boost/CPUs 4-7
write /dev/CPUset/background/CPUs 0-7
write /dev/CPUset/system-background/CPUs 0-3
// 自己查看
adb shell cat /dev/CPUset/top-app/CPUs
0-7

对应的,可以在每个 CPUset 组的 tasks 节点下面看有哪些进程和线程是跑在这个组里面的

$ adb shell cat /dev/CPUset/top-app/tasks
1687
1689
1690
3559
</pre>

需要注意每个任务跑在哪个组里面,是动态的,并不是一成不变的,有权限的进程就可以改

部分进程也可以在启动的时候就配置好跑到哪个进程里面,下面是 lmkd 的启动配置,writepid /dev/CPUset/system-background/tasks 这一句把自己安排到了 system-background 这个组里面

service lmkd /system/bin/lmkdclass coreuser lmkdgroup lmkd system readproccapabilities DAC_OVERRIDE KILL IPC_LOCK SYS_NICE SYS_RESOURCE BLOCK_SUSPENDcriticalsocket lmkd seqpacket 0660 system systemwritepid /dev/CPUset/system-background/tasks

大部分 App 进程是根据状态动态去变化的,在 Process 这个类中有详细的定义

android/os/Process.java

/*** Default thread group -* has meaning with setProcessGroup() only, cannot be used with setThreadGroup().* When used with setProcessGroup(), the group of each thread in the process* is conditionally changed based on that thread's current priority, as follows:* threads with priority numerically less than THREAD_PRIORITY_BACKGROUND* are moved to foreground thread group.  All other threads are left unchanged.* @hide*/
public static final int THREAD_GROUP_DEFAULT = -1;/*** Background thread group - All threads in* this group are scheduled with a reduced share of the CPU.* Value is same as constant SP_BACKGROUND of enum SchedPolicy.* FIXME rename to THREAD_GROUP_BACKGROUND.* @hide*/
public static final int THREAD_GROUP_BG_NONINTERACTIVE = 0;/*** Foreground thread group - All threads in* this group are scheduled with a normal share of the CPU.* Value is same as constant SP_FOREGROUND of enum SchedPolicy.* Not used at this level.* @hide**/
private static final int THREAD_GROUP_FOREGROUND = 1;/*** System thread group.* @hide**/
public static final int THREAD_GROUP_SYSTEM = 2;/*** Application audio thread group.* @hide**/
public static final int THREAD_GROUP_AUDIO_APP = 3;/*** System audio thread group.* @hide**/
public static final int THREAD_GROUP_AUDIO_SYS = 4;/*** Thread group for top foreground app.* @hide**/
public static final int THREAD_GROUP_TOP_APP = 5;/*** Thread group for RT app.* @hide**/
public static final int THREAD_GROUP_RT_APP = 6;/*** Thread group for bound foreground services that should* have additional CPU restrictions during screen off* @hide**/public static final int THREAD_GROUP_RESTRICTED = 7;

在 OomAdjuster 中会动态根据进程的状态修改其对应的 CPUset 组, 详细可以自行查看 OomAdjuster 中 computeOomAdjLocked、updateOomAdjLocked、applyOomAdjLocked 的执行逻辑(Android 10)

2.配置 affinity

使用 affinity 也可以设置任务跑在哪个核心上,其系统调用的 taskset, taskset 用来查看和设定“CPU 亲和力”,其实就是查看或者配置进程和 CPU 的绑定关系,让某进程在指定的 CPU 核上运行,即是“绑核”。

##3.taskset 的用法
显示进程运行的CPU

taskset -p pid

注意,此命令返回的是十六进制的,转换成二进制后,每一位对应一个逻辑 CPU,低位是 0 号CPU,依次类推。如果每个位置上是1,表示该进程绑定了该 CPU。例如,0101 就表示进程绑定在了 0 号和 3 号逻辑 CPU 上了

绑核设定

taskset -pc 3  pid    表示将进程pid绑定到第3个核上
taskset -c 3 command   表示执行 command 命令,并将 command 启动的进程绑定到第3个核上。

Android 中也可以使用这个系统调用,把任务绑定到某个核心上运行。部分较老的内核里面不支持 CPUset,就会用 taskset 来设置

4.调度算法

在 Linux 的调度算法中修改调度逻辑,也可以让指定的 task 跑在指定的核上面,部分厂家的核调度优化就是使用的这种方法,这里就不具体来讲了

#四、锁频

正常情况下,CPU 的调度算法都可以满足日常的使用,但是在 Android 中的部分场景里面,单纯依靠调度器,可能会无法满足这个场景对性能的要求。比如说应用启动场景,如果让调度器去拉频率迁核,可能就会有一定的延迟,比如任务先在小核跑,发现小核频率不够,那就把小核频率往上拉,拉上去之后发现可能还是不够,经过几次一直拉到最高发现还是不够,然后把这个任务迁移到中核,频率也是一次一次拉,拉到最高发现还是不够,最好迁移到大核去做。这样一套下来,时间过去不少不说,启动速度也不是最快的

基于这种情况的考虑,系统中一般都会在这种特殊场景直接暴力拉核,将硬件资源直接拉到最高去运行,比如 CPU、GPU、IO、BUS 等;另外也会在某些场景把某些资源限制使用,比如发热太严重的时候,需要限制 CPU 的最高频率,来达到降温的目的;有时候基于功耗的考虑,也会限制一些资源在某些场景的使用

目前 Android 系统一般会在下面几个场景直接进行锁频(不同厂家也会自己定制)

  1. 应用启动
  2. 应用安装
  3. 转屏
  4. 窗口动画
  5. List Fling
  6. Game

以 高通平台为例,在 CPU Info 中我们也可以看到锁频的情况

五、CPU 状态

CPU info 中还有标识 CPU 状态的标记,如下图所示,CPU 状态有 0 ,1,2,3 这四种

之前的 CPU 支持热插拔,即不用的时候可以直接关闭,不过目前的 CPU 都不支持热插拔,而是使用 C-State

下面是摘抄的其他平台的支持 C0-C4 的处理器的状态和功耗状态,Android 中不同的平台表现不一致,大家可以做一下参考

  1. C0 状态(激活)

    1. 这是 CPU 最大工作状态,在此状态下可以接收指令和处理数据
    2. 所有现代处理器必须支持这一功耗状态
  2. C1 状态(挂起)
    1. 可以通过执行汇编指令“ HLT (挂起)”进入这一状态
    2. 唤醒时间超快!(快到只需 10 纳秒!)
    3. 可以节省 70% 的 CPU 功耗
    4. 所有现代处理器都必须支持这一功耗状态
  3. C2 状态(停止允许)
    1. 处理器时钟频率和 I/O 缓冲被停止
    2. 换言之,处理器执行引擎和 I/0 缓冲已经没有时钟频率
    3. 在 C2 状态下也可以节约 70% 的 CPU 和平台能耗
    4. 从 C2 切换到 C0 状态需要 100 纳秒以上
  4. C3 状态(深度睡眠)
    1. 总线频率和 PLL 均被锁定
    2. 在多核心系统下,缓存无效
    3. 在单核心系统下,内存被关闭,但缓存仍有效可以节省 70% 的 CPU 功耗,但平台功耗比 C2 状态下大一些
    4. 唤醒时间需要 50 微妙

#六、Systrace 中的详细信息

Systrace 我们一般用 Chrome 打开,转换成图形化信息之后更加方便从整体去看,但其实 Systrace 也可以以文本的方式打开,也可以看到一些详细的信息。

比如下面就是一条标识 CPU 调度的 Message,解析的时候,里面的信息会被解析到各个模块

appEventThread-8193  [001] d..2 1638545.400415: sched_switch: prev_comm=appEventThread prev_pid=8193 prev_prio=97 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
</pre>

详细来看

appEventThread-8193    -- 标识 TASK-PID
[001]                  -- 标识是哪个 CPU ,这里是 cpu0
d..2                   -- 这是四个位,每个位分别对应 irqs-off、need-resched、hardirq/softirq、preempt-depth
1638545.400415         -- 标识 delay TIMESTAMP
sched_switch ...到最后  -- 标识信息区,里面包含前一个任务描述,前一个任务的 pid,前一个任务的优先级 ,当前任务,当前任务 pid,当前任务优先级

另外里面仔细看也可以看到许多有趣的输出,可以加深对调度的理解

  1. sched_waking: comm=kworker/u16:4 pid=17373 prio=120 target_cpu=003
  2. sched_blocked_reason: pid=17373 iowait=0 caller=rpmh_write_batch+0x638/0x7d0
  3. cpu_idle: state=0 cpu_id=3
  4. softirq_raise: vec=6 [action=TASKLET]
  5. cpu_frequency_limits: min=1555200 max=1785600 cpu_id=0
  6. cpu_frequency_limits: min=710400 max=2419200 cpu_id=4
  7. cpu_frequency_limits: min=825600 max=2841600 cpu_id=7

原文链接:https://www.androidperformance.com/2019/12/21/Android-Systrace-CPU

至此,本篇已结束。转载网络的文章,小编觉得很优秀,欢迎点击阅读原文,支持原创作者,如有侵权,恳请联系小编删除,欢迎您的建议与指正。同时期待您的关注,感谢您的阅读,谢谢!

Systrace 之 CPU info解读相关推荐

  1. 服务器cpu型号后面的字母,Intel 至强 E3服务器CPU后缀解读

    三.Intel 至强 E3服务器CPU后缀解读 DIY玩家认识服务器CPU最多的无疑是E3神教,今天我们就总结下Xeon E3神教的CPU后缀有什么特色. ●V1-V5 E3神教! 从SNB开始,In ...

  2. Systrace 线程 CPU 运行状态分析技巧 - Sleep 和 Uninterruptible Sleep 篇

    本文是 Systrace 线程 CPU 运行状态分析技巧系列的第三篇,本文主要讲了使用 Systrace 分析 CPU 状态时遇到的 Sleep 与 Uninterruptible Sleep 状态的 ...

  3. Intel CPU型号解读以及如何粗略判断Intel CPU的性能(i3、i5、i7以及CPU的代数)

    1. 简要解读Intel CPU的型号 1.1 Intel对于CPU的命名规则 Intel生产的CPU分为高中低端,最低端的G系列,然后是低端i3系列,中端i5系列,高端i7系列和至尊i9系列. 注意 ...

  4. TOP命令 %Cpu(s)解读 CPU状态信息us,sy,ni,id,wa,hi,si,st含义

    使用系统命令top即可看到如下类似信息: Cpu(s): 0.0%us, 0.5%sy, 0.0%ni, 99.5%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st 但不知什么含义 ...

  5. Android Systrace 基础知识(10) - Binder 和锁竞争解读

    本文是 Systrace 系列文章的第十篇,主要是对 Systrace 中的 Binder 和锁信息进行简单介绍,简单介绍了 Binder 的情况,介绍了 Systrace 中 Binder 通信的表 ...

  6. Android Systrace 基础知识(9)-MainThread 和 RenderThread 解读

    本文是 Systrace 系列文章的第九篇,主要是是介绍 Android App 中的 MainThread 和 RenderThread,也就是大家熟悉的「主线程」和「渲染线程」.文章会从 Syst ...

  7. Systrace 流畅性实战 2 :案例分析: MIUI 桌面滑动卡顿分析

    当我们说 流畅度 的时候,我们说的是什么?不同的人对流畅性(卡顿掉帧)有不同的理解,对卡顿阈值也有不同的感知,所以有必要在开始这个系列文章之前,先把涉及到的内容说清楚,防止出现不同的理解,也方便大家带 ...

  8. 阿里云ARM服务器通用型g6r实例CPU性能参数详解

    查看全文 http://www.taodudu.cc/news/show-2713373.html 相关文章: oracle profile 参数,oracle profile的参数详解 CPU各项参 ...

  9. 电脑主要硬件解读与选购建议

    电脑主要硬件解读与选购建议 本文目录(点击快速跳转): 一.内存 二.硬盘 三.CPU 四.显卡 五.显示器 一.内存 1.1 内存介绍 内存又叫内部存储器或者是随机存储器(RAM),分为DDR内存和 ...

最新文章

  1. Invocation of destroy method 'close' failed on bean with name 'sqlSession'
  2. 职校电子计算机专业高考分数线,2015年重庆高考分数线公布:一本文572理573
  3. 【面向对象】类的特殊成员方法
  4. Linux /etc/skel目录
  5. 计算机十进制例子,verilog给你举个最简单的例子:以十进制计算为例:14
  6. Unity3D 的物理渲染和光照模型
  7. HTML 5 中的新元素
  8. 理解SapLocation()
  9. 作业六 栈的使用和界面编程探索
  10. 我自定义安装office 但在ATA计算机考试系统考试时出现“没有正确的安装office” 怎么解决 求解
  11. OC语言基础十:OC文件操作
  12. 动态规划法---python实现
  13. 初级办公计算机,初级(计算机办公软件应用)教案
  14. PR-CTS-Specify Clock Tree Synthesis Options
  15. python计算圆锥体积和表面积_圆柱与圆锥体积与表面积计算
  16. JAVA 配合 Vue前台,完成中文、拼音全拼、拼音首字母检索
  17. python爬取百度贴吧图片库_python抓取百度贴吧-校花吧,网页图片
  18. validation插件
  19. Linux如何ping本机IP,Linux ping6 本地ipv6地址无效的参数
  20. 《C语言入门100例》第二例 数列求和

热门文章

  1. php虚拟主机搭建微信公众号服务器
  2. 【花雕动手做】有趣好玩的音乐可视化系列小项目(18)--LED平面板灯
  3. 【java】序列化与反序列
  4. android hook 第三方app_基于 VirtualApp 结合 whale hook框架实现hook第三方应用
  5. 后台弹出提示信息方法
  6. 数据结构与算法——左程云06
  7. 咸鱼硬件—Micropython快速指南
  8. 如何选择直流微电机1
  9. C++:实现量化Forward option远期合约期权测试实例
  10. SQL SERVER增加文件组和文件