CPU上下文切换可分为进程上下文切换、线程上下文切换和中断上下文切换。
怎么查看系统上下文切换情况
vmstat 5
- cs(context switch):每秒上下文切换次数。
- in(interrupt): 每秒中断次数。
- r(Running or Runnable): 就绪队列长度,也就是正在运行和等待CPU的进程数。
- b(Blocked): 处于不可中断睡眠状态的进程数。
查看进程上下文切换情况
#每5s输出一组数据
# 每隔5秒输出1组数据
$ pidstat -w 5
Linux 4.15.0 (ubuntu) 09/23/18 _x86_64_ (2 CPU)
08:18:26 UID PID cswch/s nvcswch/s Command
08:18:31 0 1 0.20 0.00 systemd
08:18:31 0 8 5.40 0.00 rcu_sched
...
pidstat -w -u 1
pidstat -wt 1
系统的就绪队列过长,也就是正在运行和等待CPU的进程数过多,会导致大量的上下文切换,而上下文切换会导致系统CPU占用率升高。
自愿上下文切换和非自愿上下文切换
-
自愿上下文切换,是指进程无法获取所需资源,导致的上下文切换。比如说,IO、内存等系统资源不足时,就会发生自愿上下文切换。
-
非自愿上下文切换,则是指进程由于时间片已等到等原因,被系统强制调度,进而发生的上下文切换。比如说,大量进程都在争抢CPU时,就容易发生非自愿上下文切换。
每次上下文切换多少次才算正常呢?
这个数值取决于系统本身的CPU性能。在我看来,如果系统的上下文切换次数比较稳定,那么从数百到一万以内,都应该算是正常的。但当上下文切换超过一万次,或者切换次数出现数量级增长时,就很可能出现了性能问题。
中断
watch -d cat /proc/interrupts
观察一段时间,可以发现,变化速度最快的是重调度中断(RES),这个中断类型表示,唤醒空间状态的CPU来调度新的任务运行。这是多处理器系统(SMP)中,调度器用来分散任务到不同CPU的机制,通常也被称为处理器间中断(IPI)。
小结
- 自愿上下文切换变多了,说明进程都在等待资源,有可能发生了IO等其他问题。
- 非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢CPU,说明CPU的确成了瓶颈。
- 中断次数变多了,说明CPU被中断处理程序占用,可通过/proc/interrupts文件来分析具体的中断类型。
练习
# 以10个线程运行5分钟的基准测试,模拟多线程切换的问题
$ sysbench --threads=10 --max-time=300 threads run
vmstat 1
ps -ef|grep sysbench
pidstat -wt -p pid 1 5
watch -d cat /proc/interrupts