英語

排程器 Nice 設計

本文件解釋了新 Linux 排程器中改進和精簡的 nice 級別實現的設計思路。

在 Linux 下,Nice 級別一直比較弱,人們不斷地要求我們讓 nice +19 的任務佔用更少的 CPU 時間。

不幸的是,這在舊排程器下不容易實現(否則我們早就做了),因為 nice 級別支援在歷史上與時間片長度耦合,而時間片單位由 HZ 時鐘驅動,因此最小的時間片是 1/HZ。

在 O(1) 排程器(在 2003 年)中,我們將負 nice 級別改為比 2.4 版本中更強(人們對這個改變感到滿意),並且我們還有意地校準了線性時間片規則,以便 nice +19 級別_正好_是 1 個 jiffy。為了更好地理解,時間片圖表如下所示(簡陋的 ASCII 藝術警告!)

                  A
            \     | [timeslice length]
             \    |
              \   |
               \  |
                \ |
                 \|___100msecs
                  |^ . _
                  |      ^ . _
                  |            ^ . _
-*----------------------------------*-----> [nice level]
-20               |                +19
                  |
                  |

因此,如果有人真的想重新調整任務的 nice 值,+19 會比正常的線性規則產生更大的影響。(早期就放棄了更改 ABI 以擴充套件優先順序的解決方案。)

這種方法在一段時間內有效,但後來隨著 HZ=1000,1 個 jiffy 變成了 1 毫秒,這意味著 0.1% 的 CPU 使用率,我們覺得這有點過度。過度_不是_因為它是一個太小的 CPU 利用率,而是因為它會導致太頻繁的(每毫秒一次)重新排程。(因此會破壞快取等等。請記住,這是很久以前的事情,硬體較弱且快取較小,並且人們正在以 nice +19 執行數值計算應用程式。)

因此,對於 HZ=1000,我們將 nice +19 更改為 5 毫秒,因為這感覺是正確的最小粒度 - 這轉化為 5% 的 CPU 利用率。但是對於 nice+19 的基本 HZ 敏感屬性仍然存在,我們從未收到過關於 nice +19 在 CPU 利用率方面太_弱_的任何投訴,我們只收到(仍然)它太_強_的投訴 :-)

總而言之:我們一直希望使 nice 級別更加一致,但在 HZ 和 jiffy 及其與時間片和粒度之間糟糕的設計級別耦合的約束下,這實際上是不可行的。

關於 Linux 的 nice 級別支援的第二個(不太頻繁但仍然週期性發生)投訴是其圍繞原點的不對稱性(您可以在上面的圖片中看到演示),或者更準確地說:nice 級別行為取決於_絕對_ nice 級別,而 nice API 本身從根本上說是“相對的”。

int nice(int inc);

asmlinkage long sys_nice(int increment)

(第一個是 glibc API,第二個是 syscall API。)請注意,“inc”是相對於當前 nice 級別的。像 bash 的 “nice” 命令這樣的工具反映了這個相對 API。

使用舊排程器,例如,如果您啟動一個 nice 值為 +1 的任務和一個 nice 值為 +2 的任務,則兩個任務之間的 CPU 分配將取決於父 shell 的 nice 級別 - 如果它是 nice -10,則 CPU 分配與它是 +5 或 +10 時不同。

針對 Linux nice 級別支援的第三個抱怨是負 nice 級別不夠“有力”,因此很多人不得不求助於在 RT 優先順序(例如 SCHED_FIFO)下執行音訊(和其他多媒體)應用程式。但這引起了其他問題:SCHED_FIFO 不是防飢餓的,並且有錯誤的 SCHED_FIFO 應用程式也可能完全鎖定系統。

v2.6.23 中的新排程器解決了所有這三種類型的抱怨

為了解決第一個抱怨(即 nice 級別不夠“有力”),排程器與“時間片”和 HZ 概念解耦(並且粒度成為與 nice 級別分離的概念),因此可以實現更好,更一致的 nice +19 支援:使用新的排程器,nice +19 任務獲得與 HZ 無關的 1.5%,而不是它們在舊排程器中獲得的 3%-5%-9% 的可變範圍。

為了解決第二個抱怨(即 nice 級別不一致),新的排程器使 nice(1) 對任務產生相同的 CPU 利用率效果,而與其絕對 nice 級別無關。因此,在新排程器上,執行 nice +10 和 nice +11 的任務具有與執行 nice -5 和 nice -4 的任務相同的 CPU 利用率“分割”。(一個將獲得 55% 的 CPU,另一個將獲得 45%。)這就是為什麼 nice 級別被更改為“乘法”(或指數),這樣無論您從哪個 nice 級別開始,'相對結果' 始終相同。

第三個抱怨(即負 nice 級別不夠“有力”,並迫使音訊應用程式在更危險的 SCHED_FIFO 排程策略下執行)幾乎由新排程器自動解決:更強的負 nice 級別是重新校準的 nice 級別動態範圍的自動副作用。