测试驿栈-由浅入深学性能 性能测试连载 (25)-剖析 cpu 上下文切换对负载的影响

飞天小子的性能课堂 · 2019年11月20日 · 1950 次阅读

性能答疑 QQ 群:697244251

cpu 平均负载

cpu 平均负载指的是单位时间内正在运行的不可中断的平均进程数,也就是是等待处理的任务队列
下图红圈显示的是 5 分钟,10 分钟,15 分钟内的平均负载

导致 cpu 平均负载升高的原因

1:CPU 密集型
2: I/O 密集型
3:大量进程竞争 cpu

平均负载究竟是如何升高的?
CPU 密集型,需要大量计算资源,会消耗 cpu;
I/O 密集型需要等待 I/O,会有大量的不可中断进程;

Linux 系统支持多用户多任务,它支持远远大于 cpu 的进程数运行。当大量的进程竞争 cpu,也就是存在大量的可运行进程。而 cpu 每次却只能运行一个任务,其他的进程都是在等待。整个过程其实是 cpu 根据时间片分配给多进程去轮流运行任务,所以在轮流执行的过程中是非常消耗 cpu 资源的。而当一个任务需要运行前,cpu 需要知道从那里加载,从哪里开始运行,也就是系统需要事先设置好cpu 寄存器和程序计数器
cpu 寄存器: cpu 内置的容量小且速度极快的内存。
程序计数器: 用来存储 cpu 正在执行的指令位置,或者即将执行的下一条指令位置。

这两个是 CPU 在运行任何任务前所必须依赖的前置条件,所以也被称为 CPU 上下文

CPU 上下文切换分类:

1:进程上下文切换
2:系统调用上下文切换
3:线程上下文切换:
4:中断上下文切换
5:主动上下文切换和被动上下文切换

进程上下文切换

进程上下文切换是指从一个进程切换到另一个进程,过程如下
1:接受切换信号,挂起进程,记录当前的进程的虚拟内存、栈等资源存储
2:存储进程在 CPU 的上下文状态
3:检索下一个进程 CPU 的上下文
4:加载到 CPU 的寄存器中进行进程恢复
5:刷新进程保存的虚拟内存和用户栈
6:跳转到程序计数器指向的位置,恢复进程运行
很多进程切换时,会消耗大量时间去保存恢复 cpu 上下文和用户空间状态,而 cpu 分配给进程的时间片是有限的。这就导致 cpu 实际运行进程时间(cpu 利用率)大大降低。而当时间片用完,进程又必须挂起,就导致了 cpu 负载急剧升高。

系统调用上下文切换

系统的进程空间分为用户态和内核态,内核态和用户态是相互隔离的。内核态可以访问用户数据,用户态不能访问内核数据。
加载磁盘里的一个文件,触发的指令是进程的用户态。而操作磁盘就需要系统调用内核态。此时原先的用户态就需要保存起来,执行内核态的指令,加载完数据就需要恢复用户态,继续运行进程。指令跳转也实现了隔离。
用户空间通过 API 请求内核空间的服务来完成其功能——内核提供给用户空间的这些 API, 就是系统调用。当一个系统调用发生时必然会发生两次 CPU 上下文切换,且始终在一个进程中运行。

线程上下文切换

线程和进程的区别在于:线程是调度的基本单位;进程是资源拥有的基本单位。内核中的任务调度,调度的对象就是线程,而进程给线程提供虚拟内存、全局变量等资源。

当进程只有一个线程的时候,进程就等于线程;
当进程有多个线程的时候,这些线程会共享虚拟内存与全局变量等资源。它们在上下文切换的时候不需要进行修改
线程的私有数据的在上下文切换时需要保存

所以多线程间的切换比多进程间的切换消耗更少的资源

中断上下文切换

系统调用的中断是由于软件的触发而中断,称为软中断。如前文所述,系统调用会触发内核的执行,因此会产生上下文切换。
中断上下文切换不会涉及到进程的用户态,只需要内核态执行。因此对于一个 cpu 来说,中断处理比进程的优先级更高

主动切换与被动切换

主动上下文切换:cswch/s:当某一任务处于阻塞,比如说, I/O、内存等系统资源不足时,就会发生自愿上下文切换 将主动让出自己的 CPU 资源

被动上下文切换:nvcswch/s:CPU 分配给某一任务的时间片耗尽,因此将强迫该进程让出 CPU 的执行权。比如大量进程争抢 CPU

查看上下文切换

vmstat 命令

vmstat 用来分析系统内存使用情况,也用来分析 cpu 上下文切换和中断的次数。术语解释如下:
r: 队列的长度,也就是正在运行和等待 CPU 的进程数
b: 处于不可中断状态的进程数
cs: Context switch 是每秒上下文切换的次数
in: Interrupt 则是每秒中断的次数

pidstat 命令

pidstat -p【pid】-w 1 10 显示线程的上下文切换,主动切换与被动切换

dstat -y显示系统中断和上下文切换的整体信息

watch -d cat /proc/interrupts分析软件中断的类别

sysbench 命令

*sysbench --threads=10 --max-time=300 threads run * 模拟 10 个线程运行 5 分钟的基准测试,演示多线程导致的上下文切换,cpu 负载升高

总结

主动切换过多就是内存/io 资源不足了;
被动切换过多就是进程过多导致 cpu 时间片不足;

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册