CPU基础扫盲:开发人员不得不了解的CPU那些事

@[TOC]

一、CPU简介

1、单核CPU的组成

CPU是计算机硬件系统的核心部件,也就是整个计算机的大脑。 包含运算器+控制器(两个部件里面有寄存器组),通过CPU内部的总线进行通信。

控制器(Control Unit,简称CU):计算机的指挥系统,用来控制计算机其它组件的运行。

运算器(算数逻辑运算器,Arithmetic/Logic Unit简称ALU):运算功能,用来完成各种二进制编码做算数运算和逻辑运算,包括加减乘、与或非运算。

控制器和运算器联系十分紧密,两大部件多数集成在同一芯片,统称为中央处理器(Central Processing Unit,简称CPU)

寄存器组(Register) :用暂存指令或数据、存储即将执行的指令等多个不同类型的寄存器。

2、多核CPU的组成

单核CPU容易存在瓶颈,现在市面上的CPU通常都是一块CPU上增加多个核心,可以提高CPU并行执行的能力。

多核CPU每个核心是可以运行指令的独立单元,包含了ALU/CU和寄存器。 每个核心配备了L1Cache和L2Cache,多个核心共享L3Cache。利用了多级缓存,提高性能。 比如说现在服务器可以支持多个处理器(CPU),2个CPU、4个CPU等。 加入4个CPU,每块CPU内有8个核心,系统可对外提供32核计算能力。 总核数 = 物理CPU个数 X 每颗物理CPU的核数。 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数。

3、存储器的层级架构

存储器的层级架构,根据分类和性能可以分成这么几个级别:

1、L0寄存器:离CPU最近,材料贵费用高,存储大小几字节,速度最快。

2、L1-Cache:离CPU有一定距离,存储空间几十到几百KB。

3、L2-Cache:离CPU的距离比L1更远,存储空间几MB到几十MB。

4、L3-Cache:离CPU的距离比L2更远,存储空间几MB到几十MB。

5、内存:位于主板上,由半导体硅制作,通过总线和CPU连接,几G到几百G不等,成本比上面更低,但是速度慢。

6、硬盘/SSD:硬盘分机械硬盘和固态硬盘SSD,几百G到几十T不等,成本最低,但是速度最慢。

4、CPU的X86和arm架构的区别

在我们购买云服务器时,通常会选择X86还是ARM: 搞明白这个之前,我们需要先搞明白CPU架构的指令集的分类。

(1)指令和指令集

什么是指令: 中央处理器CPU,执行用户和操作系统下发的指令; 指令以0 1 二进制形式组织的机器码,在硬件物理底层 -01用来控制高低电位; 一个加法运算,在x86处理器上的二进制代码【01001000 00000001 11000011】,被称为机器码。

什么是指令集: 指令集规定了一种CPU架构实现哪些【指令的集合】。

(2)主要的CPU架构指令集分类

精简指令集(Reduced Instruction Set Computing,RISC): 每个指令的运行时间短,完成的动作简单,但做复杂动作则需要多个指令来完成,一般小于200条指令。 ARM架构的CPU,市面上手机/小型设备等大多采用的是这个架构,耗电少/电压低,通常面向移动领域。

复杂指令集(Complex Instrucetion Set Computer,CISC): 指令数目多且支持的动作复杂,指令的长度不相同,执行耗时也比较长,一般大于200条指令。 x86架构的CPU:通常在家用、商用领域,功耗大,在性能和兼容性方面做的更好。

ARM架构和x86架构是市场份额最大的两大架构,各自有对应的特点和市场。

(3)CPU 32位和64位是指什么

表示一次可以处理多少位二进制,8位的CPU一次只能处理一个字节。 32位的CPU一次能处理4个字节,64位的CPU一次可以处理8个字节,所以64位的CPU在处理速度上较32位的CPU理论上快了一倍。

(4)安装软件的时候支持操作系统由x86、x64是什么意思

x86: x86是指Intel的开发的一种32位指令集,是一种CISC复杂指令集,所有Intel/AMD早期的CPU都支持这种指令集。 x86一般用的是32位的系统,但是32位操作系统可以安装在32位CPU或64位CPU的电脑上,但是无法发挥64位CPU电脑的最大性能。

x64: AMD公司比Intel公司先做x86架构的兼容64位的CPU叫做x64,后来Intel公司也迈向64位时取名较x86_64,。 所以,我们认为x86_64 也叫x64 也叫AMD64,都是一个东西。 Intel和AMD和x86架构CPU指令集上有很大差别,但互相兼容,所以软件可以直接用。 x64支持64位的系统,64位操作系统只能安装在64位处理器的电脑上(CPU必须是64位的)。

