CFS調度器中子進程被喚醒後的細節–實驗和理論

來源:互聯網
上載者:User

在我提交並自己打上child-runs-first補丁之前,我做了一個實驗,目的是驗證一下我先前理論分析的結果,我覺得子進程無論如何搶佔父進程的幾率都會比不搶佔要大些,當然前提是要有的,具體見下面的實驗。空有理論是沒有用的,理論上cfs調度器執行嚴格的歸一化,然而實際上卻不是那樣的,實踐結果永遠比理論更加現實,因為不執行歸一化絲毫影響不了cfs調度器選擇最小vruntime的進程,這很簡單,每一個進程按照自己的權值和當前的系統調度周期執行動態時間片的時間,同時按照不同的速率推進自己的虛擬時間,調度器只要能保證各個進程在運行按照其權值分給它們的不同時間片之後可以向前推進相同的虛擬時間就可以了,管他什麼歸一化呢?正是這樣,cfs調度器啟動並執行很好。

環境:單cpu,HZ=250,linux-2.6.28原始核心(沒有打我的child_runs_first補丁)

核心配置與實驗前提:sysctl_sched_child_runs_first=0,sysctl_sched_features=(僅開啟AKEUP_PREEMPT),sysctl_sched_wakeup_granularity=0,sysctl_sched_latency_ns=20000000.

目的:在沒有sysctl_sched_child_runs_first策略的情況下測試cfs調度器在子進程被喚醒時的行為

測試程式:

-------stub--------

/*類比cpu進程,將cfs_rq的nr_running提高到一定數量*/

int main(int argc,char*argv[] )

{

nice(atoi(argv[1]));

int a = 1,b=0;

while(a++||1)

{

b+=a;

}

}

-------child_run_delay--------

/*父進程延遲一會再fork,避免托shell在fork父進程時給了父進程min_vruntime的福*/

#include

#include

#include

int main(int argc,char *argv[])

{

int v = atoi(argv[1]);

nice(v);

unsigned long i = 1000000;

while(i-->0)

{

v++;

}

if(fork() == 0)

{

printf("sub/n");

exit(0);

}

printf("main,%d/n",v);

}

-------child_run_nodelay--------

/*馬上fork子進程,托父進程vruntime很小的福*/

#include

#include

#include

int main(int argc,char *argv[])

{

int v = atoi(argv[1]);

nice(v);

if(fork() == 0)

{

printf("sub/n");

exit(0);

}

printf("main/n");

}

測試過程:連續建立9個stub進程,nice值分散開來,然後以不同的nice值運行child_run_delay和child_run_nodelay。

結果:

測試代碼中i=1000時的測試結果

 

child_run_delay

child_run_nodelay

nice 15

96%preempt

95%preempt

nice 10

96%preempt

94%preempt

nice -10

70%preempt

12%preempt

nice -17

64%preempt

10%preempt

nice -20

11%preempt

4%preempt

測試代碼中i=10000000時的測試結果

 

child_run_delay

child_run_nodelay

nice 15

36%preempt

96%preempt

nice 10

33%preempt

96%preempt

nice -10

24%preempt

10%preempt

nice -17

15%preempt

9%preempt

nice -20

9%preempt

6%preempt

結果分析:

