CPU調度


CPU調度

    引入了線程,對於支持它們的操作系統,是內核級的線程被操作系統調度,而不是進程。不過,術語線程調度進程調度常常被交替使用。在討論普通調度概念時使用進程調度,特別指定為線程概念時使用線程調度。

基本概念

CPU-I/O區間周期

    CPU的成功調度依賴於進程的如下屬性:進程執行由CPU執行和I/O等待周期組成。進程在這兩個狀態之間切換。進程執行從CPU區間(CPU burst)開始,在這之后是I/O區間(I/O burst),接着是另一個CPU區間,然后是另一個I/O區間,如此進行下去。

CPU調度程序

    每當CPU空閑時,操作就必須從就緒隊列中選擇一個進程來執行。進程選擇由短期調度程序(short-term scheduler)或CPU調度程序執行。調度程序從內核中選擇一個能夠執行的進程,並為之分配CPU。就緒隊列不必是先進先出(FIFO)隊列。就緒隊列可實現為FIFO隊列,優先隊列,樹或簡單的無序鏈表。不過從概念上來說,就緒隊列內的所有進程都要排隊以等待在CPU上運行。隊列中的記錄通常為進程控制塊(PCB)。

搶占調度

CPU調度決策可在如下4種環境下發生:

  • 當一個進程從運行狀態切換到等待狀態(例如,I/O請求,或調用wait等待一個子進程的終止)。
  • 當一個進程從運行狀態切換到就緒狀態(例如,當出現中斷時)
  • 當一個進程從等待狀態切換到就緒狀態(例如,I/O完成)
  • 當一個進程終止

對於第1和第4兩種情況,沒有選擇而只有調度。一個新進程(如果就緒隊列中已有一個進程存在)必須被選擇執行。不過,對於第2和第3兩種情況,可以進行選擇。

    當調度只能發生在第1和第4兩種情況下時,稱調度方案是非搶占的(nonpreemptive)的或協作的(cooperative);否則,稱調度方案是搶占的(preemptive)。采用非搶占調度,一旦CPU分配給一個進程,那么該進程會一直使用CPU知道進程終止或切換到等待狀態。

    中斷能隨時發生,而且不能總是被內核所忽視,所以受中斷影響的代碼段必須加以保護以避免同時訪問。為了這些代碼段不被多個進程同時訪問,在進入時要禁止中斷,而在退出時要重新允許中斷。

分派程序

與CPU調度功能有關的另一個部分是分派程序(dispatcher)。分派程序是一個模塊,用來將CPU的控制交給由短期調度程序選擇的進程。其功能包括:

  • 切換上下文
  • 切換到用戶模式
  • 跳轉到用戶程序的合適位置,以重新啟動程序

分派程序應盡可能快,因為在每次進程切換時都要使用。分派程序停止一個進程而啟動另一個所要花的時間稱為分派延遲(dispatch latency)。

調度准則

    不同的CPU調度算法具有不同的屬性,且可能對某些進程更為有利。為了比較CPU調度算法,分析員提出了許多准則,這些准則包括如下:

CPU使用率:需要使CPU盡可能忙。從概念上講,CPU使用率0%-100%。對於真實系統,它應從40%(輕負荷系統)~90%(重負荷系統)

吞吐量:如果CPU忙於執行進程,那么就有工作在完成。一種測量工作量的方法稱為吞吐量,它指一個時間單元內所完成進程的數量。對於長進程,吞吐量可能為每小時一個進程;對於短進程,吞吐量可能為每秒10個進程。

周轉時間:從一個特定進程的角度來看,一個重要准則是運行該進程需要多長時間。從進程提交到進程完成的時間稱為周轉時間。周轉時間為所有時間段之和,包括等待進入內存,在就緒隊列中等待,在CPU上執行和I/O執行。

等待時間:CPU調度算法並不影響進程運行和執行I/O的時間;它只影響進程在就緒隊列中等待所花的時間。等待時間為在就緒隊列中等待所花費時間之和。

響應時間:對於交互系統,周轉時間並不是最佳准則。通常,進程能相當早就產生輸出,並繼續計算新結果同時輸出以前的結果給用戶。因此,另一時間是從提交請求道產生第一響應的時間。這種時間稱為響應時間,是從開始響應所需的時間,而不是輸出響應所需要的時間。周轉時間通常受輸出設備速度的限制。

    需要使CPU使用率和吞吐量最大化,而使周轉時間、等待時間和響應時間最小化。在絕大多數情況下,需要優化平均值。不過在有的情況下,需要優化最小值或最大值,而不是平均值。例如,為了保證所有用戶都得到好的服務,可能需要使最大響應時間最小。

調度算法

CPU調度處理是從就緒隊列中選擇進程並為之分配CPU的問題。

先到先服務調度

    顯然,最簡單的CPU調度算法是先到先服務調度算法(first-come,first-served (FCFS) Scheduling algorithm)。采用FCFS策略的平均等待時間通常不是最小的,且如果進程CPU區間時間變化很大,平均等待時間也會變化很大。

    FCFS調度算法是非搶占的。一旦CPU被分配給了一個進程,該進程會保持CPU直到釋放CPU為止,即程序終止或是請求I/O。FCFS算法對於分時系統(每個用戶需要定時地得到一定的CPU時間)是特別麻煩的。允許一個進程保持CPU時間過長將是個嚴重錯誤。

最短作業優先調度

    另一種CPU調度方法是最短作業優先調度算法(shortest-job-first(SJF)schedulingalgorithm)。這一算法將每個進程與其下一個CPU區間段相關聯。當CPU為空閑時,它會賦給具有最短CPU區間的進程。如果兩個進程具有相同長度,那么可以使用FCFS調度來處理。一個更為適當的表示是最短下一個CPU區間的算法,這是因為調度檢查進程的下一個CPU區間的長度,而不是其總長度。

    SJF調度算法可證明為最佳的,這是因為對於給定的一組進程,SJF算法的平均等待時間最小。通過將最短進程移到長進程之前,短進程等待時間的減少大於長進程等待時間的增加。因而,平均等待時間減少了。

    SJF算法的真正困難是如何知道下一個CPU區間的長度。對於批處理系統的長期(作業)調度,可以將用戶提交作業時所指定的進程時間極限作為長度。SJF調度經常用於長期調度。

    雖然SJF算法最佳,但是它不能在短期CPU調度層次上加以實現。因為沒有辦法知道下一個CPU區間的長度。一種方法是近似SJF調度。雖然不知道下一個CPU區間的長度,但是可以預測它。認為下一個CPU區間的長度與以前的相似。因此,通過計算下一個CPU區間長度近似值,能選擇具有最短預測CPU區間的進程來進行。

    下一個CPU區間通常可以預測為以前CPU區間的測量長度的指數平均。設為第n個CPU區間的長度,設為下一個CPU區間的預測值。因此,對於a, 0a≤1,定義

 

公式定義了一個指數平均。存儲了過去歷史,值包括最近信息。參數a控制了最近和過去歷史在預測中的相對加權。如果a=0,那么近來歷史沒有影響;如果a=1,只有最近的CPU區間才重要。下圖說明了一個指數平均值,其中a=1/2, =10

由於a和(1-a)小於或等於1,所以后面項的權比前面項的權要小。

    SJF算法可能是搶占或非搶占的。當一個新進程到達就緒隊列而以前進程正在執行時,就需要選擇。與當前運行的進程相對,新進程可能有一個更短的CPU區間。搶占SJF算法可搶占當前運行的進程,而非搶占SJF算法會允許當前運行的進程先完成其CPU區間。搶占SJF調度有時稱為最短剩余時間優先調度(shortest-remaining-time-first scheduling)。

優先級調度

    SJF算法可作為通用優先級調度算法(priority scheduling algorithm)的一個特例。每個進程都有一個優先級與其關聯,具有最高優先級的進程會分配到CPU。具有相同優先級的進程按FCFS順序調度。SJF算法屬於簡單優先級算法,其優先級(p)為下一個(預測的)CPU區間的倒數。CPU區間越大,則優先級越小,反之亦然。

    優先級調度可通過內部或外部方式來定義。內部定義優先級使用一些測量數據以計算進程優先級。例如,時間極限,內存要求,打開文件的數量和平均I/O區間與平均CPU區間之比都可以用於計算優先級。外部優先級是通過操作系統之外的准則來定義的,如進程重要性,用於支付使用計算機的費用類型和數量,贊助工作的單位,其他因素。

    優先級調度可以是搶占或者非搶占的。當一個進程到達就緒隊列時,其有優先級與當前運行進程的優先級相比較。如果新到達進程的優先級高於當前運行進程的優先級,那么搶占優先級調度算法會搶占CPU。而非搶占優先級調度算法只是將新進程加到就緒隊列的頭部。

    優先級調度算法的一個主要問題是無窮阻塞(indefinite blocking)或飢餓(starvation)。

可以運行但缺乏CPU的進程可認為是阻塞的,它在等待CPU。優先級調度算法會使某個低優先級進程無窮等待CPU。通常,會發生兩種情況,要么進程最終能運行,在系統最后為輕負荷時,要么系統最終崩潰並失去所有未完成的低優先級進程。

    低優先級進程無窮等待問題的解決之一是老化(aging)。老化是一種技術,以逐漸增加在系統中等待很長世間的進程的優先級。

輪轉法調度

輪轉法(round-robin,RR)調度算法是專門為分時系統設計的。它類似於FCFS調度,但是增加了搶占以切換進程。定義了一個較小時間單元,稱為時間片(time quantum,or time slice)。時間片通常為10-100ms。將就緒隊列作為循環隊列。CPU調度程序循環就緒隊列,為每個進程分配一個時間片的CPU。

    為了實現RR調度,將就緒隊列保存為進程的FIFO隊列。新進程增加到就緒隊列的尾部。CPU調度程序從就緒隊列中選擇第一個進程,設置定時器在一個時間片之后中斷,再分派該進程。

    接下來將可能發生兩種情況。進程可能只需要小於時間片的CPU區間。對於這種情況,進程本身自動釋放CPU。調度程序接着處理就緒隊列的下一個進程。否則,如果當前運行進程的CPU區間比時間片長,定時器會中斷並產生操作系統中斷,然后進程上下文切換,將進程加入到就緒隊列的尾部,接着CPU調度程序會選擇就緒隊列中的下一個進程。

    對於RR調度算法,隊列中沒有進程被分配超過一個時間片的CPU時間(除非它是唯一可運行的進程)。如果進程的CPU區間超過一個時間片,那么該進程會被搶占,而被放回到就緒隊列。RR調度算法是可搶占的。

    RR算法的性能很大程序上依賴於時間片的大小。在極端的情況下,如果時間片非常大,那么RR算法與FCFS算法一樣。如果時間片很小,那么RR算法稱為處理器共享,n個進程對於用戶都有它自己的處理器,速度為真正處理器的1/n。

    周轉時間隨着時間片的大小而改變:

多級隊列調度

多級隊列調度算法(multilevel queue scheduling algorithm)將就緒隊列分成多個獨立隊列。根據進程的屬性,如內存大小、進程優先級、進程類型,一個進程被永久地分配到一個隊列中。每個隊列都有自己的調度算法。例如,前台進程和后台進程可處於不同隊列。前台隊列可能采用RR算法調度,而后台隊列可能采用FCFS算法調度。

    另外,隊列之間必須有調度,通常采用固定優先級搶占調度。每個隊列與更低層隊列相對有絕對優先級。例如,只有系統進程、交互進程和交互編輯進程隊列都為空,批處理隊列內的進程才可運行。如果在一個批處理進程運行時有一個交互進程進入就緒隊列,那么該批處理進程會被搶占。

    另一種可能是在隊列之間划分時間片。每個隊列都有一定的CPU時間,這可用於調度隊列內的進程。例如,對於前台-后台隊列的例子,前台隊列可以有80%的CPU時間用於在進程之間進行RR調度,而后台隊列可以有20%的CPU時間采用FCFS算法調度進程。

