為什麼大量程序(通常程序數大于CPU個數)的運作會導緻CPU長時間處于等待時間而導緻平均負債率過高呢?沒有使用CPU且無不可中斷的程序,這就涉及到了上下文切換。
Linux 是一個多任務作業系統,它支援遠大于 CPU 數量的任務同時運作,這是通過頻繁的上下文切換、将CPU輪流配置設定給不同任務進而實作的。即通過上下文切換實作CPU的時間分片。
什麼是任務?
1、程序和線程是最常見的任務;
2、硬體通過觸發信号,會導緻中斷處理程式的調用,也是一種常見的任務。
每個程序運作時,CPU都需要知道程序已經運作到了哪裡以及目前的各種狀态,是以系統事先設定好 CPU 寄存器和程式計數器。 CPU 上下文切換,就是先把前一個任務的 CPU 上下文(CPU 寄存器和程式計數器)儲存起來,然後加新任務的上下文到這些寄存器和程式計數器,最後再跳轉到程式計數器所指的新位置,運作新任務,而儲存下來的上下文,會存儲在系統核心中,并在任務重新排程執行時再次加載進來。
每次上下文切換都需要幾十納秒到到微秒的CPU時間,是以如果程序上下文切換次數過多,就會導緻 CPU 将大量時間耗費在寄存器、核心棧以及虛拟記憶體等資源的儲存和恢複上,進而大大縮短了真正
運作程序的時間,實際上有效的CPU運作時間大大減少(可以認為上下文切換對使用者來說是在做無用功)。
那麼上下文切換的時機有哪些:
1、根據排程政策,将CPU時間劃片為對應的時間片,當時間片耗盡,就需要進行上下文切換;
2、程序在系統資源不足,會在擷取到足夠資源之前程序挂起;
3、程序通過sleep函數将自己挂起;
4、當有優先級更高的程序運作時,為了保證高優先級程序的運作,目前程序會被挂起,由高優先級程序來運作,也就是被搶占;
5、當發生硬體中斷時,CPU 上的程序會被中斷挂起,轉而執行核心中的中斷服務程式。
根據任務,可以将上下文切換分為:1)程序上下文切換(隻有在程序排程時才需要切換上下文;2)線程上下文切換;3)中斷上下文切換。
如何檢視CPU上下文切換情況,使用vmstat工具。
vmstat 隻給出了系統總體的上下文切換情況,要想檢視每個程序的詳細情況,就需要使用我們前面提到過的 pidstat了。給它加上 -w 選項,你就可以檢視每個程序上下文切換的情況了:pidstat -w 5 1
上圖中,可以看到stress指令導緻的非自願上下文切換。