cpu上下文切换如何查看
上一篇介绍了cpu上下文切换几种场景以及数据保存恢复过程,这篇文章介绍如何查看cpu上下文切换
一、vmstat
安装:yum install -y sysstat
vmstat是一个常用的系统性能分析工具,主要用来分析系统的内存情况,也常用来分析cpu上下文切换和中断的次数。
# vmstat <br/>procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----<br/>r b swpd free buff cache si so bi bo in cs us sy id wa st<br/>1 0 0 1030608 972 119296 0 0 52 15 0 1 4 0 95 0 0
- cs(context switch)是每秒上下文切换的次数。
- in(interrupt)是每秒中断的次数。
- r(Running or Runnable)是就绪队列的长度,也就是等待和运行cpu的进程数。
- b(Blocked)是处于不可中断睡眠状态的进程数。
vmstat只是给出了系统总体的上下切换情况,想查看每个进程的详细情况,就需要使用pidstat。加-w选项。
二、pidstat
pidstat -w 5
Linux 3.10.0-514.26.2.el7.x86_64 (nodejs-test) 06/09/2019 _x86_64_ (2 CPU)
10:53:49 AM UID PID cswch/s nvcswch/s Command
10:53:54 AM 0 9 21.56 0.00 rcu_sched
10:53:54 AM 0 10 0.40 0.00 watchdog/0
10:53:54 AM 0 11 0.40 0.00 watchdog/1
10:53:54 AM 0 12 0.40 0.00 migration/1
10:53:54 AM 0 13 0.40 0.00 ksoftirqd/1
- cswch:每秒自愿上下文切换的次数。
- nvcswch:每秒非自愿上下文切换的次数。
- 自愿上下文切换,是指进程无法获取所需资源,导致上下文切换,如:I/O、内存等资源不足时。
- 非自愿上下文切换,是指进程由于时间片已到等原因,被系统强制调度,进而发生上下文切换。如:大量进程争抢cpu。
案例
操作
打开三个终端
- 创造事故
以 10 个线程运行 5 分钟的基准测试,模拟多线程切换的问题
$ sysbench --threads=10 --max-time=300 threads run
- 打开第二个中断查看
每隔 1 秒输出 1 组数据(需要 Ctrl+C 才结束)
$ 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
6 0 0 6487428 118240 1292772 0 0 0 0 9019 1398830 16 84 0 0 0
8 0 0 6487428 118240 1292772 0 0 0 0 10191 1392312 16 84 0 0 0
- cs列的上下文切换次数升到了139万。
- r列:就绪队列到达了8。超过了cpu的个数。此时肯定有大量cpu竞争。
- us和sy列加起来100%。sy列高达84%,说明cpu主要是被内核占用了。
- in列:中断次数上升到1万左右,说明中断处理也是问题。
- pidstat
利用pidstat查看进程上下文切换详细情况;
#每隔 1 秒输出 1 组数据(需要 Ctrl+C 才结束)
-w 参数表示输出进程切换指标,而 -u 参数则表示输出 CPU 使用指标
$ pidstat -w -u 1
08:06:33 UID PID %usr %system %guest %wait %CPU CPU Command
08:06:34 0 10488 30.00 100.00 0.00 0.00 100.00 0 sysbench
08:06:34 0 26326 0.00 1.00 0.00 0.00 1.00 0 kworker/u4:2
08:06:33 UID PID cswch/s nvcswch/s Command
08:06:34 0 8 11.00 0.00 rcu_sched
08:06:34 0 16 1.00 0.00 ksoftirqd/1
08:06:34 0 471 1.00 0.00 hv_balloon
08:06:34 0 1230 1.00 0.00 iscsid
08:06:34 0 4089 1.00 0.00 kworker/1:5
08:06:34 0 4333 1.00 0.00 kworker/0:3
08:06:34 0 10499 1.00 224.00 pidstat
08:06:34 0 26326 236.00 0.00 kworker/u4:2
08:06:34 1000 26784 223.00 0.00 sshd
? 从上面输出看出,sysbench进程占用cpu100%,自愿上下文切换频率高的内核线程为sshd和 kwordker。但是,加起来也就是几百,没有达到139万。
- pidstat -t参数
#每隔 1 秒输出一组数据(需要 Ctrl+C 才结束)
#-wt 参数表示输出线程的上下文切换指标
$ pidstat -wt 1
08:14:05 UID TGID TID cswch/s nvcswch/s Command
...
08:14:05 0 10551 - 6.00 0.00 sysbench
08:14:05 0 - 10551 6.00 0.00 |__sysbench<br/>08:14:05 0 - 10552 18911.00 103740.00 |__sysbench
08:14:05 0 - 10553 18915.00 100955.00 |__sysbench<br/>08:14:05 0 - 10554 18827.00 103954.00 |__sysbench
...
此时看出,sysbench主进程上下文切换次数不多,但是子线程却很多。
前面我们看见,不止上下文切换频率升高,还有中断次数。
一旦CPU接收了中断请求,CPU就会暂时停止执行正在运行的程序,并且调用一个称为中断处理器或中断服务程序(interrupt service routine)的特定程序。
查看文件接口
#cat /proc/interrupts
?
CPU0 CPU1
25: 10652623 80703151 PCI-MSI-edge virtio3-req.0
26: 0 0 PCI-MSI-edge virtio2-config
27: 2 0 PCI-MSI-edge virtio2-virtqueues
28: 0 0 PCI-MSI-edge virtio0-config
29: 599781 28812335 PCI-MSI-edge virtio0-input.0
30: 2 506 PCI-MSI-edge virtio0-output.0
31: 0 0 PCI-MSI-edge virtio1-config
32: 6893540 111078549 PCI-MSI-edge virtio1-input.0
33: 615 1368 PCI-MSI-edge virtio1-output.0
NMI: 0 0 Non-maskable interrupts
LOC: 3818014562 3882568092 Local timer interrupts
SPU: 0 0 Spurious interrupts
PMI: 0 0 Performance monitoring interrupts
IWI: 92938221 96288600 IRQ work interrupts
RTR: 0 0 APIC ICR read retries
RES: 316386309 327268304 Rescheduling interrupts
CAL: 71367577 3699711 Function call interrupts
TLB: 21377263 20572311 TLB shootdowns
TRM: 0 0 Thermal event interrupts
THR: 0 0 Threshold APIC interrupts
中的RES: 316386309 327268304 Rescheduling interrupts
总结
- 自愿上下文切换变多了,说明进程都在等待资源,有可能发生了IO等其他问题
- 非自愿上下文切换变多了,说明进程在被强制调度,也就是在争抢cpu,说明cpu的确成了瓶颈
- 中断次数变多了,说明cpu被中断处理程序占用,需要查看/proc/interrupts 接口文件。
- 创造事故
原文地址:https://blog.51cto.com/12924846/2406447