日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2.2 CPU 上下文切换是什么意思?(下)

發布時間:2024/9/3 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2.2 CPU 上下文切换是什么意思?(下) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

怎么查看系統的上下文切換情況

過多的上下文切換,會把 CPU 時間消耗在寄存器、內核棧以及虛擬內存等數據的保存和恢復上,縮短進程真正運行的時間,成了系統性能大幅下降的一個 元兇。

使用 vmstat 這個工具,來查詢系統的上下文切換情況。
vmstat 是一個常用的系統性能分析工具,主要用來分析系統的內存使用情況,也常用來分析 CPU 上下文切換和中斷的次數。
vmstat 的使用示例:

[root@doit ~]# vmstat 5 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r b swpd free buff cache si so bi bo in cs us sy id wa st0 0 0 1068760 120384 612716 0 0 0 0 57 98 0 0 100 0 0cs(context switch)是每秒上下文切換的次數。 in(interrupt)則是每秒中斷的次數。 r(Running or Runnable)是就緒隊列的長度,也就是正在運行和等待 CPU 的進程數。 b(Blocked)則是處于不可中斷睡眠狀態的進程數。這個例子中的上下文切換次數 cs 是 98 次,而系統中斷次數 in 則是 57 次,而就緒隊列長度 r 和不可中斷狀態進程數 b 都是 0。

???? vmstat 只給出了系統總體的上下文切換情況,要想查看每個進程的詳細情況,就需要使用我們前面提到過的 pidstat 了。給它加上 -w 選項,你就可以查看每個進程上下文切換的情況了。

每隔 5 秒輸出 1 組數據 [root@doit ~]# pidstat -w 5 Linux 4.20.0-1.el7.elrepo.x86_64 (doit) 07/12/2019 _x86_64_ (2 CPU)04:28:40 PM UID PID cswch/s nvcswch/s Command04:28:45 PM 0 9 0.20 0.00 ksoftirqd/004:28:45 PM 0 10 2.00 0.00 rcu_sched04:28:45 PM 0 11 0.40 0.00 migration/004:28:45 PM 0 15 0.40 0.00 migration/104:28:45 PM 0 27 0.20 0.00 khugepaged04:28:45 PM 0 3086 0.20 0.00 haveged04:28:45 PM 0 3104 9.98 0.00 qemu-ga04:28:45 PM 0 3492 1.00 0.00 httpd04:28:45 PM 0 6094 0.40 0.00 python04:28:45 PM 0 29541 5.39 0.00 kworker/1:0-events_power_efficient04:28:45 PM 0 29590 1.40 0.00 kworker/0:1-events04:28:45 PM 0 29716 0.20 0.20 pidstat一個是 cswch ,表示每秒自愿上下文切換(voluntary context switches)的次數,另一個則是 nvcswch ,表示每秒非自愿上下文切換(non voluntary context switches)的次數。

所謂自愿上下文切換,是指進程無法獲取所需資源,導致的上下文切換。比如說, I/O、內存等系統資源不足時,就會發生自愿上下文切換。
而非自愿上下文切換,則是指進程由于時間片已到等原因,被系統強制調度,進而發生的上下文切換。比如說,大量進程都在爭搶 CPU 時,就容易發生非自愿上下文切換。

案例分析


上下文切換頻率是多少次才算正常呢?

sysbench? 是一個多線程的基準測試工具,一般用來評估不同系統參數下的數據庫負載情況。當然,在這次案例中,我們只把它當成一個異常進程來看,作用是模擬上下文切換過多的問題。

預先安裝 sysbench 和 sysstat 包,如 apt install sysbench sysstat

操作和分析

首先,在第一個終端里運行 sysbench ,模擬系統多線程調度的瓶頸:

# 以 10 個線程運行 5 分鐘的基準測試,模擬多線程切換的問題 [root@doit ~]# sysbench --threads=10 --max-time=300 threads run WARNING: --max-time is deprecated, use --time instead sysbench 1.0.17 (using system LuaJIT 2.0.4)Running the test with following options: Number of threads: 10 Initializing random number generator from current timeInitializing worker threads...Threads started!


在第二個終端運行 vmstat ,觀察上下文切換情況:

[root@doit ~]# vmstat 1procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----r b swpd free buff cache si so bi bo in cs us sy id wa st6 0 0 1066924 120388 612752 0 0 0 0 7 3 0 0 100 0 08 0 0 1066924 120388 612768 0 0 0 0 2472 1695514 17 82 1 0 08 0 0 1066924 120388 612768 0 0 0 0 3062 1847851 17 83 1 0 07 0 0 1066924 120388 612768 0 0 0 0 2093 1696907 16 82 2 0 0 cs 列的上下文切換次數從之前的 3 驟然上升到了 169 萬。同時,注意觀察其他幾個指標: r 列:就緒隊列的長度已經到了 8,遠遠超過了系統 CPU 的個數 2,所以肯定會有大量的 CPU 競爭。 us(user)和 sy(system)列:這兩列的 CPU 使用率加起來上升到了 100%,其中系統 CPU 使用率,也就是 sy 列高達 83%,說明 CPU 主要是被內核占用了。 in 列:中斷次數也上升到了 1 萬左右,說明中斷處理也是個潛在的問題。


綜合這幾個指標,我們可以知道,系統的就緒隊列過長,也就是正在運行和等待 CPU 的進程數過多,導致了大量的上下文切換,而上下文切換又導致了系統 CPU 的占用率升高。

那么到底是什么進程導致了這些問題呢?

在第三個終端再用 pidstat 來看一下, CPU 和進程上下文切換的情況

# 每隔 1 秒輸出 1 組數據-w 參數表示輸出進程切換指標,而 -u 參數則表示輸出 CPU 使用指標[root@doit ~]# pidstat -w -u 1Linux 4.20.0-1.el7.elrepo.x86_64 (doit) 07/12/2019 _x86_64_ (2 CPU)04:38:35 PM UID PID %usr %system %guest %wait %CPU CPU Command04:38:36 PM 0 29730 33.00 167.00 0.00 0.00 200.00 0 sysbench04:38:35 PM UID PID cswch/s nvcswch/s Command04:38:36 PM 0 10 3.00 0.00 rcu_sched04:38:36 PM 0 16 1.00 0.00 ksoftirqd/104:38:36 PM 0 3104 10.00 0.00 qemu-ga04:38:36 PM 0 3492 1.00 0.00 httpd04:38:36 PM 0 29541 14.00 0.00 kworker/1:0-events_power_efficient04:38:36 PM 0 29590 2.00 0.00 kworker/0:1-mm_percpu_wq04:38:36 PM 0 29640 1.00 0.00 sshd04:38:36 PM 0 29714 1.00 0.00 kworker/u4:0-events_unbound04:38:36 PM 0 29742 1.00 0.00 pidstat 從 pidstat 的輸出你可以發現,CPU 使用率的升高果然是 sysbench 導致的,它的 CPU 使用率已經達到了 200%。但上下文切換則是來自其他進程,自愿上下文切換頻率最高的內核線程 kworker。

pidstat 輸出的上下文切換次數,加起來也就幾百,比 vmstat 的 139 萬明顯小了太多。這是怎么回事呢?難道是工具本身出了錯嗎?

pidstat 默認顯示進程的指標數據,加上 -t 參數后, 才會輸出線程的指標。

[root@doit ~]# pidstat -wt 1 Linux 4.20.0-1.el7.elrepo.x86_64 (doit) 07/12/2019 _x86_64_ (2 CPU)04:45:02 PM UID TGID TID cswch/s nvcswch/s Command04:45:03 PM 0 9 - 2.91 0.00 ksoftirqd/004:45:03 PM 0 - 9 2.91 0.00 |__ksoftirqd/004:45:03 PM 0 10 - 10.68 0.00 rcu_sched04:45:03 PM 0 - 10 10.68 0.00 |__rcu_sched04:45:03 PM 0 16 - 0.97 0.00 ksoftirqd/104:45:03 PM 0 - 16 0.97 0.00 |__ksoftirqd/104:45:03 PM 0 3104 - 9.71 0.00 qemu-ga04:45:03 PM 0 - 3104 9.71 0.00 |__qemu-ga04:45:03 PM 0 - 3820 0.97 0.00 |__tuned04:45:03 PM 0 6094 - 0.97 0.00 python04:45:03 PM 0 - 6094 0.97 0.00 |__python04:45:03 PM 0 - 14238 0.97 0.00 |__node04:45:03 PM 0 29590 - 1.94 0.00 kworker/0:1-mm_percpu_wq04:45:03 PM 0 - 29590 1.94 0.00 |__kworker/0:1-mm_percpu_wq04:45:03 PM 0 - 29768 20572.82 100301.94 |__sysbench04:45:03 PM 0 - 29769 18718.45 110695.15 |__sysbench04:45:03 PM 0 - 29770 22306.80 104282.52 |__sysbench04:45:03 PM 0 - 29771 26055.34 86372.82 |__sysbench04:45:03 PM 0 - 29772 20498.06 102583.50 |__sysbench04:45:03 PM 0 - 29773 14956.31 81900.00 |__sysbench04:45:03 PM 0 - 29774 29092.23 112430.10 |__sysbench04:45:03 PM 0 - 29775 24825.24 110958.25 |__sysbench04:45:03 PM 0 - 29776 23862.14 95394.17 |__sysbench04:45:03 PM 0 - 29777 21125.24 87931.07 |__sysbench04:45:03 PM 0 29780 - 12.62 0.00 kworker/1:1-events_power_efficient04:45:03 PM 0 - 29780 12.62 0.00 |__kworker/1:1-events_power_efficient04:45:03 PM 0 29783 - 0.97 1.94 pidstat04:45:03 PM 0 - 29783 0.97 1.94 |__pidstat