所以安装软件的时候,必须要选择与CPU架构匹配的软件,否则会安装不成功:

(5)服务器的CPU到底怎么选

ARM: 近年来ARM64架构突起,现金制作工艺,大幅降低单核功耗以及更高的CPU核心数; ARM64架构的芯片功耗低性能高价格低,性价比高; 还有很多苹果电脑也逐渐用了ARM64架构的CPU。

x86: x86偏向高性能的台机(服务器),适用于绝大多数用户的上云场景;是一般用户选择阿里云服务器的主要架构,基本上都是x86架构。

ARM和x86服务器各有优缺点,看场景选择。 个人测试使用可以考虑ARM,价格低性价比高。 生产环境建议选x86,性能好。

5、CPU的超线程

超线程的英文是HT(Hyper-Threading),是一种欺骗操作系统的行为,把一颗CPU当成两颗来用,将一颗具有超线程功能的物理CPU变成两颗逻辑CPU。每颗CPU可以有多个线程,常规数量是两个,比如1核双线程,2核4线程,4核8线程。

多个物理CPU,各个CPU通过总线进行通讯,效率较低; 利用超线程技术模拟出的两个逻辑内核共享同一个CPU资源,效率更高; 同一时刻可以有两个线程都占用CPU资源,两个线程都可以得到执行,实现同一时间执行两个线程的并行操作; 允许两个线程同时不冲突地使用CPU中的资源,通过超线程的技术来提高性能; CPU的多线程是硬件多线程,程序的多线程是软件的多线程,硬件的多线程是可以被当做一个CPU核心来调度执行任务的CPU资源,这两个概念需要区分开。

6、查看CPU信息

(1)查看CPU详细信息

bash 复制代码
# 查看CPU详细信息
[root@localhost ~]# cat /proc/cpuinfo 
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 151
model name	: 12th Gen Intel(R) Core(TM) i7-12700
stepping	: 2
cpu MHz		: 2111.996
cache size	: 25600 KB
physical id	: 0
siblings	: 4
core id		: 0
cpu cores	: 4
apicid		: 0
initial apicid	: 0
fpu		: yes
fpu_exception	: yes
cpuid level	: 22
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc eagerfpu pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase bmi1 avx2 bmi2 invpcid rdseed clflushopt md_clear flush_l1d arch_capabilities
bogomips	: 4223.99
clflush size	: 64
cache_alignment	: 64
address sizes	: 46 bits physical, 48 bits virtual
power management:

processor	: 1
vendor_id	: GenuineIntel
cpu family	: 6
model		: 151
model name	: 12th Gen Intel(R) Core(TM) i7-12700
stepping	: 2
cpu MHz		: 2111.996
cache size	: 25600 KB
physical id	: 0
siblings	: 4
core id		: 1
cpu cores	: 4
apicid		: 1
initial apicid	: 1
fpu		: yes
fpu_exception	: yes
cpuid level	: 22
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc eagerfpu pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase bmi1 avx2 bmi2 invpcid rdseed clflushopt md_clear flush_l1d arch_capabilities
bogomips	: 4223.99
clflush size	: 64
cache_alignment	: 64
address sizes	: 46 bits physical, 48 bits virtual
power management:

processor	: 2
vendor_id	: GenuineIntel
cpu family	: 6
model		: 151
model name	: 12th Gen Intel(R) Core(TM) i7-12700
stepping	: 2
cpu MHz		: 2111.996
cache size	: 25600 KB
physical id	: 0
siblings	: 4
core id		: 2
cpu cores	: 4
apicid		: 2
initial apicid	: 2
fpu		: yes
fpu_exception	: yes
cpuid level	: 22
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc eagerfpu pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase bmi1 avx2 bmi2 invpcid rdseed clflushopt md_clear flush_l1d arch_capabilities
bogomips	: 4223.99
clflush size	: 64
cache_alignment	: 64
address sizes	: 46 bits physical, 48 bits virtual
power management:

processor	: 3
vendor_id	: GenuineIntel
cpu family	: 6
model		: 151
model name	: 12th Gen Intel(R) Core(TM) i7-12700
stepping	: 2
cpu MHz		: 2111.996
cache size	: 25600 KB
physical id	: 0
siblings	: 4
core id		: 3
cpu cores	: 4
apicid		: 3
initial apicid	: 3
fpu		: yes
fpu_exception	: yes
cpuid level	: 22
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc eagerfpu pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase bmi1 avx2 bmi2 invpcid rdseed clflushopt md_clear flush_l1d arch_capabilities
bogomips	: 4223.99
clflush size	: 64
cache_alignment	: 64
address sizes	: 46 bits physical, 48 bits virtual
power management:

(2)查看CPU重要信息

bash 复制代码
# 查看CPU架构
[root@localhost ~]# uname -a
Linux localhost.localdomain 3.10.0-1127.el7.x86_64 #1 SMP Tue Mar 31 23:36:51 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

# 查看CPU厂家信息
[root@localhost ~]# cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
      4  12th Gen Intel(R) Core(TM) i7-12700

# 查看物理CPU个数
[root@localhost ~]# cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l
1
# 查看每个CPU的核心数
[root@localhost ~]# cat /proc/cpuinfo | grep "cpu cores" | uniq
cpu cores	: 4

# 查看服务器的总核心数,也就是逻辑CPU数 物理CPU数 * 每个CPU核数 * 超线程数
[root@localhost ~]# cat /proc/cpuinfo | grep "processor" | wc -l
4

7、CPU指令的内存空间 - 内核态与用户态

(1)什么是内核

内核是一组应用程序,这类程序能够控制所有的硬件及计算机活动。 内核抽象计算机内部硬件资源,并统一管理对外提供支持,内核操作就是计算机硬件的操作。 内核是计算机资源的最大管理者,比如:CPU进程管理、内存管理、文件系统管理、网络接口管理等。

(2)什么是内核态和用户态

操作系统把进程的运行空间分为内核空间和用户空间。 内核空间(Kernel space),只有内核程序访问,也叫进程内核态,可以直接访问内存、硬盘等资源。 用户空间(user space),专门给应用你程序使用,也叫进程用户态,只能访问受限的用户资源。

CPU有两种工作状态:内核态和用户态,内核态比用户态权限高。

在CPU的所有指令中,有些指令是非常危险的,如果错用将导致系统崩溃,比如申请 - 释放内存、杀进程等。 所以CPU的指令分为特权指令和非特权指令,常规将CPU的特权等级分为4个级别:Ring0 - Ring3。 实际Linux系统只用了Rong0和Ring3,所以进程运行Ring3级别时称为运行在用户态,CPU可以执行部分指令;运行在Ring0级别时称为运行在内核态,CPU可以执行任何指令。

CPU处于空间什么态,实际上代表的就是当前CPU正在执行什么级别的指令。

程序最终会编译成一条条的CPU指令,在CPU上运行。 当用户态的程序需要向操作系统申请更高权限的操作时,需要通过【系统调用】向内核发起请求; 系统调用过程中,会发生CPU上下文切换,CPU寄存器会先保存用户态的状态,然后加载内核态相关内容; 系统调用结束之后,CPU寄存器要恢复原来保存的用户态,继续运行进程; 所以,一次系统调用,会发生两次CPU上下文切换

8、中断和CPU的上下文切换

(1)操作系统的中断

操作系统的中断,就类似java中的监听器Listener。 CPU在执行当前程序时系统出现某种信号使得CPU必须停止当前程序,去执行另一段程序来处理紧急事务。处理结束后CPU再返回到原来暂停的程序继续执行,这个过程就称为中断。

中断分为两种: 内部中断:指令执行时由CPU主动产生,比如说【基于时间片的优先级调度算法】,到时间后就会发出一个中断信号告诉CPU处理下一个任务。 外部中断:系统外部设备引发的程序中断(网络数据、鼠标键盘操作)。

(2)什么是CPU上下文切换

Linux是一个多任务操作系统,支持的任务同时运行的数量远远大于CPU的数量, CPU运行程序,每个任务运行之前,CPU需要知道在哪里加载和启动任务,这些信息存储在寄存器和程序计数器中。 寄存器是CPU里面空间小但速度极快的内存,程序计数器存储CPU正在执行的或下一条要执行指令的位置。

CPU寄存器和程序计数器,是CPU在运行任务前依赖的环境,也叫CPU上下文。 CPU上下文切换需要先把前一个任务的CPU上下文保存起来,下次切换回来才知道任务从哪里加载+运行。 再从寄存器和程序计数器加载新任务的上下文运行任务。

每次切换在保存和恢复上下文耗时几十纳秒或微秒(1微秒 = 1000纳秒)

(3)什么情况会发生CPU上下文切换

