關於linux的cfs調度器的宏觀理解

來源:互聯網
上載者:User
今天重讀了cfs調度器,使我忍不住再寫一篇關於cfs的文章,cfs調度器的已耗用時間是0(logN),而以前的調度器的已耗用時間是O(1),這是不是就是說cfs的效率比O(1)的更差呢?並不是那樣,我們知道cfs調度器下的運行隊列是基於紅/黑樹狀結構組織的,找出下一個進程就是截下左下角的節點,固定時間完成,所謂的O(logN)指的是插入時間,可是紅/黑樹狀結構的統計效能是不錯的,沒有多大機率真的用得了那麼多時間,因為紅節點和黑節點的特殊相片順序既保證了樹的一定程度的平衡,又不至於花太多的時間來維持這種平衡,插入操作大多數情況下都可以很快的完成,特別是對於組織得相當好的資料。實際上cfs之所以能進入核心並不是因為它能提供多好的效能,因為在一個事物的一種架構下,效能的提升肯定有個極限,不能一味的朝一個方向走,比如cpu的流水線在設計之初被認為是好的,可是intel的NetBurst架構一味的加長流水線,以為流水線越長效能越高,輸送量越大,可是工程學中永遠沒有一直單調遞增的函數,總會有一個拐點的。

cfs的精髓在於它改變了核心看待進程調度的方式,時間片越細越好嗎?搶佔點越多越好嗎?如果是的話,那麼很抱歉,到了2.6.17左右的核心,時間片已經很精細了,而且搶佔點也不能再多了,如果這個推理正確的話,那豈不是說調度器不能繼續發展了嗎,linux絕對不是這樣的性格,O(1)調度器的設計者有破有立,提供了另外一種截然不同的調度方式,這就是cfs,拋棄了時間片,拋棄了複雜的演算法,從一個新的起點開始了調度器的新時代,最開始的2.6.23版本核心的cfs是很簡單的,思想十分明確。cfs的本質思想就是提供一個虛擬時鐘,所有進程複用這個虛擬時鐘的時間,cfs將時鐘的概念從底層體系相關的硬體中抽象出來,進程調度模組直接和這個虛擬時鐘介面而不必再為硬體時鐘操作而操心,如此一來,整個進程調度模組就完整了,從時鐘到調度演算法,到不同進程的不同策略,全部都由虛擬系統提供,也正是在這個新的核心,引入了調度類。因此新的調度器就是不同特性的進程在統一的虛擬時鐘下按照不同的策略被調度。

