複製鏈接
請複製以下鏈接發送給好友

上下文切換

鎖定
上下文切換指的是內核(操作系統的核心)在CPU上對進程或者線程進行切換。上下文切換過程中的信息被保存在進程控制塊(PCB-Process Control Block)中。PCB又被稱作切換幀(SwitchFrame)。上下文切換的信息會一直被保存在CPU的內存中,直到被再次使用。 [1] 
中文名
上下文切換
外文名
Context Switch [1] 
性    質
任務切換, 或者CPU寄存器切換 [2] 

上下文切換相關信息

上下文切換 (context switch) , 其實際含義是任務切換, 或者CPU寄存器切換。當多任務內核決定運行另外的任務時, 它保存正在運行任務的當前狀態, 也就是CPU寄存器中的全部內容。這些內容被保存在任務自己的堆棧中, 入棧工作完成後就把下一個將要運行的任務的當前狀況從該任務的棧中重新裝入CPU寄存器, 並開始下一個任務的運行, 這一過程就是context switch。 [2] 
圖1 上下文切換 圖1 上下文切換 [2]
每個任務都是整個應用的一部分, 都被賦予一定的優先級, 有自己的一套CPU寄存器和棧空間, 如圖1所示。 [2] 

上下文切換基本原理

上下文切換的基本原理就是當發生任務切換時, 保存當前任務的寄存器到內存中, 將下一個即將要切換過來的任務的寄存器狀態恢復到當前CPU寄存器中, 使其繼續執行, 同一時刻只允許一個任務獨享寄存器。在任務切換的過程中是涉及任務上下文的保存和恢復操作, 而任務上下文切換操作的性能是衡量操作系統性能的一個重要指標。任務上下文切換指標可以反映出操作系統在多任務環境下的處理能力。 [3] 

上下文切換切換流程

上下文的切換流程如下 [1] 
(1)掛起一個進程,將這個進程在CPU中的狀態(上下文信息)存儲於內存的PCB中。 [1] 
(2)在PCB中檢索下一個進程的上下文並將其在CPU的寄存器中恢復。 [1] 
(3)跳轉到程序計數器所指向的位置(即跳轉到進程被中斷時的代碼行)並恢復該進程。 [1] 
時間片輪轉方式使多個任務在同一CPU上的執行有了可能,具體過程如圖2所示。 [1] 
圖2 上下文切換 圖2 上下文切換 [1]

上下文切換引起線程上下文切換的原因

引起線程上下文切換的原因如下 [1] 
(1)當前正在執行的任務完成,系統的CPU正常調度下一個任務。
(2)當前正在執行的任務遇到I/O等阻塞操作,調度器掛起此任務,繼續調度下一個任務。
(3)多個任務併發搶佔鎖資源,當前任務沒有搶到鎖資源,被調度器掛起,繼續調度下一個任務。
(4)用户的代碼掛起當前任務,比如線程執行yield()方法,讓出CPU。
(5)硬件中斷。 [1] 

上下文切換上下文切換開銷

上下文切換是操作系統內核優化的一個關鍵參數指標。在任務間發生切換需要花費大量的時間用於處理諸如:保存和恢復寄存器和內存頁表、更新內核相關數據結構等操作。上下文切換通常是計算密集型的。也就是説, 它需要相當可觀的處理器時間, 在每秒幾十上百次的切換中, 每次切換都需要納秒量級的時間。所以, 上下文切換對系統來説意味着消耗大量的CPU時間。 [4] 
從Linux內核內部實現來看, 如圖3所示, 上下文切換所花費的延遲時間是從調度器選好要調度的任務 (任務1) 後到把任務上下文切換到另一個任務 (任務2) 所花費的時間。即context_switch () 函數的開銷。 [4] 
圖3 上下文切換 圖3 上下文切換 [4]

上下文切換性能影響

上下文切換會對性能造成負面影響。一些上下文切換相對其他切換而言更加昂貴;其中一個更昂貴的上下文切換是跨核上下文切換(Cross-Core Context Switch)。一個線程可以運行在一個專用處理器上,也可以跨處理器。由單個處理器服務的線程都有處理器關聯(Processor Affinity),這樣會更加有效。在另一個處理器內核搶佔和調度線程會引起緩存丟失,作為緩存丟失和過度上下文切換的結果要訪問本地內存。總之,這稱為“跨核上下文切換”。 [5] 
參考資料