導航:首頁 > 源碼編譯 > linuxio調度演算法

linuxio調度演算法

發布時間:2022-05-29 08:44:03

『壹』 linux調度演算法的核心思想是什麼

第一部分:實時調度演算法

什麼是實時系統,POSIX 1003.b作了這樣的定義:是指系統可以在有限響應時間內提供所需的服務級別。較可取被定義為由Donald喬利士的的:一個實時系統的程序的邏輯正確性不僅取決於計算的准確度,而且還對結果,如果系統時間的限制不能滿足將是一個系統錯誤發生。

基於實時系統的實時性要求的不同,可分為軟實時和硬實時兩種。硬實時系統是指系統必須確保,在最壞情況下的服務時間,截止日期為事件的響應時間是在任何情況下,必須滿足。如航天飛船的控制是這樣一個系統的現實。所有其他實時系統的特點,可以稱為軟實時系統。如果清除,軟實時系統是那些從統計學的角度來看,一個任務(在下面的討論中,我們將有任務和過程不作出區分),以確保系統的處理時間,可以得到事件可以處理的最後期限到來之前,違反的最後期限,並不會帶來一個致命的錯誤,如實時多媒體系統是一種軟實時系統。

一台電腦系統的CPU和其他資源進行有效的調度和管理,以提供實時操作系統的支持。的多任務的實時系統中,資源的調度和管理更復雜的。下面討論本文將從各種實時任務調度演算法的分類的角度來看,普通的Linux操作系統進程調度和各種實時Linux系統,然後研究,以支持實時特點,普通的Linux系統的改進。實時領域的一些問題,並總結了各種實時Linux的Linux操作系統,歸根到底是如何解決這些問題。

CPU的實時調度演算法的分類

多種實時操作系統的實時調度演算法可以分為以下三類Wang99] [Gopalan01]:基於優先順序調度演算法(優先順序驅動調度PD),基於在共享的CPU使用率調度演算法(分享驅動調度SD)的比例,以及基於時間的進程調度演算法(時間驅動調度TD),下面這三種調度演算法逐一介紹。

1.1

/>基於優先順序的調度演算法,基於優先順序的調度演算法,每個進程被分配一個優先順序,每次的進程調度程序,調度程序總是具有最高的調度優先順序的任務執行。根據不同的優先順序分配方法,基於優先順序的調度演算法可以分為以下兩種類型的Krishna01] [Wang99]:靜態優先順序調度演算法

該演算法得到這些系統中運行的所有進程都靜態分配一個優先順序。靜態優先順序分配的屬性的應用程序,如任務循環中的用戶優先順序,或其他預先確定的政策。 RM(速率單調)的調度演算法是一個典型的靜態優先順序的調度演算法,根據執行的任務的調度優先順序的周期的長度確定,那些具有小的執行周期的任務的優先順序較高。

動態優先順序調度演算法:

該演算法基於任務的資源需求動態地分配任務的優先順序,資源分配和調度的目的更大的靈活性。非實時系統,這種演算法有很多,如短作業優先順序調度演算法。任務的實時調度演算法,EDF演算法是使用最廣泛的動態優先順序調度演算法,該演算法根據他們的截止日期(截止日期)分配優先順序的就緒隊列中的每個任務,最近期限具有最高的優先順序。

1.2

基於優先順序調度演算法的調度演算法是簡單而有效的,但這種演算法的基礎上按比例份額是一個硬實時調度,許多的情況下,不適合使用此演算法:例如,軟實時應用,如實時多媒體會議系統。對於軟實時應用程序,共享資源調度演算法(SD演算法)的比例使用是更合適的。

比例共享調度演算法是指對CPU使用率的比例共享調度演算法,其基本思路是按照一定的權重(比率),需要一組調度安排任務,以使它們的權重成比例的執行時間。

要實現比例共享調度演算法[Nieh01]有兩種方法:第一種方法是調整的准備過程中出現的調度隊列隊第一頻率,並安排一線隊的過程中,執行第二種方法是連續調度進程就緒隊列中投產,但根據調整分配一個進程的運行時間片分配的權重。

比例共享調度演算法可以分為以下類別:循環賽,公平份額,公平排隊,的彩票調度方法,(彩票)。

比例共享調度演算法的一個問題是,它並沒有定義任何優先的概念,所有的任務都根據其應用的CPU資源的比例共享系統過載時,執行的所有任務將較慢比例。因此,為了確保該系統的實時過程中獲得一定量的CPU處理時間,一般採用的是動態權重的調整過程。

1.3。基於時間進程調度演算法的調度演算法

對於那些具有穩定,簡單的系統已知輸入,您可以使用時間驅動(驅動時間時間:TD)數據處理,它可以提供一個良好的預測。這種調度演算法本質上是一個設計定型的離線靜態調度方法。在系統的設計階段,所有處理的情況下,在明確的制度,每個任務切換的開始和結束的時間提前做出了明確的安排和設計。該演算法是適用於小型嵌入式系統,自動化控制系統,感測器和其他應用環境。

該演算法的優勢是良好的可預測性任務的執行,但最大的缺點是缺乏靈活性,而且會有一個任務需要執行,而CPU保持空閑。

一般的Linux系統CPU調度

一般的Linux系統支持實時和非實時兩種進程,實時進程與普通進程方面具有絕對的優先權。相應地,實時進程調度策略SCHED_FIFO或SCHED_RR,普通進程SCHED_OTHER調度策略。

每個任務調度演算法的實現在Linux四種調度參數,它們是rt_priority優先政策(尼斯),計數器。調度進程調度的基礎上,這四個參數。

SCHED_OTHER調度策略,調度程序總是會選擇優先順序+計數器的值進程調度的執行。從邏輯分析存在SCHED_OTHER調度策略調度處理來執行,其特徵在於,所述優先順序是一個固定的調度周期(歷元),在每個調度周期內的過程中的優先順序,計數器的值的大小的影響這一刻已經確定變數值的過程中被創建時,它代表了進程的優先順序,也代表數量的時間片,通過該方法可以得到在每個調度周期內,計數器是一個動態值,它反映了當前調度周期的過程中,剩餘的時間片。在每個調度周期的開始,分配給優先順序值計數器,那麼每一次進程被調度運行計數器的值?減少。當計數器的值是零,這個過程已經運行的時間片調度期內,不再參與調度周期進程調度。當所有的進程都用完了時間片調度期結束,然後一遍又一遍。此外,可以看出在Linux系統中的調度周期是不固定的,它的量是動態變化的,例如,在運行的進程的數目和它們的優先順序值?可以影響一個劃時代的長度。有一點值得注意的是,在2.4內核中,首要任務是不錯的替換兩個類似的作用。

按比例分擔的調度策略調度策略SCHED_OTHER可見的性質,它的這種設計方法,以確保進程調度的公平性 - 一個低優先順序進程,在每個時代也將得到他們的份額那些CPU的執行時間,此外,它也提供了不同的進程的優先順序,進程執行時間可以得到更多的具有高優先順序值。

對於實時的過程中,他們使用基於實時優先順序rt_priority的優先順序調度策略,但相同的實時優先順序的進程調度方法是根據不同的調度策略,

BR /> SCHED_FIFO:不同的進程,根據靜態優先順序排隊,然後在相同的優先順序隊列,先准備好運行的第一誰調度和運行的進程不會被終止,直到發生以下情況:1。高優先順序的進程篡奪了CPU;自己的資源請求受阻;自己主動放棄CPU(呼叫SCHED_YIELD);

SCHED_RR是這樣的:這個調度策略SCHED_FIFO與上述完全相同,除了時間片分配給每個進程,正在實施的過程中,給執行時間片,時間片的長度可以通過sched_rr_get_interval調用

由於Linux系統本身是一個桌面導向的系統,因此,它是用於在實時應用中的一些問題:/> /> Linux系統調度單位是10ms,所以它不能提供精確的定時中斷; p>當一個進程調用系統調用進入內核模式運行,它不能被搶占;

Linux內核實現大量採用了封閉中斷操作損失;

由於使用虛擬內存技術,當發生頁面錯誤時,從硬碟中讀取的數據交換的需要,但硬碟讀取和寫入的存儲位置的隨機性,將導致隨機讀取和寫入時間,這在某些情況下,會影響實時任務期限;

雖然Linux的進程調度器還支持實時優先順序,但由於缺乏有效的實時任務調度機制和調度演算法;其網路子協議處理和其它設備的中斷處理,調度伴有相應的過程和自己的有沒有明確的調度機制;

各種實時Linux系統
Home>的的

3.1 RT-Linux和RTAI