我們看一下這樣做有什麼好處,cfs拋棄了時間片,採用了平滑的機制,用互相追趕的方式促使所有的進程一起向前走,那麼怎麼區分不同優先順序的進程呢?總不能所有進程以相同的速度往前走吧,顯然不能!我們都相信,用互相追趕的方式是最好的方式,就好像競爭一樣有益,我在中學的時候,老師就教導我們要互相追趕,雖然那個時候老師的意思就是大家都追趕我!既然相信互相追趕時最好的方式,那麼下一步就是怎麼實現互相追趕,如果在傳統的調度體系下,用硬時鐘,那麼很難實現不同進程的不同優先順序的管理,於是提出虛擬時鐘的概念,每個進程都有一個虛擬時鐘,然後整個系統有一個虛擬時鐘,系統虛擬時鐘以固定的步調前進,而各個進程的虛擬時鐘的前進步調卻因為其優先順序不同而不同,比如優先順序低的進程其虛擬時鐘的步調比較快,而優先順序高的步調比較慢,這一點用硬體時鐘是很難做到的,如果用硬體時鐘,我們就要維護每一個進程的狀態,然後將這個每個進程的狀態設定為一個全域的變數,可想而知,這個變數應該是個鏈表或者數組,每當硬體時鐘中斷的時候都要尋找這個鏈表進行尋找,刪除,選舉等操作,十分繁瑣,不說時間,空間上佔用的記憶體都無法接受。cfs提出的虛擬時鐘概念使得互相追趕更為容易實現,基於時間片的調度機制中,進程調度是被動的,調度模組不得不想辦法探知每個進程的特點並且根據不同的特性設定給它們不同的策略,然後依據這些不同的策略分配給它們不同的時間片,這樣必然會出現變態級的預測演算法,很複雜,讓學究們看來可以為我們賣弄一把,可是這個世界不喜歡複雜,因此學究們必須退讓;現在看看cfs調度器,進程有自己的優先順序,並且映射到權值,每個權值的進程的虛擬時鐘步調不同,大家都按照自己的虛擬時鐘往前走就是了,調度模組會選擇最落後於系統虛擬時鐘的進程來執行,這就是公平的含義,那麼在O(1)調度器中對互動進程的預測演算法在cfs中怎麼體現呢?其實完全沒有必要考慮這個問題,因為在O(1)調度器中,之所以要區分互動進程是因為O(1)調度器完全是基於優先順序來調度的,其它所有的調度依據都需要動態預測,而動態預測就必然需要複雜的演算法,在cfs調度器中,不單單有優先順序作為調度依據了,其實優先順序映射到了進程權值,然後各個進程互相追趕,這樣可以保證任何進程都不會被耽擱太久,互動進程的問題就解決了,O(1)調度器不能這樣的原因就是因為進程們不能自己互相追趕。舉個例子,就是在O(1)中,一個互動進程和一個非互動進程的優先順序都是p,調度器僅僅根據它們的優先順序來進行調度,別的什麼也不知道,只有靠探測它們的睡眠時間來進行進程類別的判斷,通過判斷如果一個進程是互動進程,那麼就暫且不把它放到到期隊列而是繼續運行用來補償它過多的睡眠,而在cfs調度器中就不會這樣,即使一個互動進程和一個非互動進程都被映射到了一個權值,互動進程隨便睡眠,只要它醒來,它就可以以不太大的(也不會太小,按照它自己的權值和當前的系統虛擬時鐘決定)key被加到紅/黑樹狀結構,隨著系統繼續運行,很公平的它就會運行。之所以O(1)中如果不預測互動進程會導致互動進程的延遲是有原因的,另起一段吧,這一段太長了。

O(1)中導致互動進程延遲響應的原因就是兩個數組存在,一個運行隊列一個到期隊列,按照一般道理,系統依據進程優先順序來分配時間片,只要時間片完畢就會被放到到期隊列,問題就出在這個到期隊列,按照道理,只有所有優先順序的所有進程都放到了到期隊列,也就是所有優先順序的所有進程都運行完畢了,才會交換到期隊列和運行隊列,如果不進行區分的話,系統內啟動並執行進程越多,互動進程看起來響應越遲鈍,因此O(1)中用睡眠時間區分了互動進程和非互動進程,可見在O(1)中,互動進程的延遲主要在所有進程的數量,其實這對於伺服器是無所謂的,但是對於互動進程就不行,因為伺服器處理序強調優先順序下的公平性,而互動進程強調響應性,對於公平性而言,要等只要大家一起等就沒有問題,對於互動進程就根本不允許等待太久,不管怎樣,O(1)調度器都不是很令人滿意,在運行隊列的進程可以看到公平和高效,可是對於到期隊列的進程,面臨卻是無期的等待...在爽完了以後,雖然很多人都喜歡休息一會,但是我相信更多的人喜歡在不久的將來再爽一次。這麼說的話,O(1)的調度周期的粒度就是所有的進程的已耗用時間之和,這個演算法雖然可以保證運行隊列進程的公平性卻無法保證全域的公平性,任何一個進程在運行了不管多久之後,都必須等待很長一段時間,在一個進程的整個生命週期看來是斷斷續續的,在cfs中,任何一個進程的執行都將是連續的,這就是cfs的進步,以前的調度器必須以硬體時鐘為準,因此不能太靈活,cfs以虛擬時鐘為準,靈活性很隨意。

在2.6.23核心中,剛剛實現的cfs調度器顯得很淳樸,每次的時鐘滴答中都會將當前進程先出隊,推進其虛擬時鐘和系統虛擬時鐘後再入隊,然後判斷紅/黑樹狀結構的左下角的進程是否還是當前進程而抉擇是否要調度,這種調度器的key的計算是用當前的虛擬時鐘減去待計算進程的等待時間,如果該計算進程在運行,那麼其等待時間就是負值,這樣,等待越長的進程key越小,從而越容易被選中投入運行;

