上下文切换的案例以及CPU使用率

一. 上节回顾

1. CPU上下文切换:CPU寄存器和程序计数器

2. CPU上下文可以分为几个不同的场景:进程上下文切换,线程上下文切换,中断上下文切换

3. 线程是调度的基本单位,进程是资源拥有的基本单位

二. 自愿上下文切换和非自愿上下文切换

vmstat:只给出了系统总体的上下文切换情况,要想查看每个进程的详细情况,需要pidstat

pidstat -w 5      #每隔5s输出1组数据(重点关注)

cswch/s:表示每秒自愿上下文切换的次数

nvcswch/s:表示每秒非自愿上下文切换的次数

 

1. 自愿上下文切换

自愿上下文切换是指进程无法获取所需自愿,导致的上下文切换,比如:I/O,内存等系统资源不足时,就会发生自愿上下文切换

2. 非自愿上下文切换

非自愿上下文切换是指进程由于时间片已到等原因,被系统强制调度

3. 案例分析

sysbench是一个多线程的基准测试工具,一般来评估不同系统参数下的数据库负载情况

 

(1) 安装

a. yum安装

yum install -y sysbench   #不需要提前准备包

b. tar.gz包安装

#解压:
tar -zxvf 文件名.tar.gz
#进入到解压之后的目录
cd 文件名
./configure
#编译安装
make&&make install

(2) 案例操作和分析步骤

a. 在第一个终端里运行sysbench,模拟系统多线程调用的瓶颈

#以10个线程运行5分钟的基准测试,模拟多线程切换的问题
sysbench --threads=10 --max-time=300 threads run

b. 在第二个终端运行vmstat,观察上下文切换情况

vmstat 3

发现:cs列的上下文切换次数从24一下子到100多万,同时观察其他几个指标

r列:就绪队列的长度已经超过5个,超过了系统CPU的个数4,有大量CPU竞争

us(user)和sy(system)列:这两列的CPU使用率加起来上升到80%以上,其中系统CPU使用率,也就是sy列高达71%,说明CPU主要是被内核占用了

in列:中断次数上升到了4万多,说明中断处理也是一个潜在的问题

 

综合这几个指标,可以知道,系统的就绪队列过长,也就是正在运行和等待CPU的进程数过多,导致了大量的上下文切换,而上下文切换又导致了系统CPU的占用率升高

那么到底是什么进程导致了这些问题?

c. 在第三个终端用pidstat来看一下,CPU和进程上下文切换情况

pidstat -w -u 1   # -w参数,表示输出进程切换指标,-u参数,表示输出CPU使用指标

从pidstat的输出可以发现,CPU的升高果然是sysbench导致的,它的CPU使用率已经达到300%多,但是发现输出的上下文切换次数很小,比vmstat看到的100多万明显小了太多了,这是怎么回事?

我们再来回想一下,前面提到的几种上下文切换场景,其中一点提到,Linux调度的基本单位实际上是线程,而我们的场景sysbench模拟的也是线程调度问题,那么是不是pidstat忽略了线程的数据?

pidstat:默认是显示进程的指标数据,加上 -t 参数,才会输出线程的指标

pidstat -wt 1   # -wt 表示输出线程的上下文切换指标

可以看到,虽然sysbench进程(也就是主线程)的上下文切换次数看起来并不多,但它的子线程的上下文切换却很多,看来,上下文切换的根源,还是过多的sysbench线程

三. CPU使用率

CPU使用率:load average:0.00,0.56,1.60

在性能测试中常用什么指标来描述系统的CPU性能?

估计很多人,可能不是平均负载,也不是CPU上下文切换,而是另一个更直观的指标:CPU使用率

CPU使用率:是单位时间内CPU使用情况的统计,以百分比的形式展示,那CPU使用率是怎么算出来的?

 

为了维护CPU时间,Linux通过事先定义的节拍率(表示为HZ),触发时间中断,并使用全局变量记录了开机以来的节拍数,每发送一次时间中断,全部变量的值加1

节拍率HZ是内核的可配置选项,可以设置100,250,1000等,不同的系统可能设置不同数值,可以通过下面命令查看:

grep 'CONFIG_HZ=' /boot/config-$(uname -r)

同时,正因为节拍率HZ是内核选项,所以用户空间程序并不能直接访问,为了方便用户空间程序,内核还提供了一个用户空间节拍率USER_HZ,它总是固定为100,也就是1/100秒,这样用户空间程序并不需要关心内核中HZ被设置了多少?因为它看到的总是固定值USER_HZ

Linux通过/proc虚拟文件系统,向用户空间提供了系统内部状态的信息,而/proc/stat提供的就是系统的CPU和任务统计信息,比如说,如果你只关心CPU的话,可以执行下面的命令:

cat /proc/stat | grep ^cp

这里输出的一个表格,其中,第一列表示的是CPU编号,如CPU,CPU0,CPU1,而第一行没有编号为2的CPU,表示的是所有CPU的累加,其他列则表示不同场景下CPU的累加节拍数,它的单位是USER_HZ,也就是10ms(1/100秒),这其实就是不同场景下的CPU时间

 

(1) 怎么查看CPU使用率

top

top:显示了系统总体的CPU和内存使用情况,以及各个进程的资源使用情况,默认是3s刷新一次

可以发现,top并没有细分进程的用户态CPU和内核态CPU,那要怎么查看每个进程的详细情况呢?是不是上一次用到的pidstat命令,它可以专门分析每个进程的CPU使用情况

pidstat 1 5   # 每隔1s输出一组数据,共输出5组

pidstat命令,CPU使用率如下:

%usr:用户态CPU使用率

%system:内核态CPU使用率

%guest:运行虚拟机CPU使用率

%wait:等待CPU使用率

%cpu:总的CPU使用率

最后Average部分,还计算了5组数据平均值

通过top,ps,pidstat等工具,能够很快找到CPU使用率过高(100%)的进程,接下来,可能又想知道,占用CPU高的进程的代码是哪个函数?或者哪个类里面的方法,只有这样,我们才能更快的,有针对性的进程优化

posted @ 2020-04-09 15:00  cnhkzyy  阅读(1164)  评论(0编辑  收藏  举报