1. 程式人生 > >作業系統概念學習筆記 10 CPU排程

作業系統概念學習筆記 10 CPU排程

作業系統概念學習筆記 10

CPU排程


多道程式作業系統的基礎。通過在程序之間切換CPU,作業系統可以提高計算機的吞吐率。

對於單處理器系統,每次只允許一個程序執行:任何其他程序必須等待,直到CPU空閒能被排程為止。

多道程式的目標是在任何時候都有某些程序在執行,以使CPU的使用率最大化。多道程式的思想較為簡單,當一個程序必須等待時,作業系統會從該程序拿走CPU的使用權,而將CPU交給其他程序。

CPU-I/O 區間週期

CPU的成功排程依賴於程序的如下屬性:

程序執行由CPU執行週期I/O等待週期組成。程序在這兩個狀態之間切換(CPU burst—I/O bust)

程序執行從CPU區間(CPU burst)開始,在這之後是I/O區間(I/O burst)。接著另外一個CPU區間,然後是另外一個I/O區間,如此進行下去,最終,最後的CPU區間通過系統請求中止執行。

這裡寫圖片描述

經過大量CPU區間的長度的測試。發現具有大量短CPU區間和少量長CPU區間。I/O約束程式通常具有很多短CPU區間。CPU約束程式可能有少量的長CPU區間。這種分佈有助於選擇合適的CPU排程演算法。

CPU程式排程

每當CPU空閒時,作業系統就必須從就緒佇列中選擇一個程序來執行。程序選擇由短期排程程式(short-term scheduler)CPU排程程式執行。排程程式從記憶體中選擇一個能夠執行的程序,併為之分配CPU。

就緒佇列不必是先進先出(FIFO)佇列,也可為優先佇列、樹或簡單的無序連結串列。不過佇列中所有的程序都要排隊以等待在CPU上執行。佇列中的記錄通常為程序控制塊(PCB)。

搶佔排程:

CPU排程決策可在如下4種情況環境下發生:

(1)當一個程序從執行切換到等待狀態(如:I/O請求,或者呼叫wait等待一個子程序的終止)

(2)當一個程序從執行狀態切換到就緒狀態(如:出現中斷)

(3)當一個程序從等待狀態切換到就緒狀態(如:I/O完成)

(4)當一個程序終止時

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

當排程只能發生在第1和4兩種情況下時,稱排程是非搶佔的(nonpreemptive)協作的(cooperative);否則,稱排程方案為搶佔的(preemptive)

。採用非搶佔排程,一旦CPU分配給一個程序,那麼該程序會一直使用CPU直到程序終止或切換到等待狀態。

搶佔排程對方問共享資料是有代價(如加鎖)的,需要新的機制來協調對共享資料的訪問。

搶佔對於作業系統核心的設計也有影響。在處理系統呼叫時,核心可能忙於程序活動。這些活動可能涉及要改變重要核心資料(如I/O佇列)。  

因為根據定義中斷能隨時發生,而且不能總是被核心所忽視,所以受中斷影響的程式碼段必須加以保護以避免同時訪問。作業系統需要在任何時候都能夠接收中斷,否則輸入會丟失或輸出會被改寫。為了這些程式碼段不被多個程序同時訪問,在進入時就要禁止中斷,而在退出時要重新允許中斷。

分派程式

分派程式(dispatch)是一個模組,用來將CPU的控制交給由短期排程程式選擇的程序。

其功能包括:

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

分派程式停止一個程序而啟動另一個所花的時間成為分派延遲(dispatch latency)。

排程準則

為了比較CPU排程演算法所提出的準則:

  • CPU使用率 : 需要使CPU儘可能忙

  • 吞吐量 : 指一個時間單元內所完成程序的數量

  • 週轉時間 : 從程序提交到程序完成的時間段稱為週轉時間,週轉時間是所有時間段之和,包括等待進入記憶體、在就緒佇列中等待、在CPU上執行和I/O執行

  • 等待時間 : 在就緒佇列中等待所花費時間之和

  • 響應時間 : 從提交請求到產生第一響應的時間

需要使CPU使用率和吞吐量最大化,而使週轉時間、等待時間和響應時間最小化。絕大多數情況下需要優化平均值,有時需要優化最大值或最小值,而不是平均值。

排程演算法

先到先服務排程

最簡單的CPU排程演算法是先到先服務演算法(First-Come,First-Served scheduling):先請求CPU的程序先分配到CPU。FCFS策略可以用FIFO佇列來容易實現。當一個程序進入就緒佇列,其PCB連結到佇列的尾部。當CPU空閒時,CPU分配給位於佇列頭的程序,接著執行程序從佇列中刪除。

FCFS策略的程式碼編寫簡單且容易理解,不過採用FCFS策略的平均等待時間通常比較長。當程序CPU區間時間變化很大,平均等待時間會變化很大。

比如以下例子

程序 區間時間
P1 24
P2 3
P3 3

如果按照P1 P2 P3 順序到達,Gantt圖如下:

這裡寫圖片描述

平均等待時間:(0+24+27)/3 = 17

如果按P2 P3 P1 順序到達,

平均等待時間:(0+3+6)/3 = 3

另外考慮在動態情況下的效能,假設有一個CPU約束程序和許多I/O約束程序,CPU約束程序會移回到就緒佇列並被分配到CPU。再次所有I/O程序會在就緒佇列中等待CPU程序的完成。由於所有其他程序都等待一個大程序釋放CPU,這稱之為護航效果(convoy effect)。與讓較短程序最先執行相比,這樣會導致CPU和裝置使用率變的很低。

FCFS排程演算法是非搶佔的。對於分時系統(每個使用者需要定時的等待一定的CPU時間)是特別麻煩。允許一個程序保持CPU時間過長是個嚴重錯誤。

最短作業優先排程(shortest-job-first scheduling,SJF)

將每個程序與下一個CPU區間段相關聯。當CPU為空閒時,它會賦給具有最短CPU區間的程序。如果兩個程序具有同樣長度,那麼可以使用FCFS排程來處理。注意,一個更為適當地表示是最短下一個CPU區間的演算法,這是因為排程檢查程序的下一個CPU區間的長度,而不是其總長度。

比如以下例子

程序 區間時間
P1 6
P2 8
P3 7
P4 3

SJF: (0+3 + 9 + 16)/4 = 7

FCFS: (0+6+14+21)/4 = 10.25

SJF演算法的平均等待時間最小。SJF演算法的真正困難是如何知道下一個CPU區間的長度。對於批處理系統的長期(作業)排程,可以將使用者提交作業時間所制定的程序時間極限作為長度。SJF排程經常用於長期排程。

它不能在短期CPU排程層次上加以實現。我們可以預測下一個CPU區間。認為下一個CPU區間的長度與以前的相似。因此通過計算下一個CPU區間長度的近似值,能選擇具有最短預測CPU區間的程序來執行。下一個CPU區間通常可預測為以前CPU去剪的測量長度的指數平均(exponential average)

SJF演算法可能是搶佔的或非搶佔的。搶佔SJF演算法可搶佔當前執行的程序,而非搶佔的SJF演算法會允許當前的程序先完成其CPU區間。搶佔SJF排程有時稱為最短剩餘時間優先排程(shortest-remaining-time-first scheduling)

比如以下例子

程序 到達時間 區間時間
P1 0
P2 1
P3 2
P4 3

根據Gantt圖:

這裡寫圖片描述

平均等待時間:

(0+0+(5-3)+(10-1)+(17-2))/4 = 26/4 = 6.5

非搶佔SJF:

(0+(8-1)+(12-3)+(17-2))/4 = 7.75

優先順序排程(priority scheduling algorithm)

SJF演算法可作為通用的優先順序排程演算法的一個特例。每個程序都有一個優先順序與其關聯,具有最高優先順序的程序會分配到CPU。具有相同優先順序的程序按FCFS順序排程。SJF,其優先順序(p)為下一個CPU區間的倒數。CPU區間越大,則優先順序越小,反之亦然。

優先順序通常是固定區間的數字,如0~7,但是數字大小與優先順序的高低沒有定論。

對於下例,假設數字越小優先順序越高

程序 區間時間 優先順序
P1 10
P2 1
P3 2
P4 1
P5 5

平均等待時間為:

(0+1+6+16+18)/5 = 8.2

優先順序可通過內部或外部方式來定義。內部定義優先順序使用一些測量資料以計算程序優先順序。外部優先順序是通過作業系統之外的準則來定義,如程序重要性等。

優先順序排程可以是搶佔的或非搶佔的。

優先順序排程演算法的一個重要問題是無限阻塞(indefinite blocking)飢餓(starvation)。可以執行但缺乏CPU的程序可認為是阻塞的,它在等待CPU。優先順序排程演算法會使某個有低優先順序無窮等待CPU。

低優先順序程序務求等待問題的解決之一是老化(aging)。老化是一種技術,以逐漸增加在系統中等待很長時間的程序的優先順序。

輪轉法排程(round-robin,RR)

專門為分時系統設計。它類似於FCFS排程,但是增加了搶佔以切換程序。定義一個較小的時間單元,稱為時間片(time quantum,or time slice)。將就緒佇列作為迴圈佇列。CPU排程程式迴圈就緒佇列,為每個程序分配不超過一個時間片段的CPU。

新程序增加到就緒佇列的尾部。CPU排程程式從就緒佇列中選擇第一個程序,設定定時器在一個時間片之後中斷,再分派該程序。接下來將可能發生兩種情況。程序可能只需要小於時間片的CPU區間。對於這種情況,程序本身會自動釋放CPU。排程程式接著處理就緒佇列的下一個程序。否則,如果當前執行程序的CPU區間比時間片要長,定時器會中斷產生作業系統中斷,然後進行上下文切換,將程序加入到就緒佇列的尾部,接著CPU排程程式會選擇就緒佇列中的下一個程序。

RR策略的平均等待時間通常較長

比如以下例子,使用4ms時間片

程序 區間時間
P1 24
P2 3
P3 3

畫出Gantt圖:

這裡寫圖片描述

平均等待時間:

(0+4+7+(10-4))/3 = 5.66

如果就緒,那麼每個程序會得到1/n的CPU時間,其長度不超過q時間單元。每個程序必須等待CPU時間不會超過(n-1)q個時間單元,直到它的下一個時間片為止。

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

小的時間片會增加上下文切換的次數,因此,希望時間片比上下文切換時間長,事實上,絕大多數現代作業系統,上下文切換的時間僅佔時間片的一小部分。

週轉時間也依賴於時間片的大小。

多級佇列排程(Multilevel Queue Scheduling)

前臺(互動)程序和後臺(批處理)程序。這兩種不同各型別的程序具有不同響應時間要求,也有不同調度需要。與後臺程序相比,前臺程序要有更高(或外部定義)的優先順序。

多級佇列排程演算法將就緒佇列分成多個獨立佇列。根據程序的屬性,如記憶體大小等,一個程序被永久地分配到一個佇列(低排程開銷但是不夠靈活),每個佇列有自己的排程演算法。前臺佇列可能採用RR演算法排程,而後臺排程可能採用FCFS演算法排程。

另外,佇列之間必須有排程,通常採用固定優先順序搶佔排程,例如前臺佇列可以比後臺佇列具有絕對優先值。另一種可能在佇列之間劃分時間片例如,前臺佇列可以有80%的時間用於在程序之間進行RR排程,而後臺佇列可以有20%的CPU時間採用FCFS演算法排程程序。

多級反饋佇列排程(Multilevel Feedback-Queue Scheduling)

與多級佇列排程相反,多級反饋佇列排程允許程序在佇列之間移動。主要思想是根據不同CPU區間的特點以區分程序。如果程序使用過多CPU時間,那麼它可能被轉移到較低優先順序佇列。這種方案將I/O約束和互動程序留在更高優先順序佇列。此外,在較低優先順序佇列中等待時間過長的程序會被轉移到更高優先順序佇列。這種形式的老化組織飢餓的發生。

通常,多級反饋佇列排程程式可由下列引數來定義:

  • 佇列數量。
  • 每個佇列的排程演算法。
  • 用以確定何時升級到更高優先順序佇列的方法。
  • 用以確定何時降級到更低優先順序佇列的方法。
  • 用以確定程序在需要服務時應進入哪個佇列的方法。

多處理器排程(Multiple-Processor Scheduling)

如果多個CPU,則負載分配(load sharing)成為可能。其中主要討論處理器功能相同(或同構)的系統,可以將任何處理器用於執行佇列內的任何程序。

多處理器排程方法

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

另一種方法是使用對稱多處理(symmetric multiprocessing,SMP)方法,即每個處理器自我排程。所有程序可能處於一個共同的就緒佇列中,或每個處理器都有自己的私有就緒佇列。無論如何,排程通過每個處理器檢查共同就緒佇列並選擇一個程序來執行。如果多個處理器試圖訪問和更新一個共同資料結構,那麼每個處理器必須仔程式設計:必須確保兩個處理器不能選擇同一程序,且程序不會從佇列中丟失。

處理器親和性

程序移到其他處理器上時,被遷移的第一個處理器的快取中的內容必須為無效,而將要遷移的第二個處理器上的快取需重新構建。由於使快取無效或重構的代價高,因而SMP努力的使一個程序在同一個處理器上執行,這被稱為處理器親和性,即一個程序需有一種對其他執行所在的處理器的親和性。

處理器親和性的幾種形式:

  • 軟親和性(soft affinity,作業系統具有設法讓一個程序保持在同一個處理器上執行的策略,但不能做任何保證)

  • 硬親和性(hard affinity,允許程序指定它不允許移至其他處理器),如LINUX

負載平衡(load balancing)

負載平衡設法將工作負載平均地分配到SMP系統中的所有處理器上。通常只是對那些擁有自己私有的可執行的程序的處理器而言是必要的,在具有共同佇列的系統中,通常不需要負載平衡,因為一旦處理器空閒,會立刻從就緒佇列中取走一個可執行程序。

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

負載平衡會抵消處理器親和性。

對稱多執行緒

提供多個邏輯(而非物理的)處理器來執行幾個執行緒,稱為對稱多執行緒(SMT),或超執行緒(hyperthreading)技術。

SMT的思想是在同一個物理處理器上生成多個邏輯處理器,即使系統僅有單處理器,每個邏輯處理器都有它自己的架構狀態,包括通用目的和機器狀態暫存器。每個邏輯處理器負責自己的中斷處理,這意味著中斷被送到並被邏輯處理器所處理,每個邏輯處理器共享其物理處理器的資源,如快取或匯流排。

SMT是硬體而非軟體提供的。硬體應該提供每個邏輯處理器的架構狀態的表示以及中斷處理方法。排程程式首先設法把不同執行緒分別排程到每個物理處理器上,而不是排程到同一個物理處理器的不同邏輯處理器上。

執行緒排程

系統排程的是核心執行緒,而不是程序。使用者執行緒由執行緒庫管理,核心並不瞭解它們。使用者執行緒最終必須對映到相應的核心級執行緒,儘管這種對映可能是間接的,可能使用輕量級程序(LWP)。

競爭範圍

使用者執行緒和核心執行緒的區別之一是它們是如何被排程的。在執行多對一模型和多對多模型系統上,執行緒庫排程使用者級執行緒到一個有效的LWP上執行,這被稱為程序競爭範圍(process-contention scope,PCS)方法,因為CPU競爭發生在屬於相同程序的執行緒之間。為了決定排程哪個核心執行緒到CPU,核心採用系統競爭範圍(system-contention scope,SCS)方法來進行,競爭CPU發生在系統所有執行緒中,採用一對一的模型的系統,排程僅使用SCS方法。

PCS是根據優先順序完成的。