標籤:服務 nic user 高效能 執行 動態 成員 lan 佔用
核心在微觀上,把CPU的已耗用時間分成許多分,然後安排給各個進程輪流程執行,造成宏觀上所有的進程彷彿同時在執行。雙核CPU,實際上最多隻能有兩個進程在同時運行,大家在top、vmstat命令裡看到的正在啟動並執行進程,並不是真的在佔有著CPU哈。
所以,一些設計良好的高效能進程,比如nginx,都是實際上有幾顆CPU,就配幾個背景工作處理序,道理就在這。比如你的伺服器有8顆CPU,那麼nginx worker應當只有8個,當你多於8個時,核心可能會放超過多個nginx worker進程到1個runqueue裡,會發生什麼呢?就是在這顆CPU上,會比較均勻的把時間分配給這幾個nginx worker,每個worker進程運行完一個時間片後,核心需要做進程切換,把正在啟動並執行進程上下文儲存下來。假設核心分配的時間片是100ms,做進程切換的時間是5ms,那麼進程效能下降還是很明顯的,跟你配置的worker有關,中老年女裝越多下降得越厲害。
當然,這是跟nginx的設計有關的。nginx是事件驅動的全非同步進程,本身設計上就幾乎不存在阻塞和中斷,nginx的設計者就希望每一個nginx worker可以獨佔CPU的幾乎全部時間片,這點就是nginx worker數量配置的依據所在。
當然,實際的運行進程裡,大部分並不是nginx這種希望獨佔CPU全部時間片的進程,許多進程,比如vi,它在很多時間是在等待使用者輸入,這時vi在等待IO中斷,是不佔用時間片的,核心面對多樣化的進程,就需要技巧性的分配CPU時間片了。
核心分配時間片是有策略和傾向性的。換句話說,核心是偏心的,它喜歡的是IO消耗型進程,因為這類進程如果不能及時響應,使用者就會很不爽,所以它總會下意識的多分配CPU已耗用時間給這類進程。而CPU消耗進程核心就不太關心了。這有道理嗎?太有了,CPU消耗型慢一點使用者感知不出來,電訊號和生物訊號運轉速度差距巨大。雖然核心盡量多的分配時間片給IO消耗型進程,但IO消耗進程常常在睡覺,給它的時間片根本用不掉。很合理吧?
那麼核心具體是怎麼實現這種偏心呢?通過動態調整進程的優先順序,以及分配不同長短的CPU時間處來實現。先說核心如何決定時間片的長度。
對每一個進程,有一個整型static_prio表示使用者佈建的靜態優先順序,核心裡它與nice值是對應的。看看進程描述結構裡的static_prio成員。
nice值是什嗎?其實就是優先順序針對使用者進程的另一種標記法,nice的取值範圍是-20到+19,-20優先順序最高,+19最低。上篇曾經說過,核心優先順序共有140,而使用者能夠設定的NICE優先順序如何與這140個優先順序對應起來呢?看代碼:
可以看到,MAX_PRIO就是140,也就是核心定義的最大優先順序了。
而MAX_USER_PRIO就是40,意指,普通進程指定的優先順序別最多40,就像前面我們講的那樣-20到+19。
nice值是-20表示最高,對應著static_prio是多少呢?NICE_TO_PRIO(0)就是120,NICE_TO_PRIO(-20)就是100。
當該進程剛被其父進程fork出來時,是平分其父進程的剩餘時間片的。這個時間片執行完後,就會根據它的初始優先順序來重新分配時間片,優先順序為+19時最低,只分配最小時間片5ms,優先順序為0時是100ms,優先順序是-20時是最大時間片800ms。我們看看核心是如何計算時間片長度的,大家先看下task_timeslice時間片計算函數:
linux核心調度演算法(2)--CPU時間片如何分配