多級反饋隊列調度

通常在使用多級隊列調度算法時,進程進入系統時被永久地分配到一個隊列。例如,如果前台進程和后台進程分別有獨立隊列,進程並不從隊列轉移到另一個隊列,這是因為進程並不改變前台或后台性質。這種設置的優點是低調度開銷,缺點是不夠靈活。

    與之相反多級反饋隊列調度算法(multilevel feedback queue scheduling algorithm)允許進程在隊列之間移動。主要思想是根據不同CPU區間的特點以區分進程。如果進程使用過多的CPU時間,那么它會被轉移到更低優先級隊列。這種方案將I/O約束和交互進程留在更高優先級隊列。此外,在較低優先級隊列中等待時間過長的進程會被轉移到更高優先級隊列。這種形式的老化阻止了飢餓的發生。

通常,多級反饋隊列調度程序可由下列參數來定義:

  1. 隊列數量
  2. 每個隊列的調度算法
  3. 用以確定何時升級到更高優先級隊列的方法
  4. 用以確定何時降級到更低優先級隊列的方法
  5. 用以確定進程在需要服務時應進入哪個隊列的方法

多級反饋隊列調度程序的定義使它成為最普通的CPU調度算法。它可被配置以適應特定系統設計。不幸的是,由於需要一些方法來選擇參數以定義最佳的調度程序,它也是最復雜的算法。

多處理器調度

    如果有多個CPU,則負載分配(load sharing)成為可能,但調度問題也相應地變得更為復雜。

多處理器調度的方法

    在一個多處理器中,CPU調度的一種方法是讓一個處理器(主服務器)處理所有的調度決定、I/O處理以及其他系統活動,其他的處理器只執行用戶代碼。這種非對稱多處理器(asymmetric multiprocessing)方法更為簡單,因為只有一個處理器訪問系統數據結構,減輕了數據共享的需要。

    另一種方法是使用對稱多處理器(symmetric multiprocessing,SMP)方法,即每個處理器自我調度。所有進程可能處於一個共同的就緒隊列中,或每個處理器都有它自己的私有就緒進程隊列。

處理器親和性

    由於使緩存無效或重新構建的代價高,絕大多數SMP系統避免將進程從一個處理器移至另一個處理器,而是努力使一個進程在同一處理器上運行,這被稱為處理器親和性。

    處理器親和性有幾種形式。當一個操作系統具有設法讓一個進程保持在同一處理器上運行的策略,但不做任何保證時,則會出現軟親和性(soft affinity)。此時,進程進程可能在處理器之間移動。有些系統,如Linux,還提供一個支持硬親和性(hard affinity)的系統調用,從而允許進程指定它不允許移至其他處理器上。

負載平衡

負載平衡(load balancing)設法將工作負載平均地分配到SMP系統中的所有處理器上。負載平衡通常只是對那些擁有自己私有的可執行進程的處理器而言是必要的。在具有共同隊列的系統中,通常不需要負載平衡,因為一旦處理器空閑,它立刻從共同隊列中取走一個可執行進程。但同樣值得注意的是,在絕大多數支持SMP的當代操作系統中,每個處理器都有一個可執行進程的私有隊列。

負載平衡通常有兩種方法:push migration和pull migration。對於push migration,一個特定的任務周期性地檢查每個處理器上的負載,如果發現不平衡,即通過將進程從超載處理器移到(或推送到)空閑或不太忙的處理器,從而平均地分配負載。當空閑處理器從一個忙的處理器上pull一個等待任務時,發送pull migration。push migration 和 pull migration不能相互排斥,

