Linux內核——進程管理之SMP負載均衡(基於版本4.x)

《奔跑吧linux內核》3.3筆記,不足之處還望你們批評指正linux

根據實際物理屬性,CPU域分類如圖1所示。負載均衡

圖1 CPU域分類函數

問題一:一個4核處理器中的每一個物理CPU擁有獨立L1 cache且不支持超線程技術,分紅兩個簇cluster0和cluster1,每一個簇包含兩個物理CPU核,簇中的CPU核共享L2cache。請畫出該處理器在Linux內核裏調度域和調度組的拓撲關係圖。spa

   4核處理器關係圖如圖2所示,在不支持超線程技術的狀況下,每一個CPU核心只有一個執行線程,因此4核處理器沒有SMT屬性。cluster由兩個CPU物理核組成,這兩個CPU是MC層級且是兄弟關係。整個處理器能夠看做DIE級別,所以該處理器只有兩個層級,即MC和DIE。根據上述原則,畫圖圖3所示上述4核處理器的調度域和調度組的拓撲關係圖。線程

圖2 4核處理器示意圖3d

圖3 4核處理器調度域和調度組的拓撲關係圖blog

問題二:假設CPU0和CPU1同屬於一個調度域中且它們都不是idle CPU,那麼CPU1能夠作負載均衡嗎?進程

   CPU1不能夠作負載均衡,默認約定優先由調度域中第一個CPU作負載均衡。此時,只有CPU0能作負載均衡,或者當CPU0不是空閒CPU,CPU1處於idle狀態,CPU1才能夠作負載均衡。ci

問題三:如何查找出一個調度域裏最繁忙的調度組?it

   在find_busiest_group()函數中,簡單概括步驟以下:

  1)首先遍歷該調度域中每一個調度組,計算各個調度組中的平均負載等相關信息;

  2)根據平均負載,找出最繁忙的調度組;

  3)獲取本地調度組的平均負載(avg_load)和最繁忙調度組的平均負載,以及該調度域的平均負載;

  4)本地調度組的平均負載大於最繁忙組的平均負載,或者本地調度組的平均負載大於調度域的平均負載,說明不適合作負載均衡,退出這次負載均衡處理;

  5)根據最繁忙組的平均負載、調度域的平均負載和本地調度組的平均負載來計算該調度域的須要遷移的負載不均衡值。

問題四:若是一個調度域負載不平衡,請問如何計算須要遷移多少負載量呢?

   計算方式如圖4所示。當最繁忙的調度組合本地調度組都出現group_overloaded的狀況下才會計算load_above_capacity,busiest.gcf指最繁忙調度組裏的group_capacity_factor。公式查看最繁忙調度組的平均負載(組裏每一個CPU的平均負載,不是組的總負載)和本地調度組的平均負載,以及整個調度域的平均負載的差值來計算該調度域的負載不均衡值(env->imbalance)。最後若是計算出來的不均衡值比最繁忙域裏的每一個進程平均負載小,那麼調用fix_small_imbalance()函數,該函數計算最小的不均衡值。(SCHED_CAPACITY_SCALE爲1024)

圖4 須要遷移的負載量的計算方式

問題五:使用內核提供的喚醒進程API,好比wake_up_process()來喚醒一個進程,那麼進程喚醒後應該在哪一個CPU上運行呢?是調用wake_up_process()的那個CPU,仍是該進程以前運行的那個CPU,或者其餘CPU呢?

   喚醒CPU記做wakeup CPU,上次運行的CPU稱爲prev CPU。

  若是設置了SD_BALANCE_WAKE,在select_idle_sibling()函數中,優先選擇idle CPU。若是沒有idle CPU,就只能選擇wakeup CPU和prev CPU。當找到一個具備親和性的調度域且wakeup CPU和prev CPU不是一個CPU,wake_affine()函數會從新計算wakeup CPU和prev CPU的負載狀況,若是wakeup CPU的負載加上被喚醒進程的負載比prev CPU小,那麼wakeup CPU能夠喚醒進程,不然選擇prev CPU。

  對於沒有設置SD_BALANCE_WAKE的狀況,變量sd指系統調度域中和sd_flag有相同標誌位的調度域,而後開始向下遍歷查找最清閒的調度組和最清閒的CPU喚醒進程。

相關文章
相關標籤/搜索