研究怎么分析CPU上下文切换的问题
1.怎么查看系统上下文切换情况
vmstat是一个常用的系统性能分析工具,主要用来分析系统内存使用情况,也用来分析CPU上下文切换和中断次数
1
2
3
4
5
6
|
# 每隔5s输出一组数据
$ vmstat 5
# 打印
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
5 0 0 1376000 10384 335352 0 0 1 0 97 0 0 0 99 0 0
|
- cs(context switch)是每秒上下文切换次数
- in(interrupt)则是每秒中断的次数
- r(running or runnable)是就绪队列的长度,也就是正在运行和等待CPU的进程数。
- b(blocked)则是处于不可中断睡眠状态的进程数。
pidstat -w 可以查看每个进程上下文切换的情况
1
2
3
4
5
6
7
8
9
10
11
|
# 每隔5s输出一组数据
$ pidstat -w 5
# 打印
Linux 4.19.76-linuxkit (4f913ef1ae8f) 05/27/20 _x86_64_ (4 CPU)
16:01:26 UID PID cswch/s nvcswch/s Command
16:01:31 0 27 0.20 0.00 pidstat
16:01:31 UID PID cswch/s nvcswch/s Command
16:01:36 0 27 0.20 0.00 pidstat
|
cswch ,表示每秒自愿上下文切换 (voluntary context switches)的次数
nvcswch ,表示每秒非自愿上下文 切换(non voluntary context switches)的次数。
自愿上下文切换,是指进程无法获取所需资源,导致的上下文切换。比如说, I/O、内存等系统资源不足时,就会发生自愿上下文切换。
非自愿上下文切换,则是指进程由于时间片已到等原因,被系统强制调度,进而发生 的上下文切换。比如说,大量进程都在争抢 CPU 时,就容易发生非自愿上下文切换。
2.案例分析
工具: sysbench
用户权限: root
操作:
步骤1. 在第一个终端运行sysbench,模拟系统多线程调度瓶颈
1
2
|
# 以10个线程运行5min的基准测试,模拟多线程切换的问题
$ sysbench --threads=10 --max-time=300 threads run
|
步骤2. 在第二个终端运行vmstat,观察上下文切换情况
1
2
3
4
5
6
7
8
9
|
# 每隔1s输出1组数据
$ 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
12 0 0 1357028 10408 349740 0 0 1 0 105 40 0 1 99 0 0
9 0 0 1357028 10408 349748 0 0 0 0 37666 880945 25 68 8 0 0
7 0 0 1357028 10408 349748 0 0 0 0 37639 916386 25 68 8 0 0
5 0 0 1357028 10408 349748 0 0 0 0 37563 866896 26 67 7 0 0
|
观察指标(本地实验结果)
r:就绪队列长度达到12(远超本地cpu个数4个),增加cpu竞争
us(user)和sy(system):系统cpu使用率为67%,说明cpu主要被内核占用了
in:中断次数上升到3.7万
分析得知:系统的就绪队列过长,也就是正在运行和等待 CPU 的进 程数过多,导致了大量的上下文切换,而上下文切换又导致了系统 CPU 的占用率升高。
步骤3. 在第三个中断使用pidstat分析,CPU和进程上下文切换的情况
1
2
3
4
5
6
7
8
9
10
11
12
|
# 每隔 1 秒输出 1 组数据
# -w 参数表示输出进程切换指标,而 -u 参数则表示输出 CPU 使用指标
$ pidstat -w -u 1
# 打印
Linux 4.19.76-linuxkit (4f913ef1ae8f) 05/27/20 _x86_64_ (4 CPU)
17:10:52 UID PID %usr %system %guest %wait %CPU CPU Command
17:10:53 0 82 87.13 271.29 0.00 0.00 358.42 1 sysbench
17:10:52 UID PID cswch/s nvcswch/s Command
17:10:53 0 93 0.99 1.98 vmstat
17:10:53 0 95 0.99 28.71 pidstat
|
分析:可以看出sysbench对cpu使用率高达358.42%,上下文切换频率低(这是因为sysbench主线程的上下文切换并不高,但它的子线程的切换却很高)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
# -wt 参数表示输出线程的上下文切换指标
$ pidstat -wt 1
# 打印
Linux 4.19.76-linuxkit (4f913ef1ae8f) 05/28/20 _x86_64_ (4 CPU)
03:28:01 UID TGID TID cswch/s nvcswch/s Command
03:28:02 0 - 97 10069.23 67911.54 |__sysbench
03:28:02 0 - 98 6050.00 78664.42 |__sysbench
03:28:02 0 - 99 6675.96 79503.85 |__sysbench
03:28:02 0 - 100 7087.50 59591.35 |__sysbench
03:28:02 0 - 101 7745.19 82932.69 |__sysbench
03:28:02 0 - 102 6235.58 79698.08 |__sysbench
03:28:02 0 - 103 7875.96 86739.42 |__sysbench
03:28:02 0 - 104 6096.15 88155.77 |__sysbench
03:28:02 0 - 105 6515.38 74141.35 |__sysbench
03:28:02 0 - 106 6939.42 93804.81 |__sysbench
03:28:02 0 107 - 0.96 1.92 vmstat
03:28:02 0 - 107 0.96 1.92 |__vmstat
03:28:02 0 108 - 0.96 173.08 pidstat
03:28:02 0 - 108 0.96 173.08 |__pidstat
|
分析:可以看出子线程的cswch和nvcswch很高
步骤4.查看中断次数
中断只发生在内核态中,pidstat只是进程的分析工具,所以要从/proc/interrupts文件中读取
1
2
3
4
5
6
7
8
|
# -d 参数表示高亮显示变化的区域
$ watch -d cat /proc/interrupts
# 打印
# 数值分别对应的是cpu0 cpu1 cpu2 cpu3
...
RES: 3404165 3087853 3195615 3123227 Rescheduling interrupts
...
|
观察一段时间RES(重调度中断)一直在快速上升