内核和系统:CPU知识点
本网站相关文章:
- 内核和系统(1)-cpu 术语和知识点
- 内核和系统(2)-cpu 架构体系
- 内核和系统(3)-IO 相关术语
- 内核和系统(4)-IO 模型
- 内核和系统(5)-磁盘分区
- 内核和系统(6)-缓存
- 内核和系统(7)-内存相关术语
- 内核和系统(8)-pstree 命令
物理, 逻辑, lcores
物理 CPU
物理封装: 每一个 CPU 都有单一的 physical id 值, 其数量表示实际主机上 socket(插槽)中的 CPU 个数, 一个物理封装使用独立的 CPU 物理插槽, 多个物理封装共享电源和风扇.
查询 linux 中物理 CPU 命令: cat /proc/cpuinfo | grep "physical id" |sort |uniq
cores
物理核心, CPU 核数
- 一个物理封装中包含了几个独立的 CPU 核心(或者芯片组数量)
- 一个 CPU 核心都包含有自己独立的完整硬件单元
逻辑 CPU
- 逻辑 CPU = physical cpu _ cpu cores _ 2(HT 超线程)
- 一个 CPU 核心对外表现为多个独立的外部 CPU 接口(逻辑 CPU)
如果有多个物理封装, 逻辑 CPU 的数量成正比, 每一个 CPU 核心(cores)共享执行单元和缓存, 上述几个术语在 linux 中的查询命令:
1 | # 1. CPU cores: 开启了超线程, 则理论上cpu核心数需要乘2. |
超线程技术
功能
在了解hyper threading
之前, 先让我们了解一下multiple threading
技术, 线程是进程最小的调度单位, 一个进程至少包含一个线程, 利用多线程进行并行开发, 已达到利用多核的目的. 那么超线程技术和多线程技术有什么关联呢? 两者都是虚拟化技术吗?
Hyper-Threading
利用特殊的硬件指令, 将两个逻辑内核模拟成两个物理芯片, 让单个处理器能使用线程级别并行计算, 进而兼容多线程操作系统和软件, 减少了 CPU 闲置时间, 提高 CPU 的运行速率, 这实际上也是一种虚拟化思想-增加资源利用率
.Hyper-Threading
就是同时多线程
运行技术, 允许一个 CPU 执行多个控制流的技术, 将一个物理 CPU 模拟成两个逻辑 CPU, 从而达到对 CPU 虚拟化的目的.
目的
在 CPU 和内存速度差异较大的情况下产生的技术, 系统瓶颈不在 CPU 执行单元, 而在外部存储器, 通过 CPU HT 技术, 提高 CPU 的使用效率:
- 让计算机做的更多
- 让计算机跑的更快
不让 CPU 闲置着, 以达到资源的最大化利用.
CPU 亲和力
CPU 亲和力指定某一个进程在指定的 CPU 上长时间运行而不被迁移到其他 CPU, 其中 CPU 之间的均衡处理由 SMP 来完成. affinity 作用对象: SMP 架构以及其他
- 基于进程数来调整 CPU 使用
- 每一个 CPU 都有一个可执行进程队列
- 当且某一个 CPU 的可执行队列中的进程数比其他最小进程数 CPU 高 25%时, 才会进行分流操作
原理:
- 提高 CPU 中的 cache 缓存命中率
- 将不同等级的业务隔离开来, 例如实时进程和其他业务进程, 见 DPDK
手动调整 affinity: 因为考虑到进程数来调度 CPU 的缺陷(一大群懒鬼占用着大量的机器, 一两个雷锋公用一台设备), 从而造成资源的极大浪费, 可以使用手动方式来调整 CPU affinity 的设置.
DPDK 中的应用: DPDK 利用 CPU affinity, 将 MP 和 DP 分别绑定到不同的 CPU 上, 避免无意义的进程切换工作.
单 CPU
术语
- User Time: CPU 执行用户进程的时间, 包括 nices, 通常该值占比越大越好
- System Time: CPU 在内核运行时间, 包括 IRQ 和 softirq, 通常该值占比越低越好
- Waiting Time: CPU 等待 I/O 操作完成的时间, 该值过高表明系统存在 IO 瓶颈
- Idle Time: CPU 空闲时间
- Nice Time: CPU 调整进程优先级的时间, 见下面说明
- Hard IRQ Time: CPU 硬中断时间
- Soft IRQ Time: CPU 软中断时间, 关于中断见下面说明
- Steal Time: CPU 丢失或者强制虚拟 CPU 的时间, 此时 hypervisor 为另外一个虚拟 CPU 服务.
PRI/NI/Nice
- PRI: 进程优先权, 值越高, 越早被执行
- NI: 进程 nice 值, 用于控制和影响进程优先级
- %nice: CPU 调整进程优先级的时间占比
PIR 表示进程的优先级, 其中 PRI 和 nice 的关系: PRI(new)=PRI(old)+nice
, 其中 nice 的占比从-20~+19
, 如果 nice 为+19
, 其优先级是最低, 这是一个高尚, 无私的
进程, 这就是 nice 的起源. 进程的 nice 可以通过命令nice
, renice
来进行调整, 前者在运行进程时设置, 后者对已启动的进程进行设置.
中断
硬中断–由硬件产生, 例如磁盘, 网卡, 键盘, 时钟, 所有的硬件都会将相应的 IRQ(中断请求)发送到对应硬件驱动上. 其中时钟中断会将当前运行的进程挂起, 从而运行其他代码, 常常用于 scheduler 调度器中. 整个硬中断过程: 硬件->CPU->内核驱动
.
软中断–正在运行的程序发生的中断, 例如 IO 请求, Yield 请求, 软中断不会停止 CPU 运行, 但是会对当前进程或者代码产生一种逻辑中断. 整个软中断过程: 进程->内核驱动
.
计算
top 命令简要信息输出:
1 | top - 09:14:56 up 264 days, 20:56, 1 user, load average: 0.02, 0.04, 0.00 |
其中关于 CPU 命令字段的计算公式如下:
- %us: (User Time + Nice Time) / CPU Time * 100%
- %sy(内核): (System Time + Hard IRQ Time + Soft IRQ Time) / CPU Time * 100%
- %id(空闲): (Idle Time) / CPU Time * 100%
- %ni: (Nice Time) / CPU Time * 100%
- %wa(IO): (Waiting Time) / CPU Time * 100%
- %hi(硬中断): (Hard IRQ Time) / CPU Time * 100%
- %si(软中断): (Soft IRQ Time) / CPU Time * 100%
- %st: (Steal Time) / CPU Time * 100%
对于 CPU 占用率的计算公式, 不同于上面的计算公式, 一般会取一个时间跨度, 并读取/proc/stat
中的数据, 最后取一个平均值, 其中 CPU 的更新频率:1/HZ秒
更新一次. 时钟中断时会获取当前正在运行的进程信息, 所以, 如果在一个时钟周期内, 发生进程调度, 则 CPU 使用率可能不准确.
cpu 信息
taskset
用于设置或检索一个进程的 CPU 亲和性(affinity)的工具。其中 CPU 亲和率表示: 在 CMP 架构下, 能够将一个或多个进程绑定到一个或多个处理器上运行. taskset 的
基本语法如下:
1 | # mask: 16进制,指定了进程可以运行的CPU核心。每个核心用一个位表示,1表示允许在该核心上运行,0表示不允许 |
例如:
1 | # a. 启动新进程并在指定的cpu上运行 |
cpuinfo
/proc/cpuinfo
存储 logical cpu 信息,注意这是一个虚拟文件,它在运行时由内核动态生成的,通过该文件可以查询到各种 CPU 信息。通过该文件可以获取硬件信息,例如制造商(vendor)、型号(model name)、核心数(cores)、处理器速度(CPU MHz)、缓存大小(cache size)等,下面是一些常用的 cpuinfo 信息查看命令:
1 | # 1. 查看物理CPU的个数, 虚拟机vmware中的processors值 |
lscpu
lscpu
命令在 Linux 系统中用于显示有关 CPU 架构的详细信息,该命令从sysfs
和/proc/cpuinfo
中读取并报告 CPU 相关的信息,包括 CPU 的数量、每个 CPU 的核心数、CPU 家族、型号、缓存大小等详细信息,相比 cpuinfo 使用更加方便。下面是 lscpu 命令的输出
1 | [root@VM-16-12-opencloudos ~]# lscpu |
cpu 监控
CPU 的监控应用往往和 Memory 的监控关联, 具体的工具介绍, 见memory的说明. 在了解本篇文章之前, 需要先了解 CPU 中的一些术语, 以更好的关联整个 CPU 监控, 以及健康检查的标准。
另外,为了测试 CPU 的监控是否成功, 有时候需要手动将某一个 CPU 的使用率跑满(adjust cpu usage), 此时可以使用如下命令: dd if=/dev/zero of=/dev/null
, 该情况对于单核机器可能会非常明显的效果, 多核机器会带来整体的 CPU 使用率一定的提升。
top
对 top 命令中关于 CPU 部分的字段说明, 其他信息见top中的说明, 其输出:
1 | top - 09:14:56 up 264 days, 20:56, 1 user, load average: 0.02, 0.04, 0.00 |
其中 CPU 占比信息说明:
1 | Cpu(s): 表示这一行显示CPU总体信息 |
这里显示数据是所有 cpu 的平均值, 如果想看每一个 cpu 的处理情况, 按 1 即可折叠, 再次按 1, 此时每一个进程输出的字段说明:
1 | PID: 进程的ID |
任务栏信息输出:
1 | 87 total: 很好理解, 就是当前有87个任务, 也就是87个进程. |
python
- 获取 cpu precent
1 | class BasicMonitor(object): |
注意, psutil.cpu_times_percent
中的 interval 为 0 或者 None 时, 其会对比上一次调用的 CPU 使用率或者导入 psutil 模块时的 CPU 使用率并立刻返回, 所以可能发生直接运行pstuil.cpu_time_percent
为 0 的情况.