日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

linux進程調(diào)度之總章:一些片湯話

 豆芽愛尚閱 2015-09-22
         最近幾天結(jié)合源碼看了很多l(xiāng)inux進程調(diào)度的文章,雖然掌握了個大概,但是越看,細節(jié)越多,寫這篇文章的信心也就越不足,曾有系列文章叫鼠眼看linux進程調(diào)度,很符合我現(xiàn)在的心境,就像盲人摸象,學到一些東西,很驚喜,但是總有一種力不從心的惶恐。但是好久沒寫博文了,還是寫一篇。寫的不對的地方,請大家批評指正。

    CPU是一種寶貴的資源,Linux是多任務(wù)的OS,這種多任務(wù)要求,對于每個任務(wù)或者說進程來說,就好像它獨占了CPU。想想如果只有一個CPU,但是有80個處于TASK_RUNNING狀態(tài)的進程,在這八十個進程選擇進程,切換進程是多么困難。如果你理解不了這種難度,你可以想想如果你同時有80個女朋友,性格迥異,愛好不同,要做到每個女朋友都認為她自己是你唯一的女友是多么的困難。

   劉明在《Linux 調(diào)度器BFS簡介》中有個很有意思的比喻,linux 內(nèi)核調(diào)度器就像處境尷尬的主婦,滿足孩子對晚餐的要求便有可能傷害到老人的食欲,做出一桌讓男女老少都滿意的飯菜實在是太難了。Linux是一個通用的操作系統(tǒng),無法預測運行其上的進程有什么樣的特點,就像一家人的口味各不相同,孩子喜歡吃甜,爸爸喜歡吃咸,老人喜歡口味清淡,所以調(diào)度器也很為難。

    一般來說根據(jù)進程的特點,可以將進程分成幾類
1 交互式進程
   這個比較簡單了,想想你你使用vi編輯文本,大量的人機交互,進程不斷的進入睡眠狀態(tài)等待你的輸入,CPU占用不高但是要求響應(yīng)迅速,比如你敲了鍵盤,過了10秒鐘才在編輯器上顯示出來,這用戶體驗是多么的糟糕。

2 批處理進程
    最典型的就是編譯工程這種進程了,如果我們編譯一個大型的工程,我們敲了個make,也許1個小時才能編譯成功,但是沒有人會兩個眼睛盯著屏幕看編譯的過程,我們更關(guān)心的是編譯的結(jié)果。對于這種進程就是屬于姥姥不疼舅舅不愛的進程,這要他在跑就行了,不必給他太多的關(guān)注和資源。

3 實時進程
    實時進程原本的含義是給定的工作要在指定的時間內(nèi)完成,不要求你多快,但是一定要在指定的時間前完成指定的任務(wù),多用在火箭 導彈類似的精密系統(tǒng)中。這種實時叫做硬實時,對于Linux 這種通用的OS來講,完全做到硬實時有點強人所難了,中斷,磁盤尋道,總線征用 鎖,等很多的機制帶來了太多的不確定性,很難做到硬實時。

    linux所說的實時進程是軟實時,就是盡量的實時,如果做不到,也不會出現(xiàn)毀滅性的后果。比如視頻播放器,解碼速度有點慢,頂多是視頻播放有點卡,用戶體驗不好,但是不會機毀人亡。

    不同的進程,就用不同的調(diào)度策略伺候之,對于實時進程,我們就采用實時調(diào)度策略:FIFO or Round Robin(時間片輪轉(zhuǎn))。對于批處理進程和交互進程,我們采用CFS調(diào)度器。在之前的版本,Linux采用O(1)調(diào)度器的時候,有復雜的方法識別交互性進程,獎勵交互性進程,算法比較復雜,現(xiàn)在采用CFS調(diào)度器后,核心思想比較簡單“完全公平”,降低了代碼復雜度,很好地滿足了各種需求。

    先說說實時調(diào)度,實時調(diào)度有兩個維度1 優(yōu)先級2 調(diào)度策略。linux用戶程序可以通過調(diào)用sched_setscheduler系統(tǒng)調(diào)用來設(shè)置進程的優(yōu)先級和調(diào)度策略。

    實時進程共有0~99共100種不同的優(yōu)先級,0優(yōu)先級最高,99優(yōu)先級最低,對應(yīng)100個隊列。對于實時進程來說,高優(yōu)先級實時進程存在,低優(yōu)先級的實時進程就撈不著CPU資源,普通進程更撈不著CPU資源。
    接下來就是調(diào)度策略,一種是FIFO,先進先出,如果最高優(yōu)先級的進程是FIFO類型,那么他就一直執(zhí)行,一條路跑到黑,直到進程退出,或者它調(diào)用sched_yield主動讓出資源,或者突然出現(xiàn)更高優(yōu)先級的進程橫空出世,搶占了它的CPU。另外一種是時間片輪轉(zhuǎn),假如說最高優(yōu)先級實時進程隊列存在多個進程,當前進程耗盡自己時間片后自動排到隊尾,選擇同一個隊列的隊列頭部的進程去執(zhí)行。這些事情是在task_tick_rt函數(shù)做的。

    
    前面提到實時進程存在,普通進程完全撈不到CPU資源也不完全對,后來LINUX增加組調(diào)度策略后,有/proc/sys/kernel/sched_rt_period_us和/proc/sys/kernel/sched_rt_runtime_us兩個參數(shù),這兩個參數(shù)表示的含義是:在sched_rt_peroid_us的周期內(nèi),所有的實時進程運行時間之和不得超過sched_rt_runtime_us。 默認值為1秒和0.95秒換句話說,在1秒的周期以內(nèi),所有實時進程運行時間之和不得超過0.95秒,剩下的0.5秒鐘留給普通進程。

    對于普通進程的CFS調(diào)度器,內(nèi)容相對比較獨立,如果有時間,后面會有專門的博文總結(jié)。

2 SMP時代的進程調(diào)度

    更要命的是現(xiàn)在進入了多核的時代,縱然不談服務(wù)器的高配置,我的筆記本配置不高,也已經(jīng)是四核,可見多核計算機已經(jīng)是滿大街了。對于負載的SMP,就引入了新的問題。單核的時候,只有一個CPU,不需要考慮選擇幾個運行隊列,就是一個run queue。但是多核的時候,是建立一個run queue,所有的CPU去run queue上選擇摘取可執(zhí)行的進程,還是每個CPU一個run queue?其實都是可以的。

    1 per cpu run queue
     目前l(fā)inux 內(nèi)核采用的是per cpu run queue,每個CPU去自己的run queue 去選擇可執(zhí)行的進程,這樣減少  了競爭。其實除了這個好處,還有另外一個甚至更重要的好處,緩存重利用。進程落在這個CPU的運行隊列上,經(jīng)過多次調(diào)度后(暫不考慮多CPU的load balance),仍然是同一顆CPU運行這個進程,也許上次運行時的變量 內(nèi)存還在cache中,如果只有一個運行隊列,多個CPU的話,上次執(zhí)行所在的CPU和這次執(zhí)行所在的CPU很可能不是同一顆CPU,那么上次執(zhí)行調(diào)入的緩存就完全用不上了。

    2 single run  queue
    所有的CPU使用同一個隊列,這也是可以的,有些人覺著太土,因為如果一個CPU 訪問run queue的時候,其他的CPU 就不能訪問run queue了,一把大鎖降低了性能,尤其是當CPU特別多的時候,想想如果你有1024個CPU,然而只有一個運行隊列,run queue這個瓶頸就是顯而易見的了。

    介紹到這里,很多筒子可能就會說了,那還有啥好糾結(jié)的,肯定是per cpu run  queue 更優(yōu)越。但是實際情況要比理論復雜的多。BFS(Brain Fuck Scheduler ,又稱腦殘調(diào)度器)就是一種單一隊列的調(diào)度器,這種調(diào)度器對于桌面應(yīng)用來說,效果非常的好。感興趣的筒子可以閱讀《Linux調(diào)度器BFS簡介》《BFS,Linux桌面的極速未來》

     per cpu run queue也不是完全沒有缺點。既然是多個隊列,就會有可能不均衡,比如一個CPU忙的要死,另一個CPU無事可做,這種情景本身也是對CPU資源的浪費。內(nèi)核為了解決這個問題就必須要發(fā)起CPU間的負載均衡load balance,兩個CPU之間負載均衡,要獲取兩個run queue的鎖,會傷害并發(fā),除此以外,負載均衡本身也消耗CPU資源。

    我們按照我們的硬件常識,如果我有兩顆物理CPU,每顆物理CPU有兩個核,那么我的CPU就是4核的,每個核又可以通過SMT(Simultaneous Multi-Threading)類似的技術(shù)實現(xiàn)多個硬件線程或者叫做Virtual CPU,比如Intel的超線程技術(shù),如果每個核可以實現(xiàn)2個Virtual CPU,那么我的硬件就有8個Virtual CPU。這些Virtual CPU 之間的親緣關(guān)系是不同的。

    為了應(yīng)對多核多CPU,Linux引進了調(diào)度域的概念,其實就是根據(jù)的親緣關(guān)系的遠近,劃分不同的范圍。根據(jù)親緣關(guān)系的遠近從近到遠分成四個層次:
1 超線程
同一個核利用超線程技術(shù)演化出來的Virtual CPU。我們知道CPU的速度要比內(nèi)存訪問的速度快,如果cache沒有命中,CPU在等待內(nèi)存的時間里面無事可做,這是一種浪費,就切換到其他線程。這樣多個線程分時復用一個核。說實話,這個超線程技術(shù)我其實并不是特別理解,改天研究下Intel手冊看個究竟。

2 同一個物理CPU的不同Core

3 同一個NUMA結(jié)點上的不同物理CPU

4 不同NUMA節(jié)點上的物理CPU。


    NUMA(非一致性內(nèi)存系統(tǒng)),CPU和RAM是以結(jié)點為單位分組的,同一個CPU訪問本結(jié)點內(nèi)的本地RAM代價要比訪問其他節(jié)點的RAM代價低。CPU親緣關(guān)系越近,他們之間進程遷移的代價越低。比如說,將進程在同一個物理CPU下的兩個Core之間遷移,代價要低于不同物理CPU之間的遷移,原因就是一部分cache可以繼續(xù)使用。

    load balance,就是將進程從一個CPU(廣義的CPU)遷移到另一個CPU,如果將進程從一個核的一個超線程域搬到另一個超線程域,沒啥關(guān)系,因為代價不高,就好像讓我從辦公樓4樓搬到辦公樓3樓,代價很低,但是CPU親緣關(guān)系越遠,代價越高,就好像上午還在南京上班,下午讓我搬到烏魯木齊上班,所以這種搬家盡量要少。事實上linux 內(nèi)核也是這么做的。

    OK,繼續(xù)我們的調(diào)度域:假如我們有兩個物理CPU,每個物理CPU有兩個Core,每個Core有通過超線程演化出兩個Virtual CPU,那么我們看下下面這個圖(這個圖是從Linux內(nèi)核SMP負載均衡淺析中拷貝的)

     對于每個virtual CPU,屬于一組調(diào)度域sched_domain,就像我是位于雨花區(qū)的,同時我也是位于南京,我還是江蘇的,我還是位于中國的,我隸屬的不同區(qū)域反應(yīng)的不過是不同層次看我所處的位置。每個調(diào)度域分成多個組,就好像中國分成30多個省級行政單位,每個省級行政單位又分成不同的市,每個市又分成不同的區(qū)。

    這還只是普通進程的SMP 調(diào)度,想想實時進程,我們每個CPU都有隊列,也許CPU-a的最高優(yōu)先級的實時進程尚不如 CPU-b第二高優(yōu)先級的實時進程,這時候,需要將CPU-b中的實時進程拽到CPU-a上面執(zhí)行,不然,會出現(xiàn)低優(yōu)先級的實時進程先執(zhí)行的異常情況,這個拽的過程是有pull_rt_task 實現(xiàn)的。

參考文獻   
Linux內(nèi)核SMP負載均衡淺析
2 Linux 進程調(diào)度淺析
3 鼠眼看Linux調(diào)度器
4 Linux調(diào)度器BFS簡介
5 BFS,Linux桌面的極速未來

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多