在2.6.25核心以後實現了一種更為簡單的方式,就是設定一個運行隊列的虛擬時鐘,它單調增長並且跟蹤該隊列的最小虛擬時鐘的進程,key值由進程的vruntime和隊列的虛擬時鐘的差值計算,這種方式就是真正的追趕,比2.6.23實現的簡單,但是很巧妙,不必在每次時鐘滴答中都將當前進程出隊,入隊,而是根據當前進程實際啟動並執行時間和理想應該啟動並執行時間判斷是否應該調度。

cfs的精髓在於它改變了核心看待進程調度的方式,時間片越細越好嗎?搶佔點越多越好嗎?如果是的話,那麼很抱歉,到了2.6.17左右的核心,時間片已經很精細了,而且搶佔點也不能再多了,如果這個推理正確的話,那豈不是說調度器不能繼續發展了嗎,linux絕對不是這樣的性格,O(1)調度器的設計者有破有立,提供了另外一種截然不同的調度方式,這就是cfs,拋棄了時間片,拋棄了複雜的演算法,從一個新的起點開始了調度器的新時代,最開始的2.6.23版本核心的cfs是很簡單的,思想十分明確。cfs的本質思想就是提供一個虛擬時鐘,所有進程複用這個虛擬時鐘的時間,cfs將時鐘的概念從底層體系相關的硬體中抽象出來,進程調度模組直接和這個虛擬時鐘介面而不必再為硬體時鐘操作而操心,如此一來,整個進程調度模組就完整了,從時鐘到調度演算法,到不同進程的不同策略,全部都由虛擬系統提供,也正是在這個新的核心,引入了調度類。因此新的調度器就是不同特性的進程在統一的虛擬時鐘下按照不同的策略被調度。

我們看一下這樣做有什麼好處,cfs拋棄了時間片,採用了平滑的機制,用互相追趕的方式促使所有的進程一起向前走,那麼怎麼區分不同優先順序的進程呢?總不能所有進程以相同的速度往前走吧,顯然不能!我們都相信,用互相追趕的方式是最好的方式,就好像競爭一樣有益,我在中學的時候,老師就教導我們要互相追趕,雖然那個時候老師的意思就是大家都追趕我!既然相信互相追趕時最好的方式,那麼下一步就是怎麼實現互相追趕,如果在傳統的調度體系下,用硬時鐘,那麼很難實現不同進程的不同優先順序的管理,於是提出虛擬時鐘的概念,每個進程都有一個虛擬時鐘,然後整個系統有一個虛擬時鐘,系統虛擬時鐘以固定的步調前進,而各個進程的虛擬時鐘的前進步調卻因為其優先順序不同而不同,比如優先順序低的進程其虛擬時鐘的步調比較快,而優先順序高的步調比較慢,這一點用硬體時鐘是很難做到的,如果用硬體時鐘,我們就要維護每一個進程的狀態,然後將這個每個進程的狀態設定為一個全域的變數,可想而知,這個變數應該是個鏈表或者數組,每當硬體時鐘中斷的時候都要尋找這個鏈表進行尋找,刪除,選舉等操作,十分繁瑣,不說時間,空間上佔用的記憶體都無法接受。cfs提出的虛擬時鐘概念使得互相追趕更為容易實現,基於時間片的調度機制中,進程調度是被動的,調度模組不得不想辦法探知每個進程的特點並且根據不同的特性設定給它們不同的策略,然後依據這些不同的策略分配給它們不同的時間片,這樣必然會出現變態級的預測演算法,很複雜,讓學究們看來可以為我們賣弄一把,可是這個世界不喜歡複雜,因此學究們必須退讓;現在看看cfs調度器,進程有自己的優先順序,並且映射到權值,每個權值的進程的虛擬時鐘步調不同,大家都按照自己的虛擬時鐘往前走就是了,調度模組會選擇最落後於系統虛擬時鐘的進程來執行,這就是公平的含義,那麼在O(1)調度器中對互動進程的預測演算法在cfs中怎麼體現呢?其實完全沒有必要考慮這個問題,因為在O(1)調度器中,之所以要區分互動進程是因為O(1)調度器完全是基於優先順序來調度的,其它所有的調度依據都需要動態預測,而動態預測就必然需要複雜的演算法,在cfs調度器中,不單單有優先順序作為調度依據了,其實優先順序映射到了進程權值,然後各個進程互相追趕,這樣可以保證任何進程都不會被耽擱太久,互動進程的問題就解決了,O(1)調度器不能這樣的原因就是因為進程們不能自己互相追趕。舉個例子,就是在O(1)中,一個互動進程和一個非互動進程的優先順序都是p,調度器僅僅根據它們的優先順序來進行調度,別的什麼也不知道,只有靠探測它們的睡眠時間來進行進程類別的判斷,通過判斷如果一個進程是互動進程,那麼就暫且不把它放到到期隊列而是繼續運行用來補償它過多的睡眠,而在cfs調度器中就不會這樣,即使一個互動進程和一個非互動進程都被映射到了一個權值,互動進程隨便睡眠,只要它醒來,它就可以以不太大的(也不會太小,按照它自己的權值和當前的系統虛擬時鐘決定)key被加到紅/黑樹狀結構,隨著系統繼續運行,很公平的它就會運行。之所以O(1)中如果不預測互動進程會導致互動進程的延遲是有原因的,另起一段吧,這一段太長了。

