【原理】 程序排程演算法
程序排程的原理:
- 需要程序排程的理由很簡單,即充分利用計算機系統中的CPU資源,讓計算機系統能夠多快好省地完成我們讓它做的各種任務。為此,可在記憶體中可存放數目遠大於計算機系統內CPU個數的程序,讓這些程序在作業系統的程序排程器的排程下,能夠讓程序高效(高的吞吐量–throughput)、及時(低延遲–latency)、公平(fairness)地使用CPU。為此排程器可設計不同的排程演算法來選擇程序,這體現了程序排程的策略,同時還需並進一步通過程序的上下文切換(context switch)來完成程序切換,這體現了程序排程的機制。總體上說,我們需要何時排程(排程的時機)、是否能夠在核心執行的任意位置進行排程(排程的方式)、如果完成程序切換(上下文切換)、如果選擇“合適”的程序執行(排程策略/排程演算法)、如果評價選擇的合理性(程序排程的指標)。瞭解上述細節,也就可以說是瞭解了程序排程。
程序排程的指標:
不同的程序排程演算法具有不同的特徵,為此需要建立衡量一個演算法的基本指標。一般而言,衡量和比較各種程序排程演算法效能的主要因素如下所示:
CPU利用率:CPU是計算機系統中的稀缺資源,所以應在有具體任務的情況下儘可能使CPU保持忙,從而使得CPU資源利用率最高。
吞吐量:CPU執行時的工作量大小是以每單位時間所完成的程序數目來描述的,即稱為吞吐量。
週轉時間:指從程序建立到作程序結束所經過的時間,這期間包括了由於各種因素(比如等待I/O操作完成)導致的程序阻塞,處於就緒態並在就緒佇列中排隊,在處理機上執行所花時間的總和。
等待時間:即程序在就緒佇列中等待所花的時間總和。因此衡量一個排程演算法的簡單方法就是統計程序在就緒佇列上的等待時間。
響應時間:指從事件(比如產生了一次時鐘中斷事件)產生到程序或系統作出響應所經過的時間。在互動式桌面計算機系統中,使用者希望響應時間越快越好,但這常常要以犧牲吞吐量為代價。
這些指標其實是相互有衝突的,響應時間短也就意味著在相關事件產生後,作業系統需要迅速進行程序切換,讓對應的程序儘快響應產生的事件,從而導致程序排程與切換的開銷增大,這會降低系統的吞吐量。
程序排程的時機:
程序排程發生的時機(也稱為排程點)與程序的狀態變化有直接的關係。回顧程序狀態變化圖,我們可以看到程序排程的時機直接與程序在執行態<–>退出態/就緒態/阻塞態的轉變時機相關。簡而言之,引起程序排程的時機可歸結為以下幾類:
正在執行的程序執行完畢,需要選擇新的就緒程序執行。
正在執行的程序呼叫相關係統呼叫(包括與I/O操作,同步互斥操作等相關的系統呼叫)導致需等待某事件發生或等待資源可用,從而將白己阻塞起來進入阻塞狀態。
正在執行的程序主動呼叫放棄CPU的系統呼叫,導致自己的狀態為就緒態,且把自己重新放到就緒佇列中。
等待事件發生或資源可用的程序等待佇列,從而導致程序從阻塞態回到就緒態,並可參與到排程中。
正在執行的程序的時間片已經用完,致自己的狀態為就緒態,且把自己重新放到就緒佇列中。
在執行完系統呼叫後準備返回使用者程序前的時刻,可排程選擇一新使用者程序執行
就緒佇列中某程序的優先順序變得高於當前執行程序的優先順序,從而也將引發程序排程。
程序排程的方式:
這裡需要注意,存在兩種程序搶佔處理器的排程方式:
可搶佔式(可剝奪式,preemptive):就緒佇列中一旦有某程序的優先順序高於當前正在執行的程序的優先順序時,作業系統便立即進行程序排程,完成程序切換。
不可搶佔式(不可剝奪式non_preemptive):即使在就緒佇列存在有某程序優先順序高於當前正在執行的程序的優先順序時,當前程序仍將佔用處理機執行,直到該程序自己進入阻塞狀態,或時間片用完,或在執行完系統呼叫後準備返回使用者程序前的時刻,才重新發生排程讓出處理機。
程序排程的策略/演算法:
- 在早期作業系統的排程方式大多數是非剝奪的,這是由於早期的應用一般是科學計算或事務處理,不太把人機互動的響應時間指標放在首要位置。在這種情況下,正在執行的程序可一直佔用CPU直到程序阻塞或終止。這種方式的排程演算法可以很簡單,且比較適用對於響應時間不關心或者關心甚少的批處理科學計算或事務處理應用。隨著計算機的應用領域進一步擴充套件,計算機更多地用在了多媒體等人機互動應用上,為此採用可搶佔式的排程方式可在一個程序終止或阻塞之前就剝奪其執行權,把CPU儘快分配給另外的“更重要”程序,使得就緒佇列中的程序有機會響應它們使用者的IO事件。基於這兩種方式的排程演算法如下:
1、先來先服務(FCFS)排程演算法:處於就緒態的程序按先後順序鏈入到就緒佇列中,而FCFS排程演算法按就緒程序進入就緒佇列的先後次序選擇當前最先進入就緒佇列的程序來執行,直到此程序阻塞或結束,才進行下一次的程序選擇排程。FCFS排程演算法採用的是不可搶佔的排程方式,一旦一個程序佔有處理機,就一直執行下去,直到該程序完成其工作,或因等待某一事件而不能繼續執行時,才釋放處理機。作業系統如果採用這種程序排程方式,則一個執行時間長且正在執行的程序會使很多晚到的且執行時間短的程序的等待時間過長。
2、短作業優先(SJF)排程演算法:其實目前作業的提法越來越少,我們姑且把“作業”用“程序”來替換,改稱為短程序優先排程演算法,此演算法選擇就緒佇列中確切(或估計)執行時間最短的程序進入執行。它既可採用可搶佔排程方式,也可採用不可搶佔排程方式。可搶佔的短程序優先排程演算法通常也叫做最短剩餘時間優先(Shortest Remaining Time First,SRTF)排程演算法。短程序優先排程演算法能有效地縮短程序的平均週轉時間,提高系統的吞吐量,但不利於長程序的執行。而且如果程序的執行時間是“估計”出來的話,會導致由於估計的執行時間不一定準確,而不能實際做到短作業優先。
3、時間片輪轉(RR)排程演算法:RR 排程演算法與FCFS 排程演算法在選擇程序上類似,但在排程的時機選擇上不同。RR排程演算法定義了一個的時間單元,稱為時間片(或時間量)。一個時間片通常在1~100 ms之間。當正在執行的程序用完了時間片後,即使此程序還要執行,作業系統也不讓它繼續執行,而是從就緒佇列依次選擇下一個處於就緒態的程序執行,而被剝奪CPU使用的程序返回到就緒佇列的末尾,等待再次被排程。時間片的大小可調整,如果時間片大到讓一個程序足以完成其全部工作,這種演算法就退化為FCFS排程演算法;若時間片設定得很小,那麼處理機在程序之間的程序上下文切換工作過於頻繁,使得真正用於執行使用者程式的時間減少。時間片可以靜態設定好,也可根據系統當前負載狀況和執行情況動態調整,時間片大小的動態調整需要考慮就緒態程序個數、程序上下文切換開銷、系統吞吐量、系統響應時間等多方面因素。
4、高響應比優先(Highest Response Ratio First,HRRF)排程演算法:HRRF排程演算法是介於先來先服務演算法與最短程序優先演算法之間的一種折中演算法。先來先服務演算法只考慮程序的等待時間而忽視了程序的執行時間,而最短程序優先排程演算法只考慮使用者估計的程序的執行時間而忽視了就緒程序的等待時間。HRRF排程演算法二者兼顧,既考慮程序等待時間,又考慮程序的執行時間,為此定義了響應比(Rp)這個指標:
- Rp=(等待時間+預計執行時間)/執行時間=響應時間/執行時間-
上個表示式假設等待時間與預計執行時間之和等於響應時間。HRRF排程演算法將選擇Rp最大值的程序執行,這樣既照顧了短程序又不使長程序的等待時間過長,改進了排程效能。但HRRF排程演算法需要每次計算各各個程序的響應比Rp,這會帶來較大的時間開銷(特別是在就緒程序個數多的情況下)。
5、多級反饋佇列(Multi-Level Feedback Queue)排程演算法:在採用多級反饋佇列排程演算法的執行邏輯流程如下:
設定多個就緒佇列,併為各個佇列賦予不同的優先順序。第一個佇列的優先順序最高,第二隊次之,其餘佇列優先順序依次降低。僅當第1~i-1個佇列均為空時,作業系統排程器才會排程第i個佇列中的程序執行。賦予各個佇列中程序執行時間片的大小也各不相同。在優先順序越高的佇列中,每個程序的執行時間片就越小或越大(Linux-2.4核心就是採用這種方式)。
當一個就緒程序需要鏈入就緒佇列時,作業系統首先將它放入第一佇列的末尾,按FCFS的原則排隊等待排程。若輪到該程序執行且在一個時間片結束時尚未完成,則作業系統排程器便將該程序轉入第二佇列的末尾,再同樣按先來先服務原則等待排程執行。如此下去,當一個長程序從第一佇列降到最後一個佇列後,在最後一個佇列中,可使用FCFS或RR排程演算法來執行處於此佇列中的程序。
如果處理機正在第i(i > 1)佇列中為某程序服務時,又有新程序進入第k(k < i)的佇列,則新程序將搶佔正在執行程序的處理機,即由排程程式把正在執行程序放回第i佇列末尾,重新將處理機分配給處於第k佇列的新程序。
從MLFQ排程演算法可以看出長程序無法長期佔用處理機,且系統的響應時間會縮短,吞吐量也不錯(前提是沒有頻繁的短程序)。所以MLFQ排程演算法是一種合適不同型別應用特徵的綜合程序排程演算法。
6、最高優先順序優先排程演算法:程序的優先順序用於表示程序的重要性及執行的優先性。一個程序的優先順序可分為兩種:靜態優先順序和動態優先順序。
靜態優先順序是在建立程序時確定的。一旦確定後,在整個程序執行期間不再改變。靜態優先順序一般由使用者依據包括程序的型別、程序所使用的資源、程序的估計執行時間等因素來設定。一般而言,若程序需要的資源越多、估計執行的時間越長,則程序的優先順序越低;反之,對於I/O bounded的程序可以把優先順序設定得高。
動態優先順序是指在程序執行過程中,根據程序執行情況的變化來調整優先順序。動態優先順序一般根據程序佔有CPU時間的長短、程序等待CPU時間的長短等因素確定。佔有處理機的時間越長,則優先順序越低,等待時間越長,優先順序越高。那麼程序排程器將根據靜態優先順序和動態優先順序的總和現在優先順序最高的就緒程序執行。
作業系統中為了能夠讓每個程序都有機會執行,需要給每個程序分配一個時間片,當一個程序的時間片用完以後,作業系統的排程器就會讓當前程序放棄CPU,而選擇另外一個程序佔用CPU執行。為了有效地支援程序排程所需的時間片,ucore設計並實現了一個timer(計時器)功能。這樣,通過timer就對基於時間事件的排程機制提供了基本支援。