一段程序要被执行,先编译成机器语言 进入内存 cpu控制器再从内存中获取指令、数据,放到寄存器中, 时钟控制cpu的运算器睡眠时候开始计算,计算时长多长 运算器开始计算,运算过程中,如果还需要数据,控制器再从寄存器中拿数据,拿不到就从内存中拿,如果一个时间片段计算不完,就干其他事,之后再执行,执行完了输出数据给寄存器,再传给内存
影响CPU性能的物理因素:主频、架构、核
GHz
单核、双核、n核

cpu组成
运算
把内存的指令、数据读入寄存器,控制计算机
暂存指针、数据、地址
CPU的几级缓存,就是寄存器
计时
在CPU中进行计算时,都会分配一个时间片段
如果某个任务需要的计算时间比较长,那么cpu的分片就会出现不连续的时间分片
与CPU沟通的桥梁
存cpu的运算数据
硬盘、外存数据

数据
CPU中的控制单元,控制指令执行的顺序,并不是按照先后顺序执行,而是按照优先级顺序
运算单元,进行计算时:
lscpu

lscpu

字段含义
cat /proc/cpuinfo 内存中记录的cpu信息
cat /proc/cpuinfo | grep "physical id"|sort |uniq |wc -l 查看物理cpu数量
cat /proc/cpuinfo | grep "cpu cores"|uniq 查看CPU的core数「核数」
cat /proc/cpuinfo | grep "processor"|wc -l 查看逻辑CPU数量
现在的linux服务器中 load average 不等于 CPU使用率
load average是系统的整体负载体现,它包括 CPU负载+Disk负载+网络负载+外设负载
load average = cpuload + ioload
CPU的使用:用户进程使用时间us、系统内核运行时间sy、空闲时间idle、管理被抢占时间st
繁忙:us + sy + st + ni + hi + si = CPU使用率的时间(除以总时间)
空闲:idle + wa
自愿上下文切换:内存瓶颈 非自愿上下文切换:cpu瓶颈(抢占资源)
上下文:CPU寄存器和程序计数器
程序计数器:存储CPU正在执行的指令位置和下一条指令的位置
上下文切换:先把当前的任务CPU上下文(CPU寄存器和程序计数器)保存起来,然后加载新任务的上下文到CPU的寄存器和程序计数器中,CPU再跳转到计数器上执行新任务
上下文切换可以分为:
进程:资源的基本单位 线程:调度的基本单位
进程上下文切换:特权等级,跨等级时,需要「系统调用」
线程上下文切换
线程,共享进程的资源,但是线程也有自己所有的数据,如栈、寄存器

top
sy系统态高:排查CPU上下文切换
root@zx:~# vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 142112 170316 3332688 0 0 0 5 1 2 1 1 99 0 0
0 0 0 141844 170316 3332728 0 0 0 0 877 1585 1 1 98 0 0
如果cs比较高,说明可能存在上下文切换问题
root@zx:~# pidstat -u -w 1
Linux 5.4.0-54-generic (zx) 06/03/2021 _x86_64_ (2 CPU)
08:45:08 PM UID PID %usr %system %guest %wait %CPU CPU Command
08:45:09 PM 0 6095 0.99 0.00 0.00 0.00 0.99 1 dockerd
08:45:09 PM 0 10684 0.99 0.00 0.00 0.00 0.99 1 containerd-shim
08:45:09 PM 0 10776 0.99 0.99 0.00 0.00 1.98 1 gunicorn
08:45:09 PM 0 479183 0.00 1.98 0.00 0.00 1.98 1 AliYunDun
08:45:09 PM 0 503082 0.00 0.99 0.00 0.00 0.99 0 kworker/0:1-events
08:45:08 PM UID PID cswch/s nvcswch/s Command
08:45:09 PM 0 11 40.59 0.00 rcu_sched
08:45:09 PM 0 10708 1.98 0.99 supervisord
08:45:09 PM 0 10775 0.99 0.00 gunicorn
08:45:09 PM 0 479183 10.89 0.00 AliYunDun
08:45:09 PM 0 496341 3.96 0.00 kworker/1:1-events
08:45:09 PM 0 502548 12.87 0.00 kworker/u4:2-events_power_efficient
08:45:09 PM 0 503082 6.93 0.00 kworker/0:1-events
08:45:09 PM 0 503173 0.99 0.00 pidstat
cswch/s :自愿上下文
nvcswch/s:非资源上下文
si软中断高:CPU抢资源,资源不够用 I/O问题
us用户态高:用户程序计算
GC 资源回收
密集型计算、内存FGC、资源等待(线程池)
服务器cpu性能压测工具,模拟系统压力
$ yum install -y epel-release.noarch && yum -y update
$ yum install -y stress-ng
进程上下文切换「进程密集型」
# 启动N*10个进程,在只有N核的系统上,会产生大量的进程切换,模拟进程间竞争CPU的场景
$ (( proc_cnt = 'nproc'*10 )); stress-ng --cpu $proc_cnt --pthread 1 --timeout 150
stress-ng: info: [504418] dispatching hogs: 2 cpu, 1 pthread
$ top

启动后
$ vmstat 1

vmstat 1
$ pidstat -u -w 1

pidstat -u -w 1
us +sy 约等于 100% us较高 sy较低解决办法:项目所在的服务器,
# 在N核系统上,生成N个进程,每个进程1024个线程,模拟线程间竞争CPU的场景
$ stress-ng --cpu `nproc` --pthread 1024 --timeout 60
$ top

top
$ vmstat 1

vmstat 1
$ pidstat -u -w 1

pidstat -u -w 1
当一个程序开启了大量的线程,就会使用大量的内存资源,就会出现大量的cpu竞争。
从内存中获取数据会有大量的IO数据交换。
解决办法
# 开启1个worker不停的读写临时文件,同时启动 6个workers不停的调用sync系统调用提交缓存
$ stress-ng -i 6 --hdd 1 --timeout 150
$ top

top
$ vmstat 1

vmstat 1
$ mpstat -P ALL 3

mpstat -P ALL 3
$ pidstat -w 1

image-20210605101558463
解决办法
磁盘性能导致
网络IO导致