1. 程式人生 > >linux排程器(六)——應用層理解CFS及組排程

linux排程器(六)——應用層理解CFS及組排程

         上面我們介紹了CFS及組排程相關的主要內容,但可能很多人還跟我一樣有點雲裡霧裡的,下面我們直接從應用層面上也檢視CFS及組排程的效果。首先對於非組排程,決定它們執行時間的唯一因素就是weight,也就是我們知道的nice,我們可以通過renice來重新調整程序的優先順序,然後再使用taskset將它們限定在同一個CPU上(CFS只是保證一個CPU的公平,所以你可以看到一個有趣的現象:如指定兩個程序的CPU_ALLOWS都有3,4,然後他們的優先順序不一樣0,3,結果是它們的CPU使用時間是一樣的。如果再執行一個0級的程序會怎樣?再把它改為5級?——SMP)。
    下面我們看一下組排程,為了便於理解及檢視proc資訊,我們建立一個包括cpu,cpuset子系統的cgroup(mount –tcgroup –o cpu,cpuset none /cgroup/cpu),然後再在下層建立一個one group,並且它的catcpuset.cpus =3,cat cpuset.cpu_exclusive=1(即該cgroup下的程序只在3號cpu上執行,並且這個cpu是獨佔的)。我們的例子如下:


圖 CFS組排程例項

         我們的目的就是通過這張圖算出每個程序(一個死迴圈的程序)應該使用的CPU資源,並且算出它們對應的cfs_rq的load,以及它們各自的執行時間片,最後再與proc上的資訊進行驗證。
    組排程的核心思想:每個層級的組按權重去分攤CPU時間給它下面的就緒排程實體(se),每個排程實體獲得這個時間後再按照同樣的方法遞迴分攤給它下面的就緒se。
         首先我們通過圖可以知道:one這個group下面管理著3個se(其中2個group,即onese->my_q下組織著3個se,而one se->cfs_rq則是指向根’/’的se),依其類推;另外,通過查表prio_to_weight[],可知17444程序對應的load是335(NICE=5, NICE=0 load=1024),則每個程序的se->weight.load:17443(1024);17444(335);17445(1024);17446(1024)。進而可以算出每個group執行佇列的權重:[big]cfs_rq->load=[17443]se->weight.load + [17444]se->weight.load = 1024+335 = 1359;[small]cfs_rq->load= [17446]se->weight.load = 1024;[one]cfs_rq->load= [big]se->weight.load + [17445]se->weight.load +[small]se->weight.load = 2048 + 1024 + 512 = 3584;[/]cfs_rq->load= [one]se->weight.load = 1024(這裡是因為我們的CPU 3被強佔了,其它的程序不會再過來,所以’/’也就只有one一個se)。這樣我們就可以算出每個se佔用的CPU比例(按100%分配):[big]2048/3584

;[17445]1024/3584;[small]512/3584;因為big下面還有兩個程序,所以[17443]1024/1359* 2048/3584;[17444]335/1359 * 2048/3584;即最後從左到右的比例分別是:43.1%;14.1%;28.6%;14.3%。我們再從核心角度來看一下上面的組關係:


圖 組排程的內部關係

         該圖與上圖的節點位置是相互對應,另外我們把相應的欄位也改成了核心的使用方式。另外根據這些值就可以計算出每個程序的執行時間片(理想)。這裡我們不再去計算讀者可以按照sched_slice()函式的方法去計算一下,要注意的是對於組排程應該回朔計算到根才能得出該se所應該執行的時間。上面值的結果可以通過/proc/sched_debug來驗證。考慮上面我們所說的情況,如果cpu_allows為3,4,然後建立兩個程序,它們的cfs_rq load是多少?group的se->load.weight又是多少?【update_cfs_load,update_cfs_shares】