CPU上下文切換
CPU上下文切換包括程序上下文切換、執行緒上下文切換及中斷上下文切換,當任務進行io或發生時間片事件及發生中斷(如硬體讀取完成)時,就會進入核心態,發生CPU上下文切換。
- 程序上下文切換,程序的上下文資訊包括, 指向可執行檔案的指標, 棧, 記憶體(資料段和堆), 程序狀態, 優先順序, 程式I/O的狀態, 授予許可權, 排程資訊, 審計資訊, 有關資源的資訊(檔案描述符和讀/寫指標), 關事件和訊號的資訊, 暫存器組(棧指標, 指令計數器)等等,當發生程序切換時,這些儲存在暫存器或快取記憶體的資訊需要記錄到記憶體,以便下次恢復程序的執行。
- 執行緒上下文切換,同一個程序的執行緒切換,只需儲存執行緒獨有的資訊,比如棧和暫存器,而共享的虛擬記憶體和全域性變數則無需切換,因此切換開銷比程序小。
- 中斷上下文切換,中斷會打斷一個正常執行的程序而執行中斷處理程式,因為中斷處理程式是核心態程序,而不涉及到使用者態程序之間的切換,當被中斷的是使用者態程序時,不需儲存和恢復這個程序的虛擬記憶體和全域性變數,中斷上下文只包括中斷服務程式所需要的狀態,比如CPU暫存器、核心堆疊、硬體中斷等引數。
過多的上下文切換會導致將大量CPU時間浪費在暫存器、核心棧以及虛擬記憶體的儲存和恢復上,導致系統整體效能下降。可以用vmstat檢視系統的整體上下文切換情況,如下圖1,空閒系統的上下文切換次數cs(context switch)為100多,中斷次數in(interrupt)為100多,在執行態r(running or runable)的程序數為2,在阻塞態的程序數b為0。
圖1 空閒系統上下文切換和中斷情況
案例:我們用sysbench來模擬多執行緒頻繁上下文切換的場景,並用vmstat、pidstat和/proc/interrupts來分析定位具體的執行緒。
用sysbench模擬10個執行緒,執行300s來觀察執行緒切換的頻繁場景,如下圖2所示。
圖2 大量執行緒切換場景模擬
用vmstat檢視系統整體的上下文切換和中斷情況,如下圖3,可看到cs和in的數目和空閒的時候比增加了很多。
圖3 系統整體上下文切換情況
發現系統切換情況比較頻繁,可以用pidstat檢視具體切換比較頻繁的執行緒,命令:pidstat -w -t 1,含義如下,
-w Report task switching activity (kernels 2.6.23 and later only). The following values may be displayed:
cswch/s
Total number of voluntary context switches the task made per second. A voluntary context switch occurs when a task blocks because it requires a resource that is unavailable.
每秒自願上下文切換次數,如等待io等。
nvcswch/s
Total number of non voluntary context switches the task made per second. A involuntary context switch takes place when a task executes for the duration of its time slice and then is
forced to relinquish the processor.
每秒非自願上下文切換次數,如時間片用完切換。
-t展示具體的執行緒情況。
結果如下圖4所示,可以看到,切換頻繁的執行緒是sysbench
圖4 執行緒切換情況