1、系统调用 即内核态和用户态的切换,一直是同一个进程在运行,不切换进程。一次系统调用的过程发生两次CPU上下文切换

2、进程切换 每个CPU都维护了一个就绪队列,存放活跃线程,根据情况进行调度。 进程是由内核来管理和调度的,进程的切换只能发生在内核态

3、线程切换 进程是资源拥有的基本单位,线程是调度的基本单位,当进程只有一个线程的时候,可以认为进程就等于线程。 线程上下文切换,前后线程同属一个进程,切换时虚拟内存资源不变,只需要保存线程私有数据,比如栈和寄存器。 同进程内的线程切换,要比多进程间的切换消耗更少的资源,所以开发中使用多线程替代多进程。

4、硬件中断 为了快速响应硬件,中断处理会打断进程的正常调度和执行,转而调用中断处理程序,响应设备事件。 打断其他进程时,就需要保存该进程状态,这样在设备事件结束后,就可以从原来的状态恢复。 比如鼠标、键盘等操作,CPU就必须中断正在执行的程序,去响应这些硬件的事件。

二、CPU指标监控

1、CPU平均负载

(1)什么是平均负载

单位时间内,系统处于可运行状态不可中断状态的平均进程数,就是平均活跃进程数,和CPU使用率并没有直接关系。

可运行状态:正在使用CPU或者正在等待CPU的进程;用ps aux命令看到的,处于R状态(Running或Runnable)的进程。

不可中断状态:正处于内核态关键流程中的进程,且流程不可打断的;比如等待硬件设备的I/O响应,为了保证数据的一致性,进程向磁盘读写数据时,在得到磁盘响应前是不能被其他进程中断的。用ps aux命令看到的处于D(Uninterruptible Sleep)状态的进程。

bash 复制代码
[root@localhost ~]# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1 193600  6672 ?        Ss   10:28   0:00 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
root         2  0.0  0.0      0     0 ?        S    10:28   0:00 [kthreadd]
root         4  0.0  0.0      0     0 ?        S<   10:28   0:00 [kworker/0:0H]
root         5  0.0  0.0      0     0 ?        S    10:28   0:00 [kworker/u8:0]
root         6  0.0  0.0      0     0 ?        S    10:28   0:00 [ksoftirqd/0]
polkitd   1238  0.2 10.0 2066188 390164 ?      Ssl  10:28   0:30 mysqld
root      1410  0.0  0.1 154716  5436 ?        Ds   10:31   0:00 sshd: root@pts/0
root      1414  0.0  0.0 116328  2944 pts/0    Ss   10:31   0:00 -bash
root      1499  0.0  0.0      0     0 ?        S    11:34   0:00 [kworker/2:1]
root      1539  0.0  0.0      0     0 ?        S    13:01   0:00 [kworker/1:1]
root      1540  0.0  0.0      0     0 ?        S    13:40   0:00 [kworker/1:2]
postfix   1541  0.0  0.1  88940  4356 ?        S    13:48   0:00 pickup -l -t unix -u
root      1542  0.0  0.0 155476  1864 pts/0    R+   13:51   0:00 ps aux

(2)查看CPU平均负载

bash 复制代码
# 查看CPU平均负载
[root@localhost ~]# uptime
 13:59:32 up  3:31,  1 user,  load average: 0.00, 0.01, 0.05

# 查看逻辑CPU个数
[root@localhost ~]# cat /proc/cpuinfo | grep "processor" | wc -l
4

load average就是平均负载,三个数分别为1分钟、5分钟、15分钟的CPU平均负载。 比如说逻辑CPU个数为2,平均负载也是2,那么这两个CPU刚刚好利用,如果是4个CPU,则有50%空闲。

如果三个数值相差不大,说明负载很平稳。 如果1分钟的值远小于15分钟的值,说明系统近1分钟的负载在降低,过去15分钟内却有很大的负载。 如果1分钟的值远大于15分钟的值,说明最近1分钟的负载在增加,平均负载接近或超过了CPU的个数,意味着系统正在发生过载,持续的时间长则说明系统出现问题需要优化。

推荐CPU平均负载小于等于CPU核数即可。

2、CPU使用率

(1)查看CPU使用率

什么是CPU使用率: CPU非空闲状态运行的时间占比,反映CPU的繁忙程度,和平均负载不一定完全一致。

生产系统的CPU总使用率不要超过70% ~ 80%。 比如单核CPU1秒内非空闲态运行时间为0.8秒,那么它的使用率就是80%。