對稱多線程

    通過提供多個物理其,SMP系統允許同時運行幾個線程。另一種方法是提供多個邏輯(而不是物理)處理器來實現。這種方法被稱為對稱多線程(SMT)。在Intel處理器中,它被稱為超線程(hyperthreading)技術。

    SMT的思想是在同一個物理處理器上生成多個邏輯處理器,向操作系統呈現一個多邏輯處理器的視圖,即使系統僅有單處理器。每個邏輯處理器都有它自己的架構狀態,包括通用目的和機器狀態寄存器。進一步講,每個邏輯處理器負責自己的中斷處理,這意味着中斷被送到並被邏輯處理器所處理,而不是物理處理器。

    SMT是硬件而不是軟件提供的。硬件應該提供每個邏輯處理器的架構狀態的表示以及中斷處理方法。

線程調度

    對於支持線程的操作系統而言,體統調度的是內核線程,而不是用戶線程。用戶線程由線程庫管理,內核並不了解它們。為了能在CPU上運行,用戶線程最終必須映射到相應的內核線程,盡管這種映射可能是間接的,可能使用輕量級進程(LWP)。

競爭范圍

    用戶線程與內核線程的區別之一在於它們是如何被調度的。在執行多對一模型多對多模型的系統上,線程庫調度用戶級線程到一個有效的LWP上運行,這被稱為進程競爭范圍(process-contention scope,PCS)方法,因為CPU競爭發生在屬於相同進程的線程之間。當提及線程庫調度用戶線程到有效的LWP時,並不意味着線程實際上就在CPU上運行,這需要操作系統將內核線程調度到物理CPU上。為了決定調度哪個內核線程到CPU,內核采用系統競爭范圍(system-contention scope,SCS)方法來進行。采用SCS調度方法,競爭CPU發生在系統的所有線程中,采用一對一的模型的系統,調度僅使用SCS方法。

    PCS是根據優先級完成的----調度程序選擇具有最高優先級的可運行的線程來運行。用戶線程優先級由程序員給定,並且不被線程庫調節,盡管有些線程庫允許程序員改變線程的優先級。

小結

CPU調度的任務是從就緒隊列中選擇一個等待進程,並為其分配CPU。CPU由調度程序分配給所選中的進程。

    先到先服務(FCFS)調度室最簡單的調度算法,但是它會讓短進程等待非常長的進程。最短作業優先(SJF)調度可證明是最佳的,它提供了最短平均等待時間。實現SJF調度比較困難,因為預測下一個CPU區間的長度有難度。SJF算法是通過優先級調度算法(將CPU簡單地分配給具有最高優先級的進程)的特例。優先級和SJF調度會產生飢餓。老化技術可以阻止飢餓。

    輪轉法(RR)調度對於分時(交互)系統更為合適。RR調度讓就緒隊列的第一個進程使用CPU的q個時間單元,這里q是時間片。在q時間單元之后,如果該進程還沒有釋放CPU,那么它被搶占並放到就緒隊列的尾部。該算法的主要問題是選擇時間片。如果時間片太大,那么RR調度就成了FCFS調度;如果時間片太小,那么因為上下文切換而引起的調度開銷就過大。

    FCFS算法是非搶占的,而RR算法是搶占的。SJF和優先級算法可以是搶占的,也可以是非搶占的。

    多級隊列調度算法允許多個不同算法用於各種類型的進程。最為常用的模型包括使用RR調度的前后台交互隊列,以及使用FCFS調度的后台批處理隊列。多級反饋隊列調度算法允許進程在隊列之間遷移。

    許多當前的計算機系統支持多處理器,並允許多個處理器獨立地調度它自己。通常,每個處理器維護自己的私有進程(或線程)隊列,它們都可以運行。與多處理器調度相關的問題包括多處理器親和性和負載平衡。

    如果操作系統在內核級支持線程,那么必須調度線程而不是進程來執行。Linux進程調度也使用基於優先級算法,並提供實時支持。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM