KVM的vCPU算法和Xen的Credit算法對比

KVM的vCPU調度算法的原理

KVM的vCPU的整個生命週期都在Qemu線程的上下文中,在Kernel(root模式)、User(root模式)、Guest(non-root模式)下互相切換。其中每個vCPU對應一個Qemu線程,直接使用內核中的調度器進行調度,有以下三種調度器:

  • O(N)調度器
  • O(1)調度器
  • CFS調度器

O(N)調度器

O(N)調度器的思想是每個進程創建時都會初始化改進程的可執行時間片數counter,每次時鐘中斷counter–,當counter爲0時就會換出CPU,然後重新遍歷runqueue(存儲當前所有的running進程),取出動態優先級最高且有時間片的進程進行調度。由於採用輪詢的方式,所以複雜度爲O(N),因此也叫O(N)調度器。但存在性能和擴展性低、特殊情況等待時間長、不支持實時進程等缺點。

O(1)調度器

O(1)調度器利用了兩個隊列,Active和Expired,Active用於活動任務(存放有時間片的進程),Expired用於過期任務(存放時間片用完的),每個隊列有140個槽位,對應0-139優先級。對應靜態優先級的進程加入對應的槽位,再加上每個隊列配一個bitmap,就可以通過O(1)找到當前數據中優先級最高的進程。但是O(1)調度器在交互式程序的時候出現了很多卡頓,其根本原因可能是用歸類的方法去分析線性分佈的事物。

CFS調度器

CFS調度器(Comletely Fair Scheduler)主要思想是維護爲進程提供處理器時間方面的平衡。每個進程有自己的虛擬時間,其增長速度與進程權重成反比,進程權重對應於進程的優先級。也就說低優先級任務具有更高的衰減係數,高優先級任務具有較低的衰減係數。這意味着與高優先級任務相比,低優先級任務執行的時間消耗地更快。這就避免了維護按優先級調度的運行隊列。與之前的linux調度器不同,CFS調度器沒有將進程維護在運行隊列中,而是維護一個以時間爲順序的紅黑樹。CFS調度器爲每個CPU分配一個按虛擬時間從小到大排序的紅黑樹的結構。紅黑樹最左邊的節點的虛擬時間最小,最右邊的虛擬時間越大。每次調度,從左側將虛擬時間最小的進程來運行,運行完之後,如果還處於就緒態,則插回樹中。

CFS調度器還有組調度的概念。這是爲了處理產生很多其他進程的進程的情況,而引入的一種調度公平的方法。產生進程的進程在整個組中共享它們的虛擬運行時間,而單個進程維持其獨立的虛擬運行時間。這樣單個任務會受到與組大致相同的調度時間。

Xen Credit算法的原理

Xen的vCPU調度算法有BVT(Borrowed Virtual Time)算法、SEDF(Simple Earliest Deadline First)、Credit算法。其中Credit算法是其默認的調度算法。

Credit調度算法是一種按比例公平共享的非搶佔式調度算法,類似記賬的情景。Credit算法爲每一個Domain U設置了兩個參數:

  • weight : 表示Domain的權重,即能佔用物理CPU的時間比例。
  • CAP:表示Domain可佔用的最多物理CPU的比例。、

算法的流程:

  1. 根據物理CPU個數計算總信用值
  2. 根據Domain的權重和vCPU個數計算應獲得的信用值,取信用值和cap中較小的作爲Domain的信用值
  3. 再將Domain的信用值平均分到這個Domain裏的vCPU去
  4. 映射到每個物理CPU的vCPU會加入該物理CPU的運行隊列按優先級進行調度

其中物理CPU的隊列中的優先級分爲四個(課堂只說了3個,這裏補充一個),按優先級從低到高排序如下:

  • IDLE:僅空閒時佔位
  • OVER:消耗完Credit值,並且無法被調度
  • UNDER:按照隊列中的先後順序週期性地被調度
  • BOOST:最高優先級的臨時狀態,最多持續10ms
  1. 當一個運行隊列空閒時,會從其他運行隊列尋找非IDLE的vCPU遷移調度

CFS算法與Credit算法比較

算法實現

CFS算法是將進程存在紅黑樹的每個節點中,利用紅黑樹這個數據結構本身的特性來實現進程調度。同時引入了虛擬時間這個概念,將進程的優先級以線性分佈來表示。

Credit算法中,每個物理CPU上都有一個調度隊列。隊列中是各個Domain的vCPU,根據信用值具有四種不同的狀態來表示其優先級。

虛擬機兼容性

CFS算法在與計算型負載虛擬機共存的環境下,會導致 I/O 型負載虛擬機的I/O 性能受損。因爲紅黑樹根據虛擬時間排序,而運行I/O 負載的進程被喚醒時所獲得的虛擬時間往往不足以搶佔當前運行的進程。另外,多處理器虛擬機可能引發鎖佔用的問題,由於vCPU 是否正在持有鎖對調度器是不可見的,如果一個正在持有自旋鎖的vCPU 進入休眠,正在等待這個自旋鎖的其他vCPU,則會因此需要等待更長的時間。

Credit算法全局管理多個物理CPU,從而將CPU時間公平高效地分配給各個虛擬CPU。另外可以通過調節guest操作系統的cap參數很好地實現Non-working-Conserving(NWC)調度模式,使得管理員可以很容易控制物理CPU的分配情況。

個人理解這是因爲CFS算法設計之初就是爲了在原生linux內核中運行,KVM直接使用內核的調度器會存在一定的兼容性不好的問題是很正常的。因爲原生linux和KVM在架構上還是差別比較大。而Credit算法是基於虛擬化的目的設計出來的,在虛擬機上會比CFS算法更穩定一些。

實時性

CFS算法使用虛擬時間進行排序,避免了維護優先級的運行隊列,從而也避免了某類本不應該是高優先級的進程長期佔據物理CPU的情況。因此,長期得不到運行的進程就會在紅黑樹的最左側節點,從而下次被系統用來調度運行。

Credit算法不能保證實時性,響應速度要求較高的應用中,事件響應延遲與其所處的隊列位置密切相關,響應延遲 普遍較長且波動明顯。具體來說,當系統運行響應敏感類應用時,I/O事件如網絡、磁盤IO的任務會使得進程處於Boost狀態,如果允許重新調度,則該進程會被馬上調度。但如果出現多個處於Boost狀態的進程,就無法體現Boost狀態優先級高的優勢,等待處理的事件仍然長時間得不到響應。因此,Credit算法不擅長處理I/O密集型應用。

參考資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章