child_run_delay進程和child_run_nodelay進程的建立也是shell執行fork而來的,那時這些進程將被賦予cfs_rq的min_vruntime,不論如何,這個vruntime是所有運行進程的最小的vruntime,包括正在執行的curr(因為min_vruntime在update_curr中被即時更新),cfs_rq的min_vruntime是單調遞增的,只有在當前進程是最後一個被落下的進程時,cfs_rq的min_vruntime才會和curr的vruntime相等,也就是說cfs_rq的min_vruntime永遠是最小的vruntime,這個比2.6.28以前的有所改進,不會拉大進程間vruntime的距離從而造成對vruntime值大的進程的不公平。既然child_run_delay進程和child_run_nodelay進程的vruntime是最小的,那麼如果它們的nice值小的話,其虛擬時鐘推進慢,到了fork的時候其vruntime可能還是最小的,於是根據代碼和核心配置,搶佔的幾率就會變小。什麼叫變小呢?誰和誰比呢?其實就是main剛執行的時候和fork的時候比較,另外還有一個比較,就是delay程式和nodelay程式的比較,對於nodely,搶佔的幾率更小,因為父進程趁著自己的vruntime最小的時候,幾乎是馬上就fork了子進程,此時子進程被賦予最小的min_vruntime,而此時此vruntime很大很大幾率就是父進程的還沒有推進幾步vruntime,如果父進程的nice值很小,推進的更慢,不搶佔的幾率更大,但是如果父進程的nice值很大的話,虛擬時鐘即vruntime推進的很快,稍微一執行就不是最小的了,那麼到了fork的時搶佔就是很大幾率的事情了。

sched_latency_ns比較小,vruntime推進很活躍的情況下,即使執行-20的nice值的child_run_delay測試進程也可能發生搶佔並且幾率很大,這好像和上面一段的分析結果相反,為什麼,因為在執行了很大一會後並且執行的都是cpu指令,沒有睡眠之類的,該進程的vruntime即使權值再高它也不一定是在一個系統調度周期(sysctl_sched_latency_ns)最後一個啟動並執行進程,更何況由於進程的不確定的睡眠喚醒建立退出,嚴格的虛擬時鐘歸一化已經被打亂,只要不是最後一個啟動並執行進程,也就是說只要說這個進程不是被落下的那一個,那麼該進程的vruntime就一定大於cfs_rq的min_vruntime,於是該進程在fork子進程的時候,由於cfs_rq的min_vruntime給了新進程,那麼新進程的vruntime會小於current(即高權值的父進程)的vruntime,如果搶佔粒度很小的話,那麼子進程就會搶佔父進程,而我們為了使事情簡單化將搶佔粒度設定為0,於是搶佔發生。可是如果高權值的父進程如果是最後一個啟動並執行,那麼由於它的虛擬時鐘推進很慢,因此很大的幾率下其vruntime將一直是cfs_rq的min_vruntime,如果是,那麼搶佔不發生,可是即使該種情況下該進程的vruntime和cfs_rq的vruntime相等的幾率再大,該進程被落下為最後一個的幾率本身就很小,畢竟每一個進程被落下為最後一個都有可能,因此不論如何,發生搶佔的幾率還是要比不發生搶佔的幾率大,符合測試,如果將活動進程的數量減小,那麼不發生搶佔的幾率會變大,但是統計意義上還是高不過發生搶佔的幾率,fork前執行cpu指令的時間越長,效果越明顯。

被隱形真相:如果將child_run_delay中的i值減小,結果就是越低nice值的進程越不容易發生搶佔,高nice值的幾乎都會搶佔。這其實是shell在執行我們的測試程式時引入的,原因見上述分析,i的值足夠小,i--的迴圈時間沒有到達該父進程的動態時間片,因此就會出現容易誤導使用者的結果。

事情的真相:不要以為權值大的進程就會被最後運行,不要以為權值大的進程的vruntime就一定是cfs_rq的min_vruntime,不是這樣的,以理想情況分析,一個調度周期內誰最後運行是不一定的,要看它們入隊的順序以及入隊時紅/黑樹狀結構的既有情況。在不藉助父進程被shell建立時被賦予很小的vruntime的優勢的情況下,也就是fork之前不睡眠不阻塞運行足夠長的時間的情況下,fork時的子進程搶佔父進程的幾率更大些,和父進程的優先順序沒有必然關係,只能說相同條件下低權值的進程搶佔絕對幾率更大些但是永遠不會超過不搶佔發生的幾率,因為那麼多進程只要父進程不是最後一個啟動並執行那麼就不會搶佔,而每個進程最後一個啟動並執行機會近乎均等。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.