本文從 Linux 2.4 調度系統的缺陷入手,詳細分析了 Linux 2.6 調度系統的原理和實現細節,並對與調度系統相關的Server Load Balancer、NUMA 結構以及即時效能進行了分析和評價。文末,作者從調度系統的發展和實現出發,對 Linux 的發展特點和方向提出了自己的看法。
1.前言
Linux 的市場非常廣闊,從案頭工作站到低端伺服器,它都是任何商用作業系統的有力競爭者。目前,Linux 正全力進軍嵌入式系統和高端伺服器系統領域,但它的技術缺陷限制了它的競爭力:缺乏對即時任務的支援,多處理機可擴充性差。在 2.4 核心中,造成這兩個弱項的關鍵原因之一就是調度器設計上的缺陷。
2.6 調度系統從設計之初就把開發重點放在更好滿足即時性和多處理機並行性上,並且基本實現了它的設計目標。主要設計者,傳奇式人物 Ingo Molnar 將新調度系統的特性概括為如下幾點:
繼承和發揚 2.4 版調度器的特點:
互動式作業優先
輕載條件下調度/喚醒的高效能
公平共用
基於優先順序調度
高 CPU 使用率
SMP 高效親和
即時調度和 cpu 綁定等調度手段
在此基礎之上的新特性:
O(1)調度演算法,調度器開銷恒定(與當前系統負載無關),即時效能更好
高可擴充性,鎖粒度大幅度減小
新設計的 SMP 親和方法
最佳化計算密集型的批次工作的調度
重載條件下調度器工作更平滑
子進程先於父進程運行等其他改進
在 2.5.x 的實驗版本中,新的調度器的開發一直受到廣泛關注,實測證明它的確使系統效能得到很大改善。本文就從新設計的資料結構開始,圍繞 2.6 對於 2.4 所作的改進,對 2.6 調度系統的原理和實現細節進行分析。2.6 調度器設計相當複雜,文中還存在很多需要繼續研究的地方,特別是各個調度參數的設定,隨著核心版本的升級,可能還會繼續修正。
2.新的資料結構runqueue
我們知道,在 2.4 核心中,就緒進程隊列是一個全域資料結構,調度器對它的所有操作都會因全域自旋鎖而導致系統各個處理機之間的等待,使得就緒隊列成為一個明顯的瓶頸。
2.4 的就緒隊列是一個簡單的以 runqueue_head 為頭的雙向鏈表,在 2.6 中,就緒隊列定義為一個複雜得多的資料結構 struct runqueue,並且,尤為關鍵的是,每一個 CPU 都將維護一個自己的就緒隊列,--這將大大減小競爭。
O(1)演算法中很多關鍵技術都與 runqueue 有關,所以,我們對調度器的分析就先從 runqueue 結構開始。