在每一個任務運行前,CPU 都須要知道任務從哪裏加載、又從哪裏開始運行,也就是說,須要系統事先幫它設置好 CPU 寄存器和程序計數器(Program Counter,PC)。工具
CPU 寄存器,是 CPU 內置的容量小、但速度極快的內存。而程序計數器,則是用來存儲 CPU 正在執行的指令位置、或者即將執行的下一條指令位置。它們都是 CPU 在運行任何任務前,必須的依賴環境,所以也被叫作 CPU 上下文。性能
根據任務的不一樣,CPU 的上下文切換就能夠分爲幾個不一樣的場景,也就是進程上下文切換、線程上下文切換以及中斷上下文切換。線程
進程是資源分配和執行的基本單位;線程是任務調度和運行的基本單位。線程沒有資源,進程給指針提供虛擬內存、棧、變量等共享資源,而線程能夠共享進程的資源。指針
Linux 按照特權等級,把進程的運行空間分爲內核空間和用戶空間。
CPU 特權等級的 Ring 0 和 Ring 3。
內核空間(Ring 0)具備最高權限,能夠直接訪問全部資源;用戶空間(Ring 3)只能訪問受限資源,不能直接訪問內存等硬件設備,必須經過系統調用陷入到內核中,才能訪問這些特權資源。code
進程既能夠在用戶空間運行,又能夠在內核空間中運行。進程在用戶空間運行時,被稱爲進程的用戶態,而陷入內核空間的時候,被稱爲進程的內核態。從用戶態到內核態的轉變,須要經過系統調用來完成。隊列
一次系統調用的過程,實際上是發生了兩次 CPU 上下文切換。進程
線程的上下文切換其實就能夠分爲兩種狀況事件
爲了快速響應硬件的事件,中斷處理會打斷進程的正常調度和執行,轉而調用中斷處理程序,響應設備事件。而在打斷其餘進程時,就須要將進程當前的狀態保存下來,這樣在中斷結束後,進程仍然能夠從原來的狀態恢復運行。內存
對同一個 CPU 來講,中斷處理比進程擁有更高的優先級,因此中斷上下文切換並不會與進程上下文切換同時發生。一樣道理,因爲中斷會打斷正常進程的調度和執行,因此大部分中斷處理程序都短小精悍,以便儘量快的執行結束。資源
中斷只會發生在內核態
從/proc/interrupts 這個只讀文件中讀取。/proc 其實是 Linux 的一個虛擬文件系統,用於內核空間與用戶空間之間的通訊。/proc/interrupts 就是這種通訊機制的一部分,提供了一個只讀的中斷使用狀況。
vmstat 是一個經常使用的系統性能分析工具,主要用來分析系統的內存使用狀況,也經常使用來分析 CPU 上下文切換和中斷的次數。
// 5s 輸出間隔 [root@k8s ~]# 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 4 0 0 1150604 194172 2888576 0 0 4 238 77 35 61 3 36 0 0 2 0 0 1147236 194172 2888812 0 0 0 96 3977 4630 69 4 27 0 0
cs(context switch)是每秒上下文切換的次數。
in(interrupt)則是每秒中斷的次數
r(Running or Runnable)是就緒隊列的長度,也就是正在運行和等待 CPU 的進程數。
b(Blocked)則是處於不可中斷睡眠狀態的進程數。
pidstat給它加上 -w 選項,就能夠查看每一個進程上下文切換的狀況了。
// -w參數表示輸出進程切換指標,而-u參數則表示輸出CPU使用指標 // pidstat 默認顯示進程的指標數據,加上 -t 參數後,纔會輸出線程的指標。 pidstat 5 -w -u Linux 3.10.0-1062.4.1.el7.x86_64 (instance-010oj085) 04/04/2020 _x86_64_ (2 CPU) 04:49:06 PM UID PID cswch/s nvcswch/s Command 04:49:11 PM 0 1 0.20 0.00 systemd 04:49:11 PM 0 6 1.20 0.00 ksoftirqd/0
cswch,表示每秒自願上下文切換(voluntary context switches)的次數,nvcswch,表示每秒非自願上下文切換(non voluntary context switches)的次數。
上下文切換類型: