如何查看系統的上下文切換情況
vmstat 是一個常用的系統性能分析工具,主要用來分析系統的內存使用情況,也常用來分析 CPU 上下文切換和中斷的次數。
# 每隔 5 秒輸出 1 組數據
vmstat 5procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r b 交換 空閑 緩沖 緩存 si so bi bo in cs us sy id wa st0 0 0 8090200 959848 5225828 0 0 15 14 150 126 6 1 93 0 00 0 0 8114904 959872 5201488 0 0 0 270 2056 7736 4 2 94 0 0
重點關注:
cs(context switch):每秒上下文切換的次數
in(interrupt):每秒中斷的次數
r(running or runnable):就緒隊列長度,即正在運行和等待CPU的進程數
b(blocked):處于不可中斷睡眠狀態的進程數
vmstat只給出系統總體的上下文切換情況,可以用pidstat -w查看每個進程上下文切換的情況。
重點關注:
cswch:每秒自愿上下文切換的次數,指的是進程無法獲取所需資源導致的上下文切換,如I/O、內存等系統資源 不足
ncswch:每秒非自愿上下文切換的次數,指的是時間片耗盡等其他原因,被系統強制調度發生的上下文切換,如大量進程搶奪CPU。
# 每隔5秒輸出1組數據
dyy@dyy-Lenovo-ThinkBook-14-IIL:~$ pidstat -w 5
Linux 5.4.0-74-generic (dyy-Lenovo-ThinkBook-14-IIL) 2021年09月11日 _x86_64_(8 CPU)
19時36分03秒 UID PID cswch/s nvcswch/s Command
19時36分08秒 0 1 259.28 0.20 systemd
19時36分08秒 0 22496 3.79 0.00 kworker/6:0-events
19時36分08秒 0 22508 2.20 0.00 kworker/4:3-events
19時36分08秒 1000 22606 0.20 0.00 pidstat
模擬壓測
# 以 10 個線程運行 5 分鐘的基準測試,模擬多線程切換的問題
$ sysbench --threads=10 --max-time=300 threads run
運行之后,在另外一個終端上可以看出:
cs突然增加了許多:
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r b 交換 空閑 緩沖 緩存 si so bi bo in cs us sy id wa st0 0 0 6177232 992200 6797896 0 0 0 0 2376 7604 6 2 92 0 00 0 0 6191628 992208 6783560 0 0 0 52 2136 6504 4 2 94 0 09 0 0 6206244 992208 6767868 0 0 0 0 2176 204091 6 9 84 0 08 0 0 6205984 992208 6767608 0 0 0 0 3140 1344343 18 53 28 0 07 0 0 6195676 992208 6778792 0 0 0 0 4403 1283034 19 54 27 0 07 0 0 6194896 992208 6779332 0 0 0 0 4521 1370898 18 50 32 0 03 0 0 6201196 992208 6773336 0 0 0 4 4633 1309928 19 50 31 0 0
r 列:就緒隊列的長度變長所以肯定會有大量的 CPU 競爭。
us(user)和 sy(system)列:這兩列的 CPU 使用率加起來上升到了 100%,其中系統 CPU 使用率,也就是 sy 列高達 84%,說明 CPU 主要是被內核占用了。
in 列:中斷次數也上升到了 4000左右,說明中斷處理也是個潛在的問題。
使用命令:
# 每隔 1 秒輸出一組數據(需要 Ctrl+C 才結束)
# -wt 參數表示輸出線程的上下文切換指標
$ pidstat -wt 1
sysbench 進程(也就是主線程)的上下文切換次數看起來并不
多,但它的子線程的上下文切換次數卻有很多。
平均時間: UID TGID TID cswch/s nvcswch/s Command
平均時間: 0 - 28411 48857.14 10855.95 |__sysbench
平均時間: 0 - 28412 49817.26 13526.39 |__sysbench
平均時間: 0 - 28413 48023.41 13608.33 |__sysbench
平均時間: 0 - 28414 48886.31 12581.94 |__sysbench
平均時間: 0 - 28415 48584.13 12016.27 |__sysbench
平均時間: 0 - 28416 47521.83 13308.93 |__sysbench
平均時間: 0 - 28417 48813.89 12481.55 |__sysbench
平均時間: 0 - 28418 49105.16 14612.70 |__sysbench
平均時間: 0 - 28419 50239.29 13927.38 |__sysbench
平均時間: 0 - 28420 47539.09 13134.33 |__sysbench
當然也可以通過下面命令查看高亮地區,即切換頻繁的地區:
# -d 參數表示高亮顯示變化的區域
$ watch -d cat /proc/interrupts
你可以發現,變化速度最快的是重調度中斷(RES),這個中斷類型表示,喚醒空閑狀態的 CPU 來調度新的任務運行。這是多處理器系統(SMP)中,調度器用來分散任務到不同 CPU 的機制,通常也被稱為處理器間中斷(Inter-Processor Interrupts,IPI)。
所以,這里的中斷升高還是因為過多任務的調度問題。
總結
自愿上下文切換變多了,說明進程都在等待資源,有可能發生了 I/O 等其他問題;
非自愿上下文切換變多了,說明進程都在被強制調度,也就是都在爭搶 CPU,說明 CPU
的確成了瓶頸;
中斷次數變多了,說明 CPU 被中斷處理程序占用,還需要通過查看 /proc/interrupts 文
件來分析具體的中斷類型。