top命令查看CPU的使用率: 按1会将所有CPU打开: us(user):CPU在用户态运行的时间百分比,通常用户态CPU高表示有应用你程序比较忙,CPU使用率高。 sy(sys):CPU在内核态运行的时间百分比(不包括中断),内核态CPU越低越好,值高则CPU使用率高。 id(idle):CPU处于空闲态的时间占比,CPU会执行一个特定的虚拟进程,名为System Idle Process,值高的话说明CPU比较空闲。 wa(iowait):CPU在等待I/O操作完成所消耗的时间,该指标越低越好,否则表示I/O存在瓶颈,用iostat命令进一步分析。 hi(hardirq):CPU处理硬中断所花费的时间,由外设硬件(键盘、传感器等)发出的中断信号,快速执行。 si(softirq):CPU处理软中断所花费的时间,由软件程序(网络、定时调度等)发出的中断信号,延迟执行。 st(steal):CPU被其他虚拟机占用的时间,仅出现在多虚拟机场景,指标过高的话,检查下宿主机或其他虚拟机是否正常。

(2)CPU使用率和平均负载的区别

CPU平均负载指单位时间内活跃进程数,包括正在使用CPU的进程,还包括等待CPU和等待I/O的进程。 是指可运行状态和不可中断状态的平均进程数。

CPU使用率是单位时间内CPU繁忙情况的统计。

CPU密集型进程,使用大量CPU运算会导致平均负载升高,这个场景这两者是一致的; I/O密集型进程,等待I/O也会导致平均负载升高,但CPU使用率不一定很高。

CPU的效率要远高于磁盘,磁盘读写请求过多就会导致大量I/O等待; 进程在CPU上访问磁盘文件,CPU会向内核发起调用文件的请求,让内核去磁盘取文件,这个时候CPU会切换到其他进程或者空闲; 任务会转换为不可中断睡眠状态,当这种读写请求过多会导致不可中断睡眠状态的进程 过多,导致CPU负载高,利用率低的情况。

大量等待CPU的进程调度也会导致平均负载升高,此时CPU使用率也会比较高。

CPU密集型应用也叫计算密集型,表示该任务需要大量的运算,没有阻塞CPU一直全速运行。比如对视频进行高清解码、机器学习和深度学习模型的训练等。 I/O密集型应用,程序需要大量I/O操作,大部分的时间是CPU在等待I/O(磁盘/内存/网络)的读写操作,CPU利用率低,但是等待I/O也会导致平均负载升高。

3、监控工具

sysstat工具(包含mpstat、pidstat)、vmstat

现在基本都是容器部署+PaSS平台,监控工具很少用到了。

【重磅推荐!免费简单内网穿透神器!支持linux+windows】

推荐内网穿透神器【cpolar】www.cpolar.com/ 点击【免费注册】之后,输入自己的个人信息就可以注册一个账号啦! 本地web项目如何使用外网访问?教你轻松使用cpolar在windows搭建内网穿透 linux虚拟机部署的web项目如何使用外网访问?教你轻松使用cpolar在centos搭建内网穿透 linux虚拟机部署的MySQL如何使用外网访问?教你轻松使用cpolar在centos搭建内网穿透

找工作难?来【万码优才】!专为程序员准备的招聘盛宴

#小程序://万码优才/t8mdtmZFcnqqzPu

大家找工作也可以试一下【万码优才】这个小程序,挺好用的,多一个选择多一份择业机会~

我看了一下,岗位挺多的,只需要完善简历找到想要的岗位,进行投递即可!

相关推荐
码农飞飞7 分钟前
深入理解Rust的模式匹配
开发语言·后端·rust·模式匹配·解构·结构体和枚举
一个小坑货9 分钟前
Rust 的简介
开发语言·后端·rust
monkey_meng39 分钟前
【遵守孤儿规则的External trait pattern】
开发语言·后端·rust
Estar.Lee1 小时前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
新知图书2 小时前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
盛夏绽放2 小时前
Node.js 和 Socket.IO 实现实时通信
前端·后端·websocket·node.js
Ares-Wang2 小时前
Asp.net Core Hosted Service(托管服务) Timer (定时任务)
后端·asp.net
uzong3 小时前
7 年 Java 后端,面试过程踩过的坑,我就不藏着了
java·后端·面试
Rverdoser3 小时前
RabbitMQ的基本概念和入门
开发语言·后端·ruby
Tech Synapse4 小时前
Java根据前端返回的字段名进行查询数据的方法
java·开发语言·后端