1. 程式人生 > 其它 >(轉載)虛擬化(3):os排程策略。

(轉載)虛擬化(3):os排程策略。

轉自:https://zhuanlan.zhihu.com/p/38046313

這一章主要是介紹幾個簡單的排程器策略。內容比較簡單,就簡單彙總下。

首先我們對現有的計算機環境有如下幾個假設:

1.每個job都執行相同的時間。

2.所有的job都同時準備好執行

3.一旦一個job啟動,那麼他就會一直執行到結束。

4.所有的job都不會有I/O

5.每個job執行的時間都是可知的。

我們先引入一個效率的測量值:turnaround time

Tturnaround =Tcompletion −Tarrival
也就是任務完成時間點減去任務到達記憶體可以執行的時間點

一個測量反應時間的:

Tresponse =Tfirstrun −Tarrival


也就是任務第一次開始執行的時間點減去任務到達的時間點。

首先第一個策略是先入先出(First In, First Out (FIFO)),就是誰先到誰先執行。

這個是一個例子,有三個任務A,B,C,我們計算對應的turnaround time為10+20+30/3=30但是如果執行時間長的任務先到,那麼turnaround time就會很高,比如這個例子,

因為任務A執行時間太長,導致turnaround time為100+110+120/3=110。因此引入了下一個策略:短任務先執行(Shortest Job First (SJF))。這樣會減少turnaround time。但是如果我們放開所有任務同時到達的假設,如果是長任務先來那麼就還是有問題,因此引入下一個策略:執行時間短的先執行(Shortest Time-to-Completion First (STCF))。但是如果執行時間不確定那還是有問題,進一步引入了新的策略:迴圈執行(Round Robin)。這種策略不是讓一個任務從開始執行一直到結束,而是將任務劃分為固定時間的一個一個時間片,然後順序執行,

這樣對應的response time會比較好,但是turnaround time會很糟糕,可以從上面的2個對比中看出來。另外RR的這種方式還會帶來任務間切換的消耗變多。而且如果程序中有I/O的時候,會導致很大的時間浪費,因此就引出了下個章節的內容:多級反饋佇列(multi-level feedback queue);

1.MLFQ的的規則

我們會有一些佇列,不同的佇列對應不同的優先順序.對於佇列中的程序,排程的規則如下:

(1)如果Priority(A) > Priority(B),那麼A執行。

(2)如果Priority(A) = Priority(B),那麼A,B按照Round-Robin方式執行。

(3)當一個任務創立的是時候,它在最高的優先順序中

(4a)如果一個任務執行的時候消耗了整個時間片,那麼降低優先順序

(4b)如果一個任務主動放棄cpu的執行時間,那麼保持優先順序不變

上面的規則所構成的排程規則,會有如下的問題:

(1)如果有很多的job是互動性的,那麼會導致那些需要大量cpu時間的job無法執行

(2)不公平性。如果有些job寫的時候故意在時間片的最後一點時間放棄cpu,那麼他就可以一直保持一個高優先順序的狀態。

(3)上面的規則只規定了job的優先順序下降,但是如果一個job 從耗費cpu變為了互動性,它的優先順序也是沒辦法提高的。

所以對上面的規則又新增了一些規則:

(5)經過一個時間S後,將所有的任務都調整到許可權最高的佇列。

(6)對規則4a和4b進行修改,一個job使用完該等級上的時間後,就會降低它的優先順序。

上面的這些規則中包含了很多的設定內容,比如佇列的個數,時間片的時間,調整所有低優先順序job的時間,每個佇列對應的時間為多少等等,這些都是具體在實現MLFQ的時候需要考慮的,一個好的建議是這些數值能夠可配置化,避免寫死。

上面介紹的排程策略在多核的時代還能不能適用呢?

首先什麼是多核,就是因為單核的速度無法提升,所以只能以增加核心的方式來提升cpu 的速度。而且需要注意的是每個核心都有對應的快取,所以這個會導致快取不一致的情況。另外還需要考慮的就是併發的問題,這個可以通過加鎖機制來完成。另外對於多核來說,會帶來一個新的問題,那就是快取關聯性(Cache Affinity)。也就是說,如果一個程序如果能夠一直執行在一個核上,那麼就可以利用快取記憶體來提高執行的效率,反之執行速度就會低下。

對於多核的OS排程機制,可以有兩種方案,一種是單個排程佇列(SQMS:single queue multiprocessor scheduling),一種是每個核一個排程佇列(multi-queue multiprocessor scheduling (or MQMS))。

SQMS的優勢在於能夠簡單,能夠直接應用之前的排程程式碼。弊端也顯而易見,首先是效率的問題,因為一個隊列表示需要大量的鎖操作來實現對資料的正確訪問。其次快取關聯性問題也很突出,不過也有一些解決方案,比如固定一些程序只在某個核上跑,另外的則在多個核之前輪轉的執行。

MQMS對於每個核都有一個排程的佇列,這保證了擴充套件性,併發不是公用鎖,所以效率也得到提升。但是會牽扯出負載均衡的問題。首先是怎麼決定新生成的程序應該屬於哪個佇列,其次是如果核之間的任務數量失衡,怎麼補救。第一個問題我們用啟發式的方法決定,第二個可以使用程序在佇列間的移動。再來個問題,每個核如何發現其他核的情況呢,那麼肯定就需要去訪問對應核的核心資料結構,這個頻率不應該太高,也不應該太低,具體的就需要在實現的時候考慮了。所以實際的策略實現中,都需要大量的trade-off,因為在實際的場景中,沒有一個最優的答案,有的只是不斷探索然後將方案做到儘可能好。

最後對於linux來說,對多核是有多個排程器策略的。O(1), CFS , BFS,這個就不做介紹了。