cpu上下文切換
? 我們經常說的平均負載和cpu公升高沒有直接的關係,在不同的場景cpu公升高會導致系統負載,但是系統負載不一定是cpu公升高導致的。
一、系統負載過高的三種場景
cpu密集型程序,使用大量cpu會導致平均負載公升高,此時這兩者是一致的。
io密集型程序,等待io也會導致平均負載公升高,但cpu不一定很高。
大量等待cpu的程序排程也會導致平均負載公升高,此時cpu使用率也會比較高。
? 大量程序競爭cpu(也就是上面的第三個場景),往往是被忽略的,cpu雖然沒有使用,只是在競爭,也會發生負載嗎?
? 我們都知道linux是乙個多工作業系統,它支援遠大於cpu數量的任務同時執行,當然這些任務不是同時執行,而是系統在很短時間內,將cpu輪流分配給它們,造成多工同時執行的錯覺。而每個任務執行前,cpu需要知道任務從**載入、又從**開始執行,也就是說,需要系統事先幫它設定好cpu暫存器和程式計數器。
二、cpu暫存器和程式計數器
1. cpu暫存器:
? cpu內建的容量小、但速度極快的記憶體。
2. 程式計數器:
? 是用來儲存cpu正在執行的指令位置、或者即將執行的下一條指令位置。他們都是cpu在執行任何任務前,必須的依賴環境,因此也被叫做cpu上下文。
3. cpu上下文切換
? cpu上下文切換:就是先前乙個任務的cpu上下文(也就是cpu暫存器和程式計數器)儲存起來,然後載入新任務的上下文到這些暫存器和程式計數器,最後再跳轉到程式計數器所指的新位置,執行新任務。
? 而這些儲存下來的上下文,會儲存在系統核心中,並在任務重新排程執行時再次載入進來。這樣就保證原來任務的狀態不受影響,讓任務看起來還是連續執行。
? 根據任務不同,cpu的上下文切換就可以分為不同的幾個場景,程序上下文切換,執行緒上下文切換以及中斷上下文切換。
3.1. 程序上下文切換
? linux安裝特權等級,把程序的執行空間分為核心空間和使用者空間
!核心空間(ring0)具有最高許可權,可以直接訪問所有資源;
使用者空間(ring3)只能訪問受限許可權,不能直接訪問記憶體等硬體裝置,必須通過系統呼叫陷入到核心中,才能訪問特權資源。
? 所以,程序既可以在使用者空間執行又可以在核心空間執行,在使用者空間執行時,稱為使用者態。在核心空間執行時,稱為核心態。
3.1.1. 系統呼叫是否發生cpu上下文切換
系統呼叫:cpu暫存器裡面原來的使用者態的指令位置,需要先儲存起來。接著,為了執行核心態**,cpu暫存器需要更新為核心態指令的新位置。最後,才跳轉到核心態執行核心任務。
系統呼叫結束後:cpu暫存器需要恢復原來儲存的使用者態,然後再切換到使用者空間,繼續執行程序。所以,一次系統呼叫,其實傳送了兩次cpu上下文切換。
系統呼叫過程中,並不會涉及到虛擬記憶體等程序使用者態的資源,也不會切換程序。所以,系統呼叫通常稱為特權模式切換,但實際上,系統呼叫也無法避免cpu上下文切換。
3.1.2. 程序上下文切換跟系統呼叫區別
? 程序是由核心來管理和排程的,程序的切換只能發生在核心態,所以,程序的上下文不僅包括了使用者態的虛擬記憶體,使用者棧,全域性變數等資源。還包括了核心棧、暫存器等核心空間的狀態。
? 因此,程序的切換比系統呼叫多了一步:在儲存當前程序的核心狀態和cpu暫存器之前,需要先把使用者態的虛擬記憶體,使用者棧儲存下來;在載入了下一程序的核心態後,需要重新整理程序的虛擬核心和使用者棧。
? 儲存上下文和恢復上下文的程序並不是免費的,需要內存在cpu上執行才能完成。
? 每次上下文切換都需要幾十納秒到微妙的cpu時間。這個時間還是相當可觀。在程序上下文切換次數較多的情況下,很容易導致cpu將大量時間耗費在暫存器、核心棧以及虛擬記憶體等資源的儲存和恢復上,進而大大縮短了真正執行程序的時間。這也是導致平均負載公升高的重要因素。
? linux通過(tlb)來管理虛擬記憶體和物理記憶體直接的對映關係,當虛擬記憶體更新後,tlb也要更新,記憶體訪問隨之變慢。特別是在多處理器系統上,快取被多個處理器共享,重新整理快取不僅影響當預處理器的程序,還會影響共享快取的其他處理器的程序。
3.1.3. 程序什麼時候切換
? 程序執行完終止了,會釋放cpu,這個時候cpu從就緒佇列裡面拿乙個新的程序執行,還有其他的一些非正常場景也會導致程序切換。
時間片耗盡:為了保證所以程序可以得到公平排程,cpu時間被劃分成一段段的時間片,這些時間片輪流分配給各個程序。當某個時間片耗盡了,就會被系統掛起,切換到其他等待cpu的程序執行。
系統資源不足(如:記憶體不足):這個時候程序會被掛起,並由系統排程其他程序執行。
程序主動掛起: 當程序通過睡眠函式sleep這樣的方式將自己主動掛起時。
高優先順序程序:當有優先順序高的程序出現時,為了保證優先順序高的程序執行,當前程序會被系統掛起
硬體中斷時:當發生硬體中斷時,cpu上的程序會被中斷掛起,轉而執行核心中的中斷服務程式。
3.2. 執行緒上下文切換
? 執行緒和程序最大的區別在於,執行緒是排程的基本單位,而程序則是資源擁有的基本單位。所謂核心中的任務排程,實際上的排程物件是執行緒;而程序只是給執行緒提供了虛擬記憶體、全域性變數等資源。所以,對於執行緒和程序可以理解為:
當程序只有乙個執行緒時,可以任務程序就是執行緒。
當程序擁有多個執行緒時,這些執行緒共享相同的虛擬記憶體、全域性變數等資源。這些資源在上下文切換時是不需要修改的。
另外,執行緒也有自己的私有資料,如:棧和暫存器等,這些在上下文切換時也是需要儲存的。
? 所以說:
? 當兩個執行緒不屬於同一程序時,執行緒上下文切換時。因為資源不共享,所以切換就相當於時程序間切換。
? 當兩個執行緒屬於同一程序時,執行緒上下文切換時。因為資源共享,只需要切換執行緒私有資料。
? 程序間切換消耗的資源多於執行緒間切換,所以就出現了多執行緒代替多程序的優勢。
3.3. 中斷上下文切換
? 為了快速響應硬體的事件,中斷處理會打斷程序的正常排程和執行,轉而呼叫中斷處理程式,響應裝置事件。在打斷其他程序時,就需要將程序當前狀態儲存起來。
? 跟程序上下文切換不同是,中斷上下文切換不會涉及到程序的使用者態。所以,即便中斷過程打斷了乙個使用者態的程序,也不需要儲存和恢復程序的虛擬記憶體。全域性變數等使用者態資源。中斷上下文,其實只包括核心態中斷服務程式執行必須的狀態,包括cpu暫存器、核心堆疊、硬體中斷引數等。
? 對同乙個cup來說,中斷處理比程序擁有更高的優先順序,所以中斷上下文切換並不會與程序上線文切換同時發生。所以大部分中斷處理程式都短小精悍,以便盡快的執行結束。
? 總結
cpu上下文切換,時保持linux系統正常執行的核心功能之一,一般情況不需要我們特別關注。
過多的上下文切換,會把cpu時間消耗在暫存器、核心棧以及虛擬記憶體等資料的儲存和恢復上,從而縮短了進**正執行的時間,導致系統效能下降。
02 CPU上下文切換(上)
cpu上下文切換是什麼意思 上 1.cpu上下文 我們都知道,linux 是乙個多工作業系統,它支援遠大於 cpu 數量的任務同時執行。當然,這些任務實際上並不是真的在同時執行,而是因為系統在很短的時間內,將 cpu 輪流分配給它們,造成多工同時執行的錯覺。而在每個任務執行前,cpu 都需要知道任務...
CPU上下文切換
linux任務執行前,cpu都要知道從任務從 載入 又從 開始執行,也就是說,需要系統事先幫它設定好cpu暫存器和程式計數器 cpu上下文 cpu暫存器和程式計數器 cpu暫存器 cpu內建容量小 速度極快的記憶體 程式計數器 儲存cpu正在執行的指令位置 或者即將執行的下一條指令位置 把前乙個任務...
CPU 上下文切換
乙個酒店,裡面滿滿的客人在吃飯,好比是,酒店裡面的所有人速速離開酒店,讓下一波客人吃。好比是 酒店裡的客人不需要離開酒店,但是服務員就是不給他們上菜,因為服務員去給 vip 客戶服務去了,好在 vip 客戶比較好說話,很快就伺候好了,服務員再來給酒店裡的客人服務 不好意思,這道菜的工序比較複雜,讓您...