您好,登錄后才能下訂單哦!
本篇內容主要講解“CPU上下文切換是什么意思”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“CPU上下文切換是什么意思”吧!
CPU 上下文 可以理解成 CPU寄存器狀態以及程序計數器PC , 這些都是記錄CPU當前任務的狀態。CPU 上下文切換 會把當前的cpu的上下文保存下來,然后加載新任務的對應上下文,而這些保存下來的上下文,會存儲在系統內核中,并在任務重新調度執行時再次加載進來。這樣就能保證任務原來的狀態不受影響,讓任務看起來還是連續運行。
任務一般包括:
1.進程
2.線程
3.中斷上下文
CPU 上下文的切換會因特權模式切換、進程上下文切換、線程上下文切換以及中斷上下文切換 產生。
特權模式切換
Linux 按照特權等級,把進程的運行空間分為內核空間和用戶空間,分別對應著下圖中, CPU 特權等級的 Ring 0 和 Ring 3。內核空間(Ring 0)具有最高權限,可以直接訪問所有資源;用戶空間(Ring 3)只能訪問受限資源,不能直接訪問內存等硬件設備,必須通過系統調用陷入到內核中,才能訪問這些特權資源。
進程可以在用戶空間運行,也可以在內核空間運行。 當調用open()、read()、write()、close()系統函數,CPU會保存原來用戶態的指令位置,然后更新CPU寄存器內核態指令的新位置。最后執行內核態函數。當系統調用結束后,CPU恢復原來的用戶態,切換回用戶空間繼續執行進程。
可以看到 用戶態->內核態, 內核態->用戶態 這兩個過程總共是產生了兩次CPU上下文切換。不過,需要注意的是,系統調用過程中,并不會涉及到虛擬內存等進程用戶態的資源
進程上下文切換
進程上下文不僅包括了虛擬內存、棧、全局變量等用戶空間的資源,還包括了內核堆棧、寄存器等內核空間的狀態,與系統調用相比進程間的切換還需要把內容保存下來。
進程上下文切換數量多,容易導致CPU花費更多的時間在寄存器、虛擬內存、內核棧等資源的保存和恢復上,減少了進程運行時間,致使平均負載升高。Linux 通過 TLB(Translation Lookaside Buffer)來管理虛擬內存到物理內存的映射關系。當虛擬內存更新后,TLB 也需要刷新,內存的訪問也會隨之變慢。特別是在多處理器系統上,緩存是被多個處理器共享的,刷新緩存不僅會影響當前處理器的進程,還會影響共享緩存的其他處理器的進程。
進程上下文切換發生在進程調度的過程。
主要在以下場景觸發:
CPU時間是被劃分成各個時間片,當前進程的時間片被耗盡之后會被系統掛起,切換到其他正在等待CPU的進程來運行。
進程在系統資源不足(比如內存不足)時,要等到資源滿足后才可以運行,這個時候進程也會被掛起,并由系統調度其他進程運行。
當進程通過睡眠函數 sleep 或者 sched_yield 這樣的方法將自己主動掛起時,自然也會重新調度。
當有優先級更高的進程運行時,為了保證高優先級進程的運行,當前進程會被掛起,由高優先級進程來運行。
發生硬件中斷時,CPU 上的進程會被中斷掛起,轉而執行內核中的中斷服務程序。
線程上下文切換
線程與進程最大的區別在于,線程是調度的基本單位,而進程則是資源擁有的基本單位。linux內核中的任務調度,實際上的調度對象是線程;而進程只是給線程提供了虛擬內存、全局變量等資源。進程中只有一個線程,進程等于線程。因為同一進程下線程是共享虛擬內存,相關間的切換只需保存其私有數據、寄存器等,因此進程內的線程切換比進程間的切換消耗更少資源。
中斷上下文切換
為了快速響應硬件的事件,中斷處理會打斷進程的正常調度和執行,轉而調用中斷處理程序,響應設備事件。而在打斷其他進程時,就需要將進程當前的狀態保存下來,這樣在中斷結束后,進程仍然可以從原來的狀態恢復運行。跟進程上下文不同,中斷上下文切換并不涉及到進程的用戶態。所以,即便中斷過程打斷了一個正處在用戶態的進程,也不需要保存和恢復這個進程的虛擬內存、全局變量等用戶態資源。中斷上下文,其實只包括內核態中斷服務程序執行所必需的狀態,包括 CPU 寄存器、內核堆棧、硬件中斷參數等。對同一個 CPU 來說,中斷處理比進程擁有更高的優先級,所以中斷上下文切換并不會與進程上下文切換同時發生。同樣道理,由于中斷會打斷正常進程的調度和執行,所以大部分中斷處理程序都短小精悍,以便盡可能快的執行結束。另外,跟進程上下文切換一樣,中斷上下文切換也需要消耗 CPU,切換次數過多也會耗費大量的 CPU,甚至嚴重降低系統的整體性能。所以,當你發現中斷次數過多時,就需要注意去排查它是否會給你的系統帶來嚴重的性能問題。
CPU上下文切分析
vmstat 是一個常用的系統性能分析工具,主要用來分析系統的內存使用情況,也常用來分析 CPU 上下文切換和中斷的次數。
root@ECSab169d:~# 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 1 0 90720 3960176 1036 3014980 0 0 35 85 0 1 1 0 98 0 0 0 0 90720 3959928 1036 3015004 0 0 0 24 240 358 0 0 99 0 0 0 1 90720 3959356 1036 3015068 0 0 0 34 260 390 1 0 99 0 0 0 0 90720 3959204 1036 3015088 0 0 0 23 234 340 0 0 99 0 0 0 0 90720 3960708 1036 3015088 0 0 0 609 297 429 0 0 99 0 0 0 0 90720 3960772 1036 3015112 0 0 0 140 295 410 0 0 99 0 0 0 0 90720 3960688 1036 3015164 0 0 0 36 269 406 0 0 99 0 0
r 是就緒隊列的長度,也就是正在運行和等待 CPU 的進程數。
b 則是處于不可中斷睡眠狀態的進程數
swpd 交換分區大小,一般在內存不足的情況會使用swap進行擴展。
free 空閑的物理內存的大小,我的機器內存總共8G,剩余3415M。
buff Linux/Unix系統是用來存儲,目錄里面有什么內容,權限等的緩存,我本機大概占用300多M
cache cache直接用來記憶我們打開的文件,給文件做緩沖,我本機大概占用300多M(這里是Linux/Unix的聰明之處,把空閑的物理內存的一部分拿來做文件和目錄的緩存,是為了提高 程序執行的性能,當程序使用內存時,buffer/cached會很快地被使用。)
si 每秒從磁盤讀入虛擬內存的大小,如果這個值大于0,表示物理內存不夠用或者內存泄露了,要查找耗內存進程解決掉。我的機器內存充裕,一切正常。
so 每秒虛擬內存寫入磁盤的大小,如果這個值大于0,同上。
bi 塊設備每秒接收的塊數量,這里的塊設備是指系統上所有的磁盤和其他塊設備,默認塊大小是1024byte,我本機上沒什么IO操作,所以一直是0,但是我曾在處理拷貝大量數據(2-3T)的機器上看過可以達到140000/s,磁盤寫入速度差不多140M每秒
bo 塊設備每秒發送的塊數量,例如我們讀取文件,bo就要大于0。bi和bo一般都要接近0,不然就是IO過于頻繁,需要調整。
in 每秒CPU的中斷次數,包括時間中斷
cs 每秒上下文切換次數
可以看到,這個例子中的上下文切換次數 cs 是 33 次,而系統中斷次數 in 則是 25 次,而就緒隊列長度 r 和不可中斷狀態進程數 b 都是 0。
vmstat 只給出了系統總體的上下文切換情況,要想查看每個進程的詳細情況,就需要使用我們前面提到過的 pidstat 了。給它加上 -w 選項,你就可以查看每個進程上下文切換的情況了。
root@xxxxx:~# pidstat -w 5 Linux 4.15.0-66-generic (xxxxx) 01/25/2021 _x86_64_ (4 CPU) 05:30:32 PM UID PID cswch/s nvcswch/s Command 05:30:37 PM 0 8 18.16 0.00 rcu_sched 05:30:37 PM 0 11 0.20 0.00 watchdog/0 05:30:37 PM 0 183 4.59 0.00 kworker/3:1H 05:30:37 PM 0 388 2.40 0.00 kworker/0:1H 05:30:37 PM 0 546 0.20 0.00 irqbalance 05:30:37 PM 0 621 9.98 0.00 qemu-ga 05:30:37 PM 109 663 0.40 0.00 uml_switch 05:30:37 PM 0 1275 0.40 0.00 master 05:30:37 PM 110 1277 0.20 0.00 qmgr 05:30:37 PM 0 5896 7.39 0.00 kworker/0:0 05:30:37 PM 0 13579 8.18 0.00 sshd 05:30:37 PM 0 13766 0.20 0.00 vmstat 05:30:37 PM 0 26398 5.19 0.00 kworker/u8:1 05:30:37 PM 0 28341 6.19 0.00 kworker/u8:2 05:30:37 PM 0 28898 5.99 1.40 bash
這個結果中有兩列內容是我們的重點關注對象。一個是 cswch ,表示每秒自愿上下文切換(voluntary context switches)的次數,另一個則是 nvcswch ,表示每秒非自愿上下文切換(non voluntary context switches)的次數。
謂自愿上下文切換: 是指進程無法獲取所需資源,導致的上下文切換。比如說, I/O、內存等系統資源不足時,就會發生自愿上下文切換。
非自愿上下文切換: 則是指進程由于時間片已到等原因,被系統強制調度,進而發生的上下文切換。比如說,大量進程都在爭搶 CPU 時,就容易發生非自愿上下文切換。
總結
自愿上下文切換變多了,說明進程都在等待資源,有可能發生了 I/O 等其他問題;
非自愿上下文切換變多了,說明進程都在被強制調度,也就是都在爭搶 CPU,說明 CPU 的確成了瓶頸;
中斷次數變多了,說明 CPU 被中斷處理程序占用,還需要通過查看 /proc/interrupts 文件來分析具體的中斷類型
到此,相信大家對“CPU上下文切換是什么意思”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。