RT-Linux是新墨西哥大學的研究(新墨西哥州技術學院)[RTLinuxWeb] [Barabanov97。其基本思路是,在Linux系統上的硬實時支持,它實現了一個微內核實時操作系統(也被稱為RT-Linux的實時子系統),而普通的Linux系統作為一個低優先順序任務在操作系統中運行。在正常的Linux系統的另一個任務可以溝通,通過FIFO和實時任務。 RT-Linux的框架如圖1所示:

圖1 RT-Linux的結構

RT-Linux的關鍵技術是軟體模擬硬體中斷控制器。當Linux系統不時阻止CPU中斷,實時定量RT-Linux的子系統的請求攔截,愛不釋手,而事實上並沒有真正阻止硬體中斷,從而避免了由於中斷造成的封由系統在一段時間內沒有響應,從而在改進的實時。當傳遞給Linux內核的RT-Linux的一個硬體中斷到達截取的中斷,並確定是否有一個實時子系統中斷常式來處理或處理。此外,的最小定時的精度在正常的Linux系統是確定系統的實時時鍾的頻率,Linux的系統時鍾被設置到時鍾中斷每秒100,所以在Linux的系統定時的精度10毫秒,即時鍾周期10ms時,RT-Linux的實時時鍾設置為單觸發狀態,可以提供更多的十幾微秒調度粒度。

RT-Linux實時子系統的任務調度優先順序驅動演算法,RM,EDF等,也可用於其他調度演算法。

RT-Linux的專有系統,重型工作,的確是一個不錯的選擇,但他只提供了CPU資源的調度和實時系統和Linux系統的關系不是非常密切,因此開發人員可以充分利用已在Linux系統中,如協議棧實現的功能。 RT-Linux的工業控制等實時任務簡單和硬實時要求的環境,但大量的工作需要做,如果你想應用的多媒體處理。

義大利實時應用程序介面(RTAI)來自RT-Linux的,它是在設計和RT-Linux的思想相同。這是原來的設計中,為了解決問題,RT-Linux的不同版本的Linux之間很難很難移植,RTAI在Linux上定義的實時硬體抽象層,這個抽象層介面提供實時任務Linux系統的相互作用,這可以增加一點可以Linux內核源代碼到Linux內核的實時支持。

3.2。 KURT-Linux的

KURT-Linux的堪薩斯大學開發的,它可以提供實時微秒精度[KurtWeb] [斯里尼瓦桑]。與RT-Linux的單獨實現一個實時內核,KURT-Linux是常用的Linux系統的基礎上實現的,這也是第一個基於Linux的實時系統可以使用普通的Linux系統調用。

KURT-Linux系統分為三種狀態:正常狀態,實時狀態和混合狀態,在正常狀態下,它使用普通的Linux實時運行狀態實時調度策略任務,實時和非實時任務的混合狀態,可以執行實時狀態可以被用來為實時的要求更加嚴格。

為了提高Linux系統的實時特性,有必要提高精度的時鍾系統的支持。但是,如果只是簡單地增加時鍾頻率將導致調度負載的增加,從而嚴重降低系統的性能。為了解決這個矛盾,KURT-Linux中使用的時鍾精度的方法[UTIMEWeb]提高Linux系統UTIME,時鍾晶元設置為單次觸發狀態(單拍模式),也就是每個時鍾晶元設置超時,然後再次超時事件發生時,在時鍾中斷的處理程序所需的時鍾晶元設置一個超時。其基本思想是一個精確的時間意味著我們需要的時鍾中斷發生時,我們需要一個更精確的時間,以達到這樣的精度,但並不一定需要系統時鍾頻率。它採用了CPU時鍾計數器時間戳計數器(TSC)提供准確的CPU頻率精度的時間。

KURT-Linux的實時任務調度,使用靜態CPU的實時調度演算法,基於時間(TD)。實時任務需要實時事件發生在設計階段就必須清楚列明。該演算法可以實現更好的調度任務,對於那些誰周期。

KURT-Linux的相RT-Linux的優勢之一是,你可以使用系統調用的Linux系統,它最初是專為硬實時支持,但因為它是簡單的實現將使用一個簡單的時間驅動調度取代Linux的調度,實時進程調度的影響等非實時任務,在某些情況下會發生實時任務的截止日期是脆弱的不符合的,也被稱為嚴格的實時系統(快地實時)。基於KURT-Linux的應用程序:藝術(ATM參考交通系統),多媒體播放軟體。 KURT-Linux的另一種方法,需要頻繁的時鍾晶元編程

3.3。 RED-Linux的

RED-Linux是加州大學爾灣,實時Linux系統的發展[REDWeb] [Wang99],它將支持實時調度和Linux實現相同的操作系統內核。它支持三種類型的調度演算法,即:時間驅動優先Dirven,分享驅動。

為了提高系統的調度粒度,RED-Linux的學習RT-Linux的軟體模擬中斷的管理機制,並增加頻率的時鍾中斷。 RED-Linux的中斷模擬程序只是簡單地中斷會在隊列中排隊一個硬體中斷到來時,並沒有進行實際的中斷處理程序。

另外,為了解決Linux的內核模式的過程中不能被中斷,RED-Linux的插入Linux內核搶占點原語的眾多功能,使這一進程在內核模式下,也在一定程度上被搶占。通過這種方法提高了內核的實時特性。

RED-Linux的設計目標是提供常規調度框架可以支持多種調度演算法,系統為每個任務增加幾個屬性,進程調度的基礎上:

優先順序:作業的優先順序;

開始時間:工作的開始時間;

完成時間:工作的結束時間; BR p>預算:資源的數量在操作過程中要使用的工作;

調整值?這些屬性和調度根據什麼優先使用的這些屬性值幾乎所有的調度演算法。在這種情況下,三種不同的調度演算法無縫地一起耦合到一個統一的。

『貳』 Linux如何進行進程調度引入線程機制後,進程管理內容包括哪些

進程調度的演算法有很多,簡單來說就是每個進程都有一個自己的時間片,時間到了,就會被掛起,然後系統挑選下一個合適的進程來執行。至於誰合適,那就要看演算法了,優先順序,是不是飢餓,I/O型還是運算型,都要考慮的。
調度演算法比較復雜龐大,不是這里說的清楚的。
進程切換的過程大概就是保存當前上下文,也就是各種寄存器的狀態,包括指令寄存器。然後把下一個進程的上下文載入上來。
有了線程機制之後,進程管理主要管理線程之間的數據共享,管理進程地址空間,進程的交換空間。因為這些資源是屬於進程的,線程之間是共享的。
​現代操作系統調度基本是圍繞線程進行的,進程更多的是起到資源管理分配的作用。

『叄』 linux進程調度的三種策略是什麼

linux內核的三種主要調度策略:
1,SCHED_OTHER 分時調度策略,
2,SCHED_FIFO實時調度策略,先到先服務
3,SCHED_RR實時調度策略,時間片輪轉

實時進程將得到優先調用,實時進程根據實時優先順序決定調度權值。分時進程則通過nice和counter值決定權值,nice越小,counter越大,被調度的概率越大,也就是曾經使用了cpu最少的進程將會得到優先調度。

SHCED_RR和SCHED_FIFO的不同:
當採用SHCED_RR策略的進程的時間片用完,系統將重新分配時間片,並置於就緒隊列尾。放在隊列尾保證了所有具有相同優先順序的RR任務的調度公平。
SCHED_FIFO一旦佔用cpu則一直運行。一直運行直到有更高優先順序任務到達或自己放棄。
如果有相同優先順序的實時進程(根據優先順序計算的調度權值是一樣的)已經准備好,FIFO時必須等待該進程主動放棄後才可以運行這個優先順序相同的任務。而RR可以讓每個任務都執行一段時間。

相同點:
RR和FIFO都只用於實時任務。
創建時優先順序大於0(1-99)。
按照可搶占優先順序調度演算法進行。
就緒態的實時任務立即搶占非實時任務。

所有任務都採用linux分時調度策略時:
1,創建任務指定採用分時調度策略,並指定優先順序nice值(-20~19)。
2,將根據每個任務的nice值確定在cpu上的執行時間(counter)。
3,如果沒有等待資源,則將該任務加入到就緒隊列中。
4,調度程序遍歷就緒隊列中的任務,通過對每個任務動態優先順序的計算權值(counter+20-nice)結果,選擇計算結果最大的一個去運行,當這個時間片用完後(counter減至0)或者主動放棄cpu時,該任務將被放在就緒隊列末尾(時間片用完)或等待隊列(因等待資源而放棄cpu)中。
5,此時調度程序重復上面計算過程,轉到第4步。
6,當調度程序發現所有就緒任務計算所得的權值都為不大於0時,重復第2步。

所有任務都採用FIFO時:
1,創建進程時指定採用FIFO,並設置實時優先順序rt_priority(1-99)。
2,如果沒有等待資源,則將該任務加入到就緒隊列中。
3,調度程序遍歷就緒隊列,根據實時優先順序計算調度權值(1000+rt_priority),選擇權值最高的任務使用cpu,該FIFO任務將一直佔有cpu直到有優先順序更高的任務就緒(即使優先順序相同也不行)或者主動放棄(等待資源)。
4,調度程序發現有優先順序更高的任務到達(高優先順序任務可能被中斷或定時器任務喚醒,再或被當前運行的任務喚醒,等等),則調度程序立即在當前任務堆棧中保存當前cpu寄存器的所有數據,重新從高優先順序任務的堆棧中載入寄存器數據到cpu,此時高優先順序的任務開始運行。重復第3步。
5,如果當前任務因等待資源而主動放棄cpu使用權,則該任務將從就緒隊列中刪除,加入等待隊列,此時重復第3步。

所有任務都採用RR調度策略時:
1,創建任務時指定調度參數為RR,並設置任務的實時優先順序和nice值(nice值將會轉換為該任務的時間片的長度)。
2,如果沒有等待資源,則將該任務加入到就緒隊列中。
3,調度程序遍歷就緒隊列,根據實時優先順序計算調度權值(1000+rt_priority),選擇權值最高的任務使用cpu。
4,如果就緒隊列中的RR任務時間片為0,則會根據nice值設置該任務的時間片,同時將該任務放入就緒隊列的末尾。重復步驟3。
5,當前任務由於等待資源而主動退出cpu,則其加入等待隊列中。重復步驟3。

系統中既有分時調度,又有時間片輪轉調度和先進先出調度:
1,RR調度和FIFO調度的進程屬於實時進程,以分時調度的進程是非實時進程。
2,當實時進程准備就緒後,如果當前cpu正在運行非實時進程,則實時進程立即搶占非實時進程。
3,RR進程和FIFO進程都採用實時優先順序做為調度的權值標准,RR是FIFO的一個延伸。FIFO時,如果兩個進程的優先順序一樣,則這兩個優先順序一樣的進程具體執行哪一個是由其在隊列中的未知決定的,這樣導致一些不公正性(優先順序是一樣的,為什麼要讓你一直運行?),如果將兩個優先順序一樣的任務的調度策略都設為RR,則保證了這兩個任務可以循環執行,保證了公平。

Ingo Molnar-實時補丁
為了能並入主流內核,Ingo Molnar的實時補丁也採用了非常靈活的策略,它支持四種搶占模式:
1.No Forced Preemption (Server),這種模式等同於沒有使能搶占選項的標准內核,主要適用於科學計算等伺服器環境。
2.Voluntary Kernel Preemption (Desktop),這種模式使能了自願搶占,但仍然失效搶占內核選項,它通過增加搶占點縮減了搶占延遲,因此適用於一些需要較好的響應性的環境,如桌面環境,當然這種好的響應性是以犧牲一些吞吐率為代價的。
3.Preemptible Kernel (Low-Latency Desktop),這種模式既包含了自願搶占,又使能了可搶占內核選項,因此有很好的響應延遲,實際上在一定程度上已經達到了軟實時性。它主要適用於桌面和一些嵌入式系統,但是吞吐率比模式2更低。
4.Complete Preemption (Real-Time),這種模式使能了所有實時功能,因此完全能夠滿足軟實時需求,它適用於延遲要求為100微秒或稍低的實時系統。
實現實時是以犧牲系統的吞吐率為代價的,因此實時性越好,系統吞吐率就越低。

『肆』 如何提高Linux伺服器磁碟io性能

您好,很高興為您解答。

在現有文件系統下進行優化:
linux內核和各個文件系統採用了幾個優化方案來提升磁碟訪問速度。但這些優化方案需要在我們的伺服器設計中進行配合才能得到充分發揮。
文件系統緩存
linux內核會將大部分空閑內存交給虛擬文件系統,來作為文件緩存,叫做page cache。在內存不足時,這部分內存會採用lru演算法進行淘汰。通過free命令查看內存,顯示為cached的部分就是文件緩存了。

如何針對性優化:
lru並不是一個優秀淘汰演算法,lru最大的優勢是普適性好,在各種使用場景下都能起到一定的效果。如果能找到當前使用場景下,文件被訪問的統計特徵,針 對性的寫一個淘汰演算法,可以大幅提升文件緩存的命中率。對於http正向代理來說,一個好的淘汰演算法可以用1GB內存達到lru演算法100GB內存的緩存 效果。如果不打算寫一個新的淘汰演算法,一般不需要在應用層再搭一個文件cache程序來做緩存。

最小分配:
當文件擴大,需要分配磁碟空間時,大部分文件系統不會僅僅只分配當前需要的磁碟空間,而是會多分配一些磁碟空間。這樣下次文件擴大時就可以使用已經分配好的空間,而不會頻繁的去分配新空間。
例如ext3下,每次分配磁碟空間時,最小是分配8KB。
最小分配的副作用是會浪費一些磁碟空間(分配了但是又沒有使用)

如何針對性優化:
我們在reiserfs下將最小分配空間從8KB改大到128K後提升了30%的磁碟io性能。如果當前使用場景下小文件很多,把預分配改大就會浪費很多 磁碟空間,所以這個數值要根據當前使用場景來設定。似乎要直接改源代碼才能生效,不太記得了,09年的時候改的,有興趣的同學自己google吧。

io訪問調度:
在同時有多個io訪問時,linux內核可以對這些io訪問按LBA進行合並和排序,這樣磁頭在移動時,可以「順便」讀出移動過程中的數據。
SATA等磁碟甚至在磁碟中內置了io排序來進一步提升性能,一般需要在主板中進行配置才能啟動磁碟內置io排序。linux的io排序是根據LBA進行的,但LBA是一個一維線性地址,無法完全反應出二維的圓形磁碟,所以磁碟的內置io排序能達到更好的效果。

如何針對性優化:
io訪問調度能大幅提升io性能,前提是應用層同時發起了足夠的io訪問供linux去調度。
怎樣才能從應用層同時向內核發起多個io訪問呢?
方案一是用aio_read非同步發起多個文件讀寫請求。
方案二是使用磁碟線程池同時發起多個文件讀寫請求。
對我們的http正向代理來說,採用16個線程讀寫磁碟可以將性能提升到2.5倍左右。具體開多少個線程/進程,可以根據具體使用場景來決定。

小提示:
將文件句柄設置為非阻塞時,進程還是會睡眠等待磁碟io,非阻塞對於文件讀寫是不生效的。在正常情況下,讀文件只會引入十幾毫秒睡眠,所以不太明顯;而在磁碟io極大時,讀文件會引起十秒以上的進程睡眠。

預讀取:
linux內核可以預測我們「將來的讀請求」並提前將數據讀取出來。通過預讀取可以減少讀io的次數,並且減小讀請求的延時。

如何針對性優化:
預讀取的預測准確率是有限的,與其依賴預讀取,不如我們直接開一個較大的緩沖區,一次性將文件讀出來再慢慢處理;盡量不要開一個較小的緩沖區,循環讀文件/處理文件。
雖然說「預讀取」和「延遲分配」能起到類似的作用,但是我們自己擴大讀寫緩沖區效果要更好。

延遲分配:
當文件擴大,需要分配磁碟空間時,可以不立即進行分配,而是暫存在內存中,將多次分配磁碟空間的請求聚合在一起後,再進行一次性分配。
延遲分配的目的也是減少分配次數,從而減少文件不連續。

延遲分配的副作用有幾個:
1、如果應用程序每次寫數據後都通過fsync等介面進行強制刷新,延遲分配將不起作用
2、延遲分配有可能間歇性引入一個較大的磁碟IO延時(因為要一次性向磁碟寫入較多數據)
只有少數新文件系統支持這個特性

如何針對性優化:
如果不是對安全性(是否允許丟失)要求極高的數據,可以直接在應用程序里緩存起來,積累到一定大小再寫入,效果比文件系統的延遲分配更好。如果對安全性要求極高,建議經常用fsync強制刷新。

在線磁碟碎片整理:
Ext4提供了一款碎片整理工具,叫e4defrag,主要包含三個功能:
1、讓每個文件連續存儲
2、盡量讓每個目錄下的文件連續存儲
3、通過整理空閑磁碟空間,讓接下來的分配更不容易產生碎片

如何針對性優化:
「讓每個目錄下的文件連續存儲」是一個極有價值的功能。
傳統的做法是通過拼接圖片來將這10張圖片合並到一張大圖中,再由前端將大圖切成10張小圖。
有了e4defrag後,可以將需連續訪問的文件放在同一個文件夾下,再定期使用e4defrag進行磁碟整理。

實現自己的文件系統:
在大部分伺服器上,不需要支持「修改文件」這個功能。一旦文件創建好,就不能再做修改操作,只支持讀取和刪除。在這個前提下,我們可以消滅所有文件碎片,把磁碟io效率提升到理論極限。

有一個公式可以衡量磁碟io的效率:
磁碟利用率 = 傳輸時間/(平均尋道時間+傳輸時間)

如若滿意,請點擊回答右側【採納答案】,如若還有問題,請點擊【追問】

~ O(∩_∩)O~

『伍』 linux內核怎麼調度系統

1.調度器的概述

多任務操作系統分為非搶占式多任務和搶占式多任務。與大多數現代操作系統一樣,Linux採用的是搶占式多任務模式。這表示對CPU的佔用時間由操作系統決定的,具體為操作系統中的調度器。調度器決定了什麼時候停止一個進程以便讓其他進程有機會運行,同時挑選出一個其他的進程開始運行。

2.調度策略

在Linux上調度策略決定了調度器是如何選擇一個新進程的時間。調度策略與進程的類型有關,內核現有的調度策略如下:

#define SCHED_NORMAL 0#define SCHED_FIFO 1#define SCHED_RR 2#define SCHED_BATCH 3/* SCHED_ISO: reserved but not implemented yet */#define SCHED_IDLE 5

0: 默認的調度策略,針對的是普通進程。
1:針對實時進程的先進先出調度。適合對時間性要求比較高但每次運行時間比較短的進程。
2:針對的是實時進程的時間片輪轉調度。適合每次運行時間比較長得進程。
3:針對批處理進程的調度,適合那些非交互性且對cpu使用密集的進程。
SCHED_ISO:是內核的一個預留欄位,目前還沒有使用
5:適用於優先順序較低的後台進程。
註:每個進程的調度策略保存在進程描述符task_struct中的policy欄位

3.調度器中的機制

內核引入調度類(struct sched_class)說明了調度器應該具有哪些功能。內核中每種調度策略都有該調度類的一個實例。(比如:基於公平調度類為:fair_sched_class,基於實時進程的調度類實例為:rt_sched_class),該實例也是針對每種調度策略的具體實現。調度類封裝了不同調度策略的具體實現,屏蔽了各種調度策略的細節實現。
調度器核心函數schele()只需要調用調度類中的介面,完成進程的調度,完全不需要考慮調度策略的具體實現。調度類連接了調度函數和具體的調度策略。

『陸』 linux環境下的進程調度演算法有哪些

第一部分: 實時調度演算法介紹

對於什麼是實時系統,POSIX 1003.b作了這樣的定義:指系統能夠在限定的響應時間內提供所需水平的服務。而一個由Donald Gillies提出的更加為大家接受的定義是:一個實時系統是指計算的正確性不僅取決於程序的邏輯正確性,也取決於結果產生的時間,如果系統的時間約束條件得不到滿足,將會發生系統出錯。

實時系統根據其對於實時性要求的不同,可以分為軟實時和硬實時兩種類型。硬實時系統指系統要有確保的最壞情況下的服務時間,即對於事件的響應時間的截止期限是無論如何都必須得到滿足。比如航天中的宇宙飛船的控制等就是現實中這樣的系統。其他的所有有實時特性的系統都可以稱之為軟實時系統。如果明確地來說,軟實時系統就是那些從統計的角度來說,一個任務(在下面的論述中,我們將對任務和進程不作區分)能夠得到有確保的處理時間,到達系統的事件也能夠在截止期限到來之前得到處理,但違反截止期限並不會帶來致命的錯誤,像實時多媒體系統就是一種軟實時系統。

一個計算機系統為了提供對於實時性的支持,它的操作系統必須對於CPU和其他資源進行有效的調度和管理。在多任務實時系統中,資源的調度和管理更加復雜。本文下面將先從分類的角度對各種實時任務調度演算法進行討論,然後研究普通的 Linux操作系統的進程調度以及各種實時Linux系統為了支持實時特性對普通Linux系統所做的改進。最後分析了將Linux操作系統應用於實時領域中時所出現的一些問題,並總結了各種實時Linux是如何解決這些問題的。

1. 實時CPU調度演算法分類

各種實時操作系統的實時調度演算法可以分為如下三種類別[Wang99][Gopalan01]:基於優先順序的調度演算法(Priority-driven scheling-PD)、基於CPU使用比例的共享式的調度演算法(Share-driven scheling-SD)、以及基於時間的進程調度演算法(Time-driven scheling-TD),下面對這三種調度演算法逐一進行介紹。

1.1. 基於優先順序的調度演算法

基於優先順序的調度演算法給每個進程分配一個優先順序,在每次進程調度時,調度器總是調度那個具有最高優先順序的任務來執行。根據不同的優先順序分配方法,基於優先順序的調度演算法可以分為如下兩種類型[Krishna01][Wang99]:

靜態優先順序調度演算法:

這種調度演算法給那些系統中得到運行的所有進程都靜態地分配一個優先順序。靜態優先順序的分配可以根據應用的屬性來進行,比如任務的周期,用戶優先順序,或者其它的預先確定的策略。RM(Rate-Monotonic)調度演算法是一種典型的靜態優先順序調度演算法,它根據任務的執行周期的長短來決定調度優先順序,那些具有小的執行周期的任務具有較高的優先順序。

動態優先順序調度演算法:

這種調度演算法根據任務的資源需求來動態地分配任務的優先順序,其目的就是在資源分配和調度時有更大的靈活性。非實時系統中就有很多這種調度演算法,比如短作業優先的調度演算法。在實時調度演算法中, EDF演算法是使用最多的一種動態優先順序調度演算法,該演算法給就緒隊列中的各個任務根據它們的截止期限(Deadline)來分配優先順序,具有最近的截止期限的任務具有最高的優先順序。

1.2. 基於比例共享調度演算法

雖然基於優先順序的調度演算法簡單而有效,但這種調度演算法提供的是一種硬實時的調度,在很多情況下並不適合使用這種調度演算法:比如象實時多媒體會議系統這樣的軟實時應用。對於這種軟實時應用,使用一種比例共享式的資源調度演算法(SD演算法)更為適合。

比例共享調度演算法指基於CPU使用比例的共享式的調度演算法,其基本思想就是按照一定的權重(比例)對一組需要調度的任務進行調度,讓它們的執行時間與它們的權重完全成正比。

我們可以通過兩種方法來實現比例共享調度演算法[Nieh01]:第一種方法是調節各個就緒進程出現在調度隊列隊首的頻率,並調度隊首的進程執行;第二種做法就是逐次調度就緒隊列中的各個進程投入運行,但根據分配的權重調節分配個每個進程的運行時間片。

比例共享調度演算法可以分為以下幾個類別:輪轉法、公平共享、公平隊列、彩票調度法(Lottery)等。

比例共享調度演算法的一個問題就是它沒有定義任何優先順序的概念;所有的任務都根據它們申請的比例共享CPU資源,當系統處於過載狀態時,所有的任務的執行都會按比例地變慢。所以為了保證系統中實時進程能夠獲得一定的CPU處理時間,一般採用一種動態調節進程權重的方法。

1.3. 基於時間的進程調度演算法

對於那些具有穩定、已知輸入的簡單系統,可以使用時間驅動(Time-driven:TD)的調度演算法,它能夠為數據處理提供很好的預測性。這種調度演算法本質上是一種設計時就確定下來的離線的靜態調度方法。在系統的設計階段,在明確系統中所有的處理情況下,對於各個任務的開始、切換、以及結束時間等就事先做出明確的安排和設計。這種調度演算法適合於那些很小的嵌入式系統、自控系統、感測器等應用環境。

這種調度演算法的優點是任務的執行有很好的可預測性,但最大的缺點是缺乏靈活性,並且會出現有任務需要被執行而CPU卻保持空閑的情況。

2. 通用Linux系統中的CPU調度

通用Linux系統支持實時和非實時兩種進程,實時進程相對於普通進程具有絕對的優先順序。對應地,實時進程採用SCHED_FIFO或者SCHED_RR調度策略,普通的進程採用SCHED_OTHER調度策略。

在調度演算法的實現上,Linux中的每個任務有四個與調度相關的參數,它們是rt_priority、policy、priority(nice)、counter。調度程序根據這四個參數進行進程調度。

在SCHED_OTHER 調度策略中,調度器總是選擇那個priority+counter值最大的進程來調度執行。從邏輯上分析,SCHED_OTHER調度策略存在著調度周期(epoch),在每一個調度周期中,一個進程的priority和counter值的大小影響了當前時刻應該調度哪一個進程來執行,其中 priority是一個固定不變的值,在進程創建時就已經確定,它代表了該進程的優先順序,也代表這該進程在每一個調度周期中能夠得到的時間片的多少; counter是一個動態變化的值,它反映了一個進程在當前的調度周期中還剩下的時間片。在每一個調度周期的開始,priority的值被賦給 counter,然後每次該進程被調度執行時,counter值都減少。當counter值為零時,該進程用完自己在本調度周期中的時間片,不再參與本調度周期的進程調度。當所有進程的時間片都用完時,一個調度周期結束,然後周而復始。另外可以看出Linux系統中的調度周期不是靜態的,它是一個動態變化的量,比如處於可運行狀態的進程的多少和它們priority值都可以影響一個epoch的長短。值得注意的一點是,在2.4以上的內核中, priority被nice所取代,但二者作用類似。

可見SCHED_OTHER調度策略本質上是一種比例共享的調度策略,它的這種設計方法能夠保證進程調度時的公平性--一個低優先順序的進程在每一個epoch中也會得到自己應得的那些CPU執行時間,另外它也提供了不同進程的優先順序區分,具有高priority值的進程能夠獲得更多的執行時間。

對於實時進程來說,它們使用的是基於實時優先順序rt_priority的優先順序調度策略,但根據不同的調度策略,同一實時優先順序的進程之間的調度方法有所不同:

SCHED_FIFO:不同的進程根據靜態優先順序進行排隊,然後在同一優先順序的隊列中,誰先准備好運行就先調度誰,並且正在運行的進程不會被終止直到以下情況發生:1.被有更高優先順序的進程所強佔CPU;2.自己因為資源請求而阻塞;3.自己主動放棄CPU(調用sched_yield);

SCHED_RR:這種調度策略跟上面的SCHED_FIFO一模一樣,除了它給每個進程分配一個時間片,時間片到了正在執行的進程就放棄執行;時間片的長度可以通過sched_rr_get_interval調用得到;

由於Linux系統本身是一個面向桌面的系統,所以將它應用於實時應用中時存在如下的一些問題:

Linux系統中的調度單位為10ms,所以它不能夠提供精確的定時;

當一個進程調用系統調用進入內核態運行時,它是不可被搶占的;

Linux內核實現中使用了大量的封中斷操作會造成中斷的丟失;

由於使用虛擬內存技術,當發生頁出錯時,需要從硬碟中讀取交換數據,但硬碟讀寫由於存儲位置的隨機性會導致隨機的讀寫時間,這在某些情況下會影響一些實時任務的截止期限;

雖然Linux進程調度也支持實時優先順序,但缺乏有效的實時任務的調度機制和調度演算法;它的網路子系統的協議處理和其它設備的中斷處理都沒有與它對應的進程的調度關聯起來,並且它們自身也沒有明確的調度機制;

3. 各種實時Linux系統

3.1. RT-Linux和RTAI

RT -Linux是新墨西哥科技大學(New Mexico Institute of Technology)的研究成果[RTLinuxWeb][Barabanov97]。它的基本思想是,為了在Linux系統中提供對於硬實時的支持,它實現了一個微內核的小的實時操作系統(我們也稱之為RT-Linux的實時子系統),而將普通Linux系統作為一個該操作系統中的一個低優先順序的任務來運行。另外普通Linux系統中的任務可以通過FIFO和實時任務進行通信。RT-Linux的框架如圖 1所示:

圖 1 RT-Linux結構

RT -Linux的關鍵技術是通過軟體來模擬硬體的中斷控制器。當Linux系統要封鎖CPU的中斷時時,RT-Linux中的實時子系統會截取到這個請求,把它記錄下來,而實際上並不真正封鎖硬體中斷,這樣就避免了由於封中斷所造成的系統在一段時間沒有響應的情況,從而提高了實時性。當有硬體中斷到來時, RT-Linux截取該中斷,並判斷是否有實時子系統中的中斷常式來處理還是傳遞給普通的Linux內核進行處理。另外,普通Linux系統中的最小定時精度由系統中的實時時鍾的頻率決定,一般Linux系統將該時鍾設置為每秒來100個時鍾中斷,所以Linux系統中一般的定時精度為 10ms,即時鍾周期是10ms,而RT-Linux通過將系統的實時時鍾設置為單次觸發狀態,可以提供十幾個微秒級的調度粒度。

RT-Linux實時子系統中的任務調度可以採用RM、EDF等優先順序驅動的演算法,也可以採用其他調度演算法。

RT -Linux對於那些在重負荷下工作的專有系統來說,確實是一個不錯的選擇,但他僅僅提供了對於CPU資源的調度;並且實時系統和普通Linux系統關系不是十分密切,這樣的話,開發人員不能充分利用Linux系統中已經實現的功能,如協議棧等。所以RT-Linux適合與工業控制等實時任務功能簡單,並且有硬實時要求的環境中,但如果要應用與多媒體處理中還需要做大量的工作。

義大利的RTAI( Real-Time Application Interface )源於RT-Linux,它在設計思想上和RT-Linux完全相同。它當初設計目的是為了解決RT-Linux難於在不同Linux版本之間難於移植的問題,為此,RTAI在 Linux 上定義了一個實時硬體抽象層,實時任務通過這個抽象層提供的介面和Linux系統進行交互,這樣在給Linux內核中增加實時支持時可以盡可能少地修改 Linux的內核源代碼。

3.2. Kurt-Linux

Kurt -Linux由Kansas大學開發,它可以提供微秒級的實時精度[KurtWeb] [Srinivasan]。不同於RT-Linux單獨實現一個實時內核的做法,Kurt -Linux是在通用Linux系統的基礎上實現的,它也是第一個可以使用普通Linux系統調用的基於Linux的實時系統。

Kurt-Linux將系統分為三種狀態:正常態、實時態和混合態,在正常態時它採用普通的Linux的調度策略,在實時態只運行實時任務,在混合態實時和非實時任務都可以執行;實時態可以用於對於實時性要求比較嚴格的情況。

為了提高Linux系統的實時特性,必須提高系統所支持的時鍾精度。但如果僅僅簡單地提高時鍾頻率,會引起調度負載的增加,從而嚴重降低系統的性能。為了解決這個矛盾, Kurt-Linux採用UTIME所使用的提高Linux系統中的時鍾精度的方法[UTIMEWeb]:它將時鍾晶元設置為單次觸發狀態(One shot mode),即每次給時鍾晶元設置一個超時時間,然後到該超時事件發生時在時鍾中斷處理程序中再次根據需要給時鍾晶元設置一個超時時間。它的基本思想是一個精確的定時意味著我們需要時鍾中斷在我們需要的一個比較精確的時間發生,但並非一定需要系統時鍾頻率達到此精度。它利用CPU的時鍾計數器TSC (Time Stamp Counter)來提供精度可達CPU主頻的時間精度。

對於實時任務的調度,Kurt-Linux採用基於時間(TD)的靜態的實時CPU調度演算法。實時任務在設計階段就需要明確地說明它們實時事件要發生的時間。這種調度演算法對於那些循環執行的任務能夠取得較好的調度效果。

Kurt -Linux相對於RT-Linux的一個優點就是可以使用Linux系統自身的系統調用,它本來被設計用於提供對硬實時的支持,但由於它在實現上只是簡單的將Linux調度器用一個簡單的時間驅動的調度器所取代,所以它的實時進程的調度很容易受到其它非實時任務的影響,從而在有的情況下會發生實時任務的截止期限不能滿足的情況,所以也被稱作嚴格實時系統(Firm Real-time)。目前基於Kurt-Linux的應用有:ARTS(ATM Reference Traffic System)、多媒體播放軟體等。另外Kurt-Linux所採用的這種方法需要頻繁地對時鍾晶元進行編程設置。

3.3. RED-Linux

RED -Linux是加州大學Irvine分校開發的實時Linux系統[REDWeb][ Wang99],它將對實時調度的支持和Linux很好地實現在同一個操作系統內核中。它同時支持三種類型的調度演算法,即:Time-Driven、 Priority-Dirven、Share-Driven。

為了提高系統的調度粒度,RED-Linux從RT-Linux那兒借鑒了軟體模擬中斷管理器的機制,並且提高了時鍾中斷頻率。當有硬體中斷到來時,RED-Linux的中斷模擬程序僅僅是簡單地將到來的中斷放到一個隊列中進行排隊,並不執行真正的中斷處理程序。

另外為了解決Linux進程在內核態不能被搶占的問題, RED-Linux在Linux內核的很多函數中插入了搶占點原語,使得進程在內核態時,也可以在一定程度上被搶占。通過這種方法提高了內核的實時特性。

RED-Linux的設計目標就是提供一個可以支持各種調度演算法的通用的調度框架,該系統給每個任務增加了如下幾項屬性,並將它們作為進程調度的依據:

Priority:作業的優先順序;

Start-Time:作業的開始時間;

Finish-Time:作業的結束時間;

Budget:作業在運行期間所要使用的資源的多少;

通過調整這些屬性的取值及調度程序按照什麼樣的優先順序來使用這些屬性值,幾乎可以實現所有的調度演算法。這樣的話,可以將三種不同的調度演算法無縫、統一地結合到了一起。

『柒』 面試 linux 文件系統怎樣io到底層

前言:本文主要講解LinuxIO調度層的三種模式:cfp、deadline和noop,並給出各自的優化和適用場景建議。IO調度發生在Linux內核的IO調度層。這個層次是針對Linux的整體IO層次體系來說的。從read()或者write()系統調用的角度來說,Linux整體IO體系可以分為七層,它們分別是:VFS層:虛擬文件系統層。由於內核要跟多種文件系統打交道,而每一種文件系統所實現的數據結構和相關方法都可能不盡相同,所以,內核抽象了這一層,專門用來適配各種文件系統,並對外提供統一操作介面。文件系統層:不同的文件系統實現自己的操作過程,提供自己特有的特徵,具體不多說了,大家願意的話自己去看代碼即可。頁緩存層:負責真對page的緩存。通用塊層:由於絕大多數情況的io操作是跟塊設備打交道,所以Linux在此提供了一個類似vfs層的塊設備操作抽象層。下層對接各種不同屬性的塊設備,對上提供統一的BlockIO請求標准。IO調度層:因為絕大多數的塊設備都是類似磁碟這樣的設備,所以有必要根據這類設備的特點以及應用的不同特點來設置一些不同的調度演算法和隊列。以便在不同的應用環境下有針對性的提高磁碟的讀寫效率,這里就是大名鼎鼎的Linux電梯所起作用的地方。針對機械硬碟的各種調度方法就是在這實現的。塊設備驅動層:驅動層對外提供相對比較高級的設備操作介面,往往是C語言的,而下層對接設備本身的操作方法和規范。塊設備層:這層就是具體的物理設備了,定義了各種真對設備操作方法和規范。有一個已經整理好的[LinuxIO結構圖],非常經典,一圖勝千言:我們今天要研究的內容主要在IO調度這一層。它要解決的核心問題是,如何提高塊設備IO的整體性能?這一層也主要是針對機械硬碟結構而設計的。眾所周知,機械硬碟的存儲介質是磁碟,磁頭在碟片上移動進行磁軌定址,行為類似播放一張唱片。這種結構的特點是,順序訪問時吞吐量較高,但是如果一旦對碟片有隨機訪問,那麼大量的時間都會浪費在磁頭的移動上,這時候就會導致每次IO的響應時間變長,極大的降低IO的響應速度。磁頭在碟片上尋道的操作,類似電梯調度,實際上在最開始的時期,Linux把這個演算法命名為Linux電梯演算法,即:如果在尋道的過程中,能把順序路過的相關磁軌的數據請求都「順便」處理掉,那麼就可以在比較小影響響應速度的前提下,提高整體IO的吞吐量。這就是我們為什麼要設計IO調度演算法的原因。目前在內核中默認開啟了三種演算法/模式:noop,cfq和deadline。嚴格算應該是兩種:因為第一種叫做noop,就是空操作調度演算法,也就是沒有任何調度操作,並不對io請求進行排序,僅僅做適當的io合並的一個fifo隊列。目前內核中默認的調度演算法應該是cfq,叫做完全公平隊列調度。這個調度演算法人如其名,它試圖給所有進程提供一個完全公平的IO操作環境。註:請大家一定記住這個詞語,cfq,完全公平隊列調度,不然下文就沒法看了。cfq為每個進程創建一個同步IO調度隊列,並默認以時間片和請求數限定的方式分配IO資源,以此保證每個進程的IO資源佔用是公平的,cfq還實現了針對進程級別的優先順序調度,這個我們後面會詳細解釋。查看和修改IO調度演算法的方法是:cfq是通用伺服器比較好的IO調度演算法選擇,對桌面用戶也是比較好的選擇。但是對於很多IO壓力較大的場景就並不是很適應,尤其是IO壓力集中在某些進程上的場景。因為這種場景我們需要的滿足某個或者某幾個進程的IO響應速度,而不是讓所有的進程公平的使用IO,比如資料庫應用。deadline調度(最終期限調度)就是更適合上述場景的解決方案。deadline實現了四個隊列:其中兩個分別處理正常read和write,按扇區號排序,進行正常io的合並處理以提高吞吐量。因為IO請求可能會集中在某些磁碟位置,這樣會導致新來的請求一直被合並,可能會有其他磁碟位置的io請求被餓死。另外兩個處理超時read和write的隊列,按請求創建時間排序,如果有超時的請求出現,就放進這兩個隊列,調度演算法保證超時(達到最終期限時間)的隊列中的請求會優先被處理,防止請求被餓死。不久前,內核還是默認標配四種演算法,還有一種叫做as的演算法(Anticipatoryscheler),預測調度演算法。一個高大上的名字,搞得我一度認為Linux內核都會算命了。結果發現,無非是在基於deadline演算法做io調度的之前等一小會時間,如果這段時間內有可以合並的io請求到來,就可以合並處理,提高deadline調度的在順序讀寫情況下的數據吞吐量。其實這根本不是啥預測,我覺得不如叫撞大運調度演算法,當然這種策略在某些特定場景差效果不錯。但是在大多數場景下,這個調度不僅沒有提高吞吐量,還降低了響應速度,所以內核乾脆把它從默認配置里刪除了。畢竟Linux的宗旨是實用,而我們也就不再這個調度演算法上多費口舌了。1、cfq:完全公平隊列調度cfq是內核默認選擇的IO調度隊列,它在桌面應用場景以及大多數常見應用場景下都是很好的選擇。如何實現一個所謂的完全公平隊列(CompletelyFairQueueing)?首先我們要理解所謂的公平是對誰的公平?從操作系統的角度來說,產生操作行為的主體都是進程,所以這里的公平是針對每個進程而言的,我們要試圖讓進程可以公平的佔用IO資源。那麼如何讓進程公平的佔用IO資源?我們需要先理解什麼是IO資源。當我們衡量一個IO資源的時候,一般喜歡用的是兩個單位,一個是數據讀寫的帶寬,另一個是數據讀寫的IOPS。帶寬就是以時間為單位的讀寫數據量,比如,100Mbyte/s。而IOPS是以時間為單位的讀寫次數。在不同的讀寫情境下,這兩個單位的表現可能不一樣,但是可以確定的是,兩個單位的任何一個達到了性能上限,都會成為IO的瓶頸。從機械硬碟的結構考慮,如果讀寫是順序讀寫,那麼IO的表現是可以通過比較少的IOPS達到較大的帶寬,因為可以合並很多IO,也可以通過預讀等方式加速數據讀取效率。當IO的表現是偏向於隨機讀寫的時候,那麼IOPS就會變得更大,IO的請求的合並可能性下降,當每次io請求數據越少的時候,帶寬表現就會越低。從這里我們可以理解,針對進程的IO資源的主要表現形式有兩個:進程在單位時間內提交的IO請求個數和進程佔用IO的帶寬。其實無論哪個,都是跟進程分配的IO處理時間長度緊密相關的。有時業務可以在較少IOPS的情況下佔用較大帶寬,另外一些則可能在較大IOPS的情況下佔用較少帶寬,所以對進程佔用IO的時間進行調度才是相對最公平的。即,我不管你是IOPS高還是帶寬佔用高,到了時間咱就換下一個進程處理,你愛咋樣咋樣。所以,cfq就是試圖給所有進程分配等同的塊設備使用的時間片,進程在時間片內,可以將產生的IO請求提交給塊設備進行處理,時間片結束,進程的請求將排進它自己的隊列,等待下次調度的時候進行處理。這就是cfq的基本原理。當然,現實生活中不可能有真正的「公平」,常見的應用場景下,我們很肯能需要人為的對進程的IO佔用進行人為指定優先順序,這就像對進程的CPU佔用設置優先順序的概念一樣。所以,除了針對時間片進行公平隊列調度外,cfq還提供了優先順序支持。每個進程都可以設置一個IO優先順序,cfq會根據這個優先順序的設置情況作為調度時的重要參考因素。優先順序首先分成三大類:RT、BE、IDLE,它們分別是實時(RealTime)、最佳效果(BestTry)和閑置(Idle)三個類別,對每個類別的IO,cfq都使用不同的策略進行處理。另外,RT和BE類別中,分別又再劃分了8個子優先順序實現更細節的QOS需求,而IDLE只有一個子優先順序。另外,我們都知道內核默認對存儲的讀寫都是經過緩存(buffer/cache)的,在這種情況下,cfq是無法區分當前處理的請求是來自哪一個進程的。只有在進程使用同步方式(syncread或者syncwirte)或者直接IO(DirectIO)方式進行讀寫的時候,cfq才能區分出IO請求來自哪個進程。所以,除了針對每個進程實現的IO隊列以外,還實現了一個公共的隊列用來處理非同步請求。當前內核已經實現了針對IO資源的cgroup資源隔離,所以在以上體系的基礎上,cfq也實現了針對cgroup的調度支持。總的來說,cfq用了一系列的數據結構實現了以上所有復雜功能的支持,大家可以通過源代碼看到其相關實現,文件在源代碼目錄下的block/cfq-iosched.c。1.1cfq設計原理在此,我們對整體數據結構做一個簡要描述:首先,cfq通過一個叫做cfq_data的數據結構維護了整個調度器流程。在一個支持了cgroup功能的cfq中,全部進程被分成了若干個contralgroup進行管理。每個cgroup在cfq中都有一個cfq_group的結構進行描述,所有的cgroup都被作為一個調度對象放進一個紅黑樹中,並以vdisktime為key進行排序。vdisktime這個時間紀錄的是當前cgroup所佔用的io時間,每次對cgroup進行調度時,總是通過紅黑樹選擇當前vdisktime時間最少的cgroup進行處理,以保證所有cgroups之間的IO資源佔用「公平」。當然我們知道,cgroup是可以對blkio進行資源比例分配的,其作用原理就是,分配比例大的cgroup佔用vdisktime時間增長較慢,分配比例小的vdisktime時間增長較快,快慢與分配比例成正比。這樣就做到了不同的cgroup分配的IO比例不一樣,並且在cfq的角度看來依然是「公平「的。選擇好了需要處理的cgroup(cfq_group)之後,調度器需要決策選擇下一步的service_tree。service_tree這個數據結構對應的都是一系列的紅黑樹,主要目的是用來實現請求優先順序分類的,就是RT、BE、IDLE的分類。每一個cfq_group都維護了7個service_trees,其定義如下:其中service_tree_idle就是用來給IDLE類型的請求進行排隊用的紅黑樹。而上面二維數組,首先第一個維度針對RT和BE分別各實現了一個數組,每一個數組中都維護了三個紅黑樹,分別對應三種不同子類型的請求,分別是:SYNC、SYNC_NOIDLE以及ASYNC。我們可以認為SYNC相當於SYNC_IDLE並與SYNC_NOIDLE對應。idling是cfq在設計上為了盡量合並連續的IO請求以達到提高吞吐量的目的而加入的機制,我們可以理解為是一種「空轉」等待機制。空轉是指,當一個隊列處理一個請求結束後,會在發生調度之前空等一小會時間,如果下一個請求到來,則可以減少磁頭定址,繼續處理順序的IO請求。為了實現這個功能,cfq在service_tree這層數據結構這實現了SYNC隊列,如果請求是同步順序請求,就入隊這個servicetree,如果請求是同步隨機請求,則入隊SYNC_NOIDLE隊列,以判斷下一個請求是否是順序請求。所有的非同步寫操作請求將入隊ASYNC的servicetree,並且針對這個隊列沒有空轉等待機制。此外,cfq還對SSD這樣的硬碟有特殊調整,當cfq發現存儲設備是一個ssd硬碟這樣的隊列深度更大的設備時,所有針對單獨隊列的空轉都將不生效,所有的IO請求都將入隊SYNC_NOIDLE這個servicetree。每一個servicetree都對應了若干個cfq_queue隊列,每個cfq_queue隊列對應一個進程,這個我們後續再詳細說明。cfq_group還維護了一個在cgroup內部所有進程公用的非同步IO請求隊列,其結構如下:非同步請求也分成了RT、BE、IDLE這三類進行處理,每一類對應一個cfq_queue進行排隊。BE和RT也實現了優先順序的支持,每一個類型有IOPRIO_BE_NR這么多個優先順序,這個值定義為8,數組下標為0-7。我們目前分析的內核代碼版本為Linux4.4,可以看出,從cfq的角度來說,已經可以實現非同步IO的cgroup支持了,我們需要定義一下這里所謂非同步IO的含義,它僅僅表示從內存的buffer/cache中的數據同步到硬碟的IO請求,而不是aio(man7aio)或者linux的native非同步io以及lio機制,實際上這些所謂的「非同步」IO機制,在內核中都是同步實現的(本質上馮諾伊曼計算機沒有真正的「非同步」機制)。我們在上面已經說明過,由於進程正常情況下都是將數據先寫入buffer/cache,所以這種非同步IO都是統一由cfq_group中的async請求隊列處理的。那麼為什麼在上面的service_tree中還要實現和一個ASYNC的類型呢?這當然是為了支持區分進程的非同步IO並使之可以「完全公平」做准備嘍。實際上在最新的cgroupv2的blkio體系中,內核已經支持了針對bufferIO的cgroup限速支持,而以上這些可能容易混淆的一堆類型,都是在新的體系下需要用到的類型標記。新體系的復雜度更高了,功能也更加強大,但是大家先不要著急,正式的cgroupv2體系,在Linux4.5發布的時候會正式跟大家見面。我們繼續選擇service_tree的過程,三種優先順序類型的service_tree的選擇就是根據類型的優先順序來做選擇的,RT優先順序最高,BE其次,IDLE最低。就是說,RT里有,就會一直處理RT,RT沒了再處理BE。每個service_tree對應一個元素為cfq_queue排隊的紅黑樹,而每個cfq_queue就是內核為進程(線程)創建的請求隊列。每一個cfq_queue都會維護一個rb_key的變數,這個變數實際上就是這個隊列的IO服務時間(servicetime)。這里還是通過紅黑樹找到servicetime時間最短的那個cfq_queue進行服務,以保證「完全公平」。選擇好了cfq_queue之後,就要開始處理這個隊列里的IO請求了。這里的調度方式基本跟deadline類似。cfq_queue會對進入隊列的每一個請求進行兩次入隊,一個放進fifo中,另一個放進按訪問扇區順序作為key的紅黑樹中。默認從紅黑樹中取請求進行處理,當請求的延時時間達到deadline時,就從紅黑樹中取等待時間最長的進行處理,以保證請求不被餓死。這就是整個cfq的調度流程,當然其中還有很多細枝末節沒有交代,比如合並處理以及順序處理等等。1.2cfq的參數調整理解整個調度流程有助於我們決策如何調整cfq的相關參數。所有cfq的可調參數都可以在/sys/class/block/sda/queue/iosched/目錄下找到,當然,在你的系統上,請將sda替換為相應的磁碟名稱。我們來看一下都有什麼:這些參數部分是跟機械硬碟磁頭尋道方式有關的,如果其說明你看不懂,請先補充相關知識:back_seek_max:磁頭可以向後定址的最大范圍,默認值為16M。back_seek_penalty:向後定址的懲罰系數。這個值是跟向前定址進行比較的。以上兩個是為了防止磁頭尋道發生抖動而導致定址過慢而設置的。基本思路是這樣,一個io請求到來的時候,cfq會根據其定址位置預估一下其磁頭尋道成本。設置一個最大值back_seek_max,對於請求所訪問的扇區號在磁頭後方的請求,只要定址范圍沒有超過這個值,cfq會像向前定址的請求一樣處理它。再設置一個評估成本的系數back_seek_penalty,相對於磁頭向前定址,向後定址的距離為1/2(1/back_seek_penalty)時,cfq認為這兩個請求定址的代價是相同。這兩個參數實際上是cfq判斷請求合並處理的條件限制,凡事復合這個條件的請求,都會盡量在本次請求處理的時候一起合並處理。fifo_expire_async:設置非同步請求的超時時間。同步請求和非同步請求是區分不同隊列處理的,cfq在調度的時候一般情況都會優先處理同步請求,之後再處理非同步請求,除非非同步請求符合上述合並處理的條件限制范圍內。當本進程的隊列被調度時,cfq會優先檢查是否有非同步請求超時,就是超過fifo_expire_async參數的限制。如果有,則優先發送一個超時的請求,其餘請求仍然按照優先順序以及扇區編號大小來處理。fifo_expire_sync:這個參數跟上面的類似,區別是用來設置同步請求的超時時間。slice_idle:參數設置了一個等待時間。這讓cfq在切換cfq_queue或servicetree的時候等待一段時間,目的是提高機械硬碟的吞吐量。一般情況下,來自同一個cfq_queue或者servicetree的IO請求的定址局部性更好,所以這樣可以減少磁碟的定址次數。這個值在機械硬碟上默認為非零。當然在固態硬碟或者硬RAID設備上設置這個值為非零會降低存儲的效率,因為固態硬碟沒有磁頭定址這個概念,所以在這樣的設備上應該設置為0,關閉此功能。group_idle:這個參數也跟上一個參數類似,區別是當cfq要切換cfq_group的時候會等待一段時間。在cgroup的場景下,如果我們沿用slice_idle的方式,那麼空轉等待可能會在cgroup組內每個進程的cfq_queue切換時發生。這樣會如果這個進程一直有請求要處理的話,那麼直到這個cgroup的配額被耗盡,同組中的其它進程也可能無法被調度到。這樣會導致同組中的其它進程餓死而產生IO性能瓶頸。在這種情況下,我們可以將slice_idle=0而group_idle=8。這樣空轉等待就是以cgroup為單位進行的,而不是以cfq_queue的進程為單位進行,以防止上述問題產生。low_latency:這個是用來開啟或關閉cfq的低延時(lowlatency)模式的開關。當這個開關打開時,cfq將會根據target_latency的參數設置來對每一個進程的分片時間(slicetime)進行重新計算。這將有利於對吞吐量的公平(默認是對時間片分配的公平)。關閉這個參數(設置為0)將忽略target_latency的值。這將使系統中的進程完全按照時間片方式進行IO資源分配。這個開關默認是打開的。我們已經知道cfq設計上有「空轉」(idling)這個概念,目的是為了可以讓連續的讀寫操作盡可能多的合並處理,減少磁頭的定址操作以便增大吞吐量。如果有進程總是很快的進行順序讀寫,那麼它將因為cfq的空轉等待命中率很高而導致其它需要處理IO的進程響應速度下降,如果另一個需要調度的進程不會發出大量順序IO行為的話,系統中不同進程IO吞吐量的表現就會很不均衡。就比如,系統內存的cache中有很多臟頁要寫回時,桌面又要打開一個瀏覽器進行操作,這時臟頁寫回的後台行為就很可能會大量命中空轉時間,而導致瀏覽器的小量IO一直等待,讓用戶感覺瀏覽器運行響應速度變慢。這個low_latency主要是對這種情況進行優化的選項,當其打開時,系統會根據target_latency的配置對因為命中空轉而大量佔用IO吞吐量的進程進行限制,以達到不同進程IO佔用的吞吐量的相對均衡。這個開關比較合適在類似桌面應用的場景下打開。target_latency:當low_latency的值為開啟狀態時,cfq將根據這個值重新計算每個進程分配的IO時間片長度。quantum:這個參數用來設置每次從cfq_queue中處理多少個IO請求。在一個隊列處理事件周期中,超過這個數字的IO請求將不會被處理。這個參數只對同步的請求有效。slice_sync:當一個cfq_queue隊列被調度處理時,它可以被分配的處理總時間是通過這個值來作為一個計算參數指定的。公式為:time_slice=slice_sync+(slice_sync/5*(4-prio))。這個參數對同步請求有效。slice_async:這個值跟上一個類似,區別是對非同步請求有效。slice_async_rq:這個參數用來限制在一個slice的時間范圍內,一個隊列最多可以處理的非同步請求個數。請求被處理的最大個數還跟相關進程被設置的io優先順序有關。1.3cfq的IOPS模式我們已經知道,默認情況下cfq是以時間片方式支持的帶優先順序的調度來保證IO資源佔用的公平。高優先順序的進程將得到的時間片長度,而低優先順序的進程時間片相對較小。當我們的存儲是一個高速並且支持NCQ(原生指令隊列)的設備的時候,我們最好可以讓其可以從多個cfq隊列中處理多路的請求,以便提升NCQ的利用率。此時使用時間片的分配方式分配資源就顯得不合時宜了,因為基於時間片的分配,同一時刻最多能處理的請求隊列只有一個。這時,我們需要切換cfq的模式為IOPS模式。切換方式很簡單,就是將slice_idle=0即可。內核會自動檢測你的存儲設備是否支持NCQ,如果支持的話cfq會自動切換為IOPS模式。另外,在默認的基於優先順序的時間片方式下,我們可以使用ionice命令來調整進程的IO優先順序。進程默認分配的IO優先順序是根據進程的nice值計算而來的,計算方法可以在manionice中看到,這里不再廢話。2、deadline:最終期限調度deadline調度演算法相對cfq要簡單很多。其設計目標是:在保證請求按照設備扇區的順序進行訪問的同時,兼顧其它請求不被餓死,要在一個最終期限前被調度到。我們知道磁頭對磁碟的尋道是可以進行順序訪問和隨機訪問的,因為尋道延時時間的關系,順序訪問時IO的吞吐量更大,隨機訪問的吞吐量小。如果我們想為一個機械硬碟進行吞吐量優化的話,那麼就可以讓調度器按照盡量復合順序訪問的IO請求進行排序,之後請求以這樣的順序發送給硬碟,就可以使IO的吞吐量更大。但是這樣做也有另一個問題,就是如果此時出現了一個請求,它要訪問的磁軌離目前磁頭所在磁軌很遠,應用的請求又大量集中在目前磁軌附近。導致大量請求一直會被合並和插隊處理,而那個要訪問比較遠磁軌的請求將因為一直不能被調度而餓死。deadline就是這樣一種調度器,能在保證IO最大吞吐量的情況下,盡量使遠端請求在一個期限內被調度而不被餓死的調度器。

『捌』 誰有linux i/o 調度演算法deadline,anticipatory,noop,cfq中各個調優參數的具體作用。

1.Deadline scheler Deadline scheler 用 deadline 演算法保證對於既定的 IO 請求以最小的延遲時間,從這一點理解,對於 DSS 應用應該會是很適合的。
2.Anticipatory scheler(as) 曾經一度是 Linux 2.6 Kernel 的 IO scheler 。Anticipatory 的中文含義是」預料的, 預想的」, 這個詞的確揭示了這個演算法的特點,簡單的說,有個 IO 發生的時候,如果又有進程請求 IO 操作,則將產生一個默認的 6 毫秒猜測時間,猜測下一個 進程請求 IO 是要干什麼的。這對於隨即讀取會造成比較大的延時,對資料庫應用很糟糕,而對於 Web Server 等則會表現的不錯。這個演算法也可以簡單理解為面向低速磁碟的,因為那個」猜測」實際上的目的是為了減少磁頭移動時間。
3.Completely Fair Queuing 雖然這世界上沒有完全公平的事情,但是並不妨礙開源愛好者們設計一個完全公平的 IO 調度演算法。Completely Fair Queuing (cfq, 完全公平隊列) 在 2.6.18 取代了 Anticipatory scheler 成為 Linux Kernel 默認的 IO scheler 。cfq 對每個進程維護一個 IO 隊列,各個進程發來的 IO 請求會被 cfq 以輪循方式處理。也就是對每一個 IO 請求都是公平的。這使得 cfq 很適合離散讀的應用(eg: OLTP DB)。我所知道的企業級 Linux 發行版中,SuSE Linux 好像是最先默認用 cfq 的.
4.NOOP Noop 對於 IO 不那麼操心,對所有的 IO請求都用 FIFO 隊列形式處理,默認認為 IO 不會存在性能問題。這也使得 CPU 也不用那麼操心。當然,對於復雜一點的應用類型,使用這個調度器,用戶自己就會非常操心。

『玖』 linux io 調度 何時觸發

調度程序運行時,要在所有可運行狀態的進程中選擇最值得運行的進程投入運行。選擇進程的依據是什麼呢?在每個進程的task_struct結構中有以下四 項:policy、priority、counter、rt_priority。這四項是選擇進程的依據。其中,policy是進程的調度策略,用來區分 實時進程和普通進程,實時進程優先於普通進程運行;priority是進程(包括實時和普通)的靜態優先順序;counter是進程剩餘的時間片,它的起始 值就是priority的值;由於counter在後面計算一個處於可運行狀態的進程值得運行的程度goodness時起重要作用,因此,counter 也可以看作是進程的動態優先順序。rt_priority是實時進程特有的,用於實時進程間的選擇。 Linux用函數goodness()來衡量一個處於可運行狀態的進程值得運行的程度。該函數綜合了以上提到的四項,還結合了一些其他的因素,給每個處於 可運行狀態的進程賦予一個權值(weight),調度程序以這個權值作為選擇進程的唯一依據。關於goodness()的情況在後面將會詳細分析。

閱讀全文

與linuxio調度演算法相關的資料

熱點內容
javaoa開發 瀏覽:875
單片機的用途和使用方法 瀏覽:944
程序員在新公司上班 瀏覽:430
發信如何設置伺服器 瀏覽:77
源代碼查詢加密數字 瀏覽:605
附帶編譯 瀏覽:108
海康螢石雲app怎麼回放 瀏覽:404
寫一個編譯器怎麼寫 瀏覽:285
單片機蜂鳴器發聲原理 瀏覽:137
程序員那麼可愛陸離跳水是哪集 瀏覽:17
如何製作cdn伺服器 瀏覽:111
寫java加密程序 瀏覽:659
菜鳥數據分析pdf 瀏覽:291
單片機做實用東西 瀏覽:651
我的世界最強斗羅伺服器怎麼覺醒武魂 瀏覽:931
密友圈app怎麼切換用戶登錄 瀏覽:217
我把程序員當愛豆追 瀏覽:978
android判斷電話接通 瀏覽:646
大孔文件夾 瀏覽:785
反詐騙app在哪裡下載 瀏覽:527