? 雖然 sysbench 進程(也就是主線程)的上下文切換次數看起來并不多,但它的子線程的上下文切換次數卻有很多。看來,上下文切換罪魁禍首,還是過多的sysbench 線程。
?? 在觀察系統指標時,除了上下文切換頻率驟然升高,還有一個指標也有很大的變化。是的,正是中斷次數。中斷次數也上升到了 1 萬,但到底是什么類型的中斷上升了,現在還不清楚。接下來繼續抽絲剝繭找源頭。既然是中斷,我們都知道,它只發生在內核態,而 pidstat 只是一個進程的性能分析工具,并不提供任何關于中斷的詳細信息,怎樣才能知道中斷發生的類型呢?

沒錯,那就是從 /proc/interrupts 這個只讀文件中讀取。/proc 實際上是 Linux 的一個虛擬文件系統,用于內核空間與用戶空間之間的通信。/proc/interrupts? 就是這種通信機制的一部分,提供了一個只讀的中斷使用情況。

[root@doit ~]# watch -d cat /proc/interruptsEvery 2.0s: cat /proc/interrupts Fri Jul 12 16:49:08 2019CPU0 CPU1LOC: 83008310 107586288 Local timer interruptsSPU: 0 0 Spurious interruptsPMI: 0 0 Performance monitoring interruptsIWI: 0 1 IRQ work interruptsRTR: 0 0 APIC ICR read retriesRES: 9169892 7079828 Rescheduling interrupts

???? 觀察一段時間,你可以發現,變化速度最快的是重調度中斷(RES),這個中斷類型表示,喚醒空閑狀態的 CPU 來調度新的任務運行。這是多處理器系統(SMP)中,調度器用來分散任務到不同 CPU 的機制,通常也被稱為處理器間中斷(Inter-Processor Interrupts,IPI)。所以,這里的中斷升高還是因為過多任務的調度問題,跟前面上下文切換次數的分析結果是一致的。


現在再回到最初的問題,每秒上下文切換多少次才算正常呢?
???? 這個數值其實取決于系統本身的 CPU 性能。在我看來,如果系統的上下文切換次數比較穩定,那么從數百到一萬以內,都應該算是正常的。但當上下文切換次數超過一萬次,或者切換次數出現數量級的增長時,就很可能已經出現了性能問題。

這時,你還需要根據上下文切換的類型,再做具體分析。比方說:

??? 自愿上下文切換變多了,說明進程都在等待資源,有可能發生了 I/O 等其他問題;
??? 非自愿上下文切換變多了,說明進程都在被強制調度,也就是都在爭搶 CPU,說明 CPU 的確成了瓶頸;
??? 中斷次數變多了,說明 CPU 被中斷處理程序占用,還需要通過查看 /proc/interrupts 文件來分析具體的中斷類型。

小結


通過一個 sysbench 的案例,給你講了上下文切換問題的分析思路。碰到上下文切換次數過多的問題時,我們可以借助 vmstat 、 pidstat 和 /proc/interrupts 等工具,來輔助排查性能問題的根源。


首先通過uptime查看系統負載,然后使用mpstat結合pidstat來初步判斷到底是cpu計算量大還是進程爭搶過大或者是io過多,接著使用vmstat分析切換次數,以及切換類型,來進一步判斷到底是io過多導致問題還是進程爭搶激烈導致問題。

總結

以上是生活随笔為你收集整理的2.2 CPU 上下文切换是什么意思?(下)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。