O(1)中導致互動進程延遲響應的原因就是兩個數組存在,一個運行隊列一個到期隊列,按照一般道理,系統依據進程優先順序來分配時間片,只要時間片完畢就會被放到到期隊列,問題就出在這個到期隊列,按照道理,只有所有優先順序的所有進程都放到了到期隊列,也就是所有優先順序的所有進程都運行完畢了,才會交換到期隊列和運行隊列,如果不進行區分的話,系統內啟動並執行進程越多,互動進程看起來響應越遲鈍,因此O(1)中用睡眠時間區分了互動進程和非互動進程,可見在O(1)中,互動進程的延遲主要在所有進程的數量,其實這對於伺服器是無所謂的,但是對於互動進程就不行,因為伺服器處理序強調優先順序下的公平性,而互動進程強調響應性,對於公平性而言,要等只要大家一起等就沒有問題,對於互動進程就根本不允許等待太久,不管怎樣,O(1)調度器都不是很令人滿意,在運行隊列的進程可以看到公平和高效,可是對於到期隊列的進程,面臨卻是無期的等待...在爽完了以後,雖然很多人都喜歡休息一會,但是我相信更多的人喜歡在不久的將來再爽一次。這麼說的話,O(1)的調度周期的粒度就是所有的進程的已耗用時間之和,這個演算法雖然可以保證運行隊列進程的公平性卻無法保證全域的公平性,任何一個進程在運行了不管多久之後,都必須等待很長一段時間,在一個進程的整個生命週期看來是斷斷續續的,在cfs中,任何一個進程的執行都將是連續的,這就是cfs的進步,以前的調度器必須以硬體時鐘為準,因此不能太靈活,cfs以虛擬時鐘為準,靈活性很隨意。

在2.6.23核心中,剛剛實現的cfs調度器顯得很淳樸,每次的時鐘滴答中都會將當前進程先出隊,推進其虛擬時鐘和系統虛擬時鐘後再入隊,然後判斷紅/黑樹狀結構的左下角的進程是否還是當前進程而抉擇是否要調度,這種調度器的key的計算是用當前的虛擬時鐘減去待計算進程的等待時間,如果該計算進程在運行,那麼其等待時間就是負值,這樣,等待越長的進程key越小,從而越容易被選中投入運行;

在2.6.25核心以後實現了一種更為簡單的方式,就是設定一個運行隊列的虛擬時鐘,它單調增長並且跟蹤該隊列的最小虛擬時鐘的進程,key值由進程的vruntime和隊列的虛擬時鐘的差值計算,這種方式就是真正的追趕,比2.6.23實現的簡單,但是很巧妙,不必在每次時鐘滴答中都將當前進程出隊,入隊,而是根據當前進程實際啟動並執行時間和理想應該啟動並執行時間判斷是否應該調度。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.