能耗感知排程¶
1. 引言¶
能耗感知排程(Energy Aware Scheduling,簡稱 EAS)賦予排程器預測其決策對 CPU 能耗影響的能力。EAS 依賴於 CPU 的能耗模型(Energy Model,簡稱 EM)為每個任務選擇能耗高效的 CPU,同時最大程度地減少對吞吐量的影響。本文旨在介紹 EAS 的工作原理、其主要設計決策以及執行 EAS 所需的詳細資訊。
在深入探討之前,請注意,在撰寫本文時:
/!\ EAS does not support platforms with symmetric CPU topologies /!\
EAS 僅在異構 CPU 拓撲(如 Arm big.LITTLE)上執行,因為這是透過排程節省能耗潛力最大的地方。
EAS 實際使用的 EM _並非_由排程器維護,而是由一個專門的框架維護。有關該框架及其提供內容的詳細資訊,請參閱其文件(參見裝置的能耗模型)。
2. 背景與術語¶
- 首先明確:
能量 = [焦耳](像電源裝置中的電池一樣的資源)
功率 = 能量/時間 = [焦耳/秒] = [瓦特]
EAS 的目標是在完成工作的同時最小化能耗。也就是說,我們希望最大化
performance [inst/s]
--------------------
power [W]
這等同於最小化
energy [J]
-----------
instruction
同時仍獲得“良好”的效能。它本質上是排程器當前僅以效能為目標的替代最佳化目標。此替代目標同時考慮了能效和效能兩個目標。
引入 EM 的目的是讓排程器能夠評估其決策的影響,而不是盲目應用可能只對某些平臺產生積極效果的節能技術。同時,EM 必須儘可能簡單,以最大程度地減少對排程器延遲的影響。
簡而言之,EAS 改變了 CFS 任務分配給 CPU 的方式。當排程器需要決定任務在哪裡執行時(在喚醒期間),EM 被用於在幾個好的 CPU 候選者之間做出選擇,並挑選出預計能耗最低且不損害系統吞吐量的那個。EAS 所做的預測依賴於平臺拓撲的特定知識元素,其中包括 CPU 的“容量”及其各自的能耗成本。
3. 拓撲資訊¶
EAS(以及排程器的其餘部分)使用“容量”概念來區分具有不同計算吞吐量的 CPU。CPU 的“容量”表示其在最高頻率執行時可以吸收的工作量,與系統中能力最強的 CPU 相比。容量值被歸一化到 1024 的範圍,並且與透過實體負載跟蹤(Per-Entity Load Tracking,PELT)機制計算的任務和 CPU 利用率訊號具有可比性。得益於容量和利用率值,EAS 能夠估計任務/CPU 的大小/繁忙程度,並在評估效能與能耗權衡時將其考慮在內。CPU 的容量透過 arch-specific 程式碼透過 arch_scale_cpu_capacity() 回撥提供。
EAS 使用的其餘平臺知識直接從能耗模型(EM)框架中讀取。平臺的 EM 由系統中每個“效能域”的功耗成本表組成(有關效能域的更多詳細資訊,請參閱裝置的能耗模型)。
排程器在構建或重建排程域時,在拓撲程式碼中管理對 EM 物件的引用。對於每個根域(rd),排程器維護一個單鏈表,其中包含與當前 rd->span 相交的所有效能域。列表中的每個節點都包含一個指向 EM 框架提供的struct em_perf_domain的指標。
這些列表附加到根域,以應對獨佔 cpuset 配置。由於獨佔 cpuset 的邊界不一定與效能域的邊界匹配,不同根域的列表可能包含重複元素。
- 示例 1。
讓我們考慮一個有 12 個 CPU 的平臺,分為 3 個性能域(pd0、pd4 和 pd8),組織如下:
CPUs: 0 1 2 3 4 5 6 7 8 9 10 11 PDs: |--pd0--|--pd4--|---pd8---| RDs: |----rd1----|-----rd2-----|
現在,假設使用者空間決定將系統分為兩個獨佔的 cpuset,從而建立兩個獨立的根域,每個包含 6 個 CPU。上圖中將這兩個根域分別標記為 rd1 和 rd2。由於 pd4 與 rd1 和 rd2 都有交集,它將存在於附加到每個根域的連結串列“->pd”中:
rd1->pd: pd0 -> pd4
rd2->pd: pd4 -> pd8
請注意,排程器將為 pd4 建立兩個重複的列表節點(每個列表一個)。然而,兩者都只持有一個指向 EM 框架中相同共享資料結構的指標。
由於對這些列表的訪問可能與熱插拔和其他操作併發發生,它們像排程器操作的其餘拓撲結構一樣受到 RCU 的保護。
EAS 還維護一個靜態鍵(sched_energy_present),當至少一個根域滿足 EAS 啟動的所有條件時,該鍵被啟用。這些條件總結在第 6 節中。
4. 能耗感知任務放置¶
EAS 覆蓋 CFS 任務喚醒平衡程式碼。它使用平臺的 EM 和 PELT 訊號在喚醒平衡期間選擇能效目標 CPU。當 EAS 啟用時,select_task_rq_fair() 呼叫 find_energy_efficient_cpu() 來進行放置決策。此函式在每個效能域中尋找備用容量最高的 CPU(CPU 容量 - CPU 利用率),因為這是能讓我們保持最低頻率的 CPU。然後,該函式檢查將任務放置在那裡是否比將其留在 prev_cpu(即任務上次啟用時執行的 CPU)上能節省更多能耗。
find_energy_efficient_cpu() 使用 compute_energy() 來估算如果喚醒任務被遷移,系統將消耗的能耗。compute_energy() 檢視 CPU 的當前利用率情況,並進行調整以“模擬”任務遷移。EM 框架提供了 em_pd_energy() API,該 API 計算給定利用率情況下每個效能域的預期能耗。
下面詳細介紹一個能耗最佳化任務放置決策的例子。
- 示例 2。
讓我們考慮一個(虛構的)平臺,它有兩個獨立的效能域,每個域由兩個 CPU 組成。CPU0 和 CPU1 是小核 CPU;CPU2 和 CPU3 是大核 CPU。
排程器必須決定將 util_avg = 200 且 prev_cpu = 0 的任務 P 放置在哪裡。
CPU 的當前利用率情況如下圖所示。CPU 0-3 的 util_avg 分別為 400、100、600 和 500。每個效能域有三個操作效能點(OPP)。與每個 OPP 相關的 CPU 容量和功耗成本列在能耗模型表中。P 的 util_avg 在下圖中顯示為“PP”。
CPU util. 1024 - - - - - - - Energy Model +-----------+-------------+ | Little | Big | 768 ============= +-----+-----+------+------+ | Cap | Pwr | Cap | Pwr | +-----+-----+------+------+ 512 =========== - ##- - - - - | 170 | 50 | 512 | 400 | ## ## | 341 | 150 | 768 | 800 | 341 -PP - - - - ## ## | 512 | 300 | 1024 | 1700 | PP ## ## +-----+-----+------+------+ 170 -## - - - - ## ## ## ## ## ## ------------ ------------- CPU0 CPU1 CPU2 CPU3 Current OPP: ===== Other OPP: - - - util_avg (100 each): ##find_energy_efficient_cpu() 將首先在兩個效能域中尋找備用容量最大的 CPU。在本例中是 CPU1 和 CPU3。然後它將估算如果 P 放置在其中任一 CPU 上,系統的能耗,並檢查這是否比將 P 留在 CPU0 上更能節省能耗。EAS 假設 OPP 遵循利用率(這與 schedutil CPUFreq governor 的行為一致,有關此主題的更多詳細資訊,請參閱第 6 節)。
情況 1. P 遷移到 CPU1:
1024 - - - - - - - Energy calculation: 768 ============= * CPU0: 200 / 341 * 150 = 88 * CPU1: 300 / 341 * 150 = 131 * CPU2: 600 / 768 * 800 = 625 512 - - - - - - - ##- - - - - * CPU3: 500 / 768 * 800 = 520 ## ## => total_energy = 1364 341 =========== ## ## PP ## ## 170 -## - - PP- ## ## ## ## ## ## ------------ ------------- CPU0 CPU1 CPU2 CPU3情況 2. P 遷移到 CPU3:
1024 - - - - - - - Energy calculation: 768 ============= * CPU0: 200 / 341 * 150 = 88 * CPU1: 100 / 341 * 150 = 43 PP * CPU2: 600 / 768 * 800 = 625 512 - - - - - - - ##- - -PP - * CPU3: 700 / 768 * 800 = 729 ## ## => total_energy = 1485 341 =========== ## ## ## ## 170 -## - - - - ## ## ## ## ## ## ------------ ------------- CPU0 CPU1 CPU2 CPU3情況 3. P 留在 prev_cpu / CPU 0 上:
1024 - - - - - - - Energy calculation: 768 ============= * CPU0: 400 / 512 * 300 = 234 * CPU1: 100 / 512 * 300 = 58 * CPU2: 600 / 768 * 800 = 625 512 =========== - ##- - - - - * CPU3: 500 / 768 * 800 = 520 ## ## => total_energy = 1437 341 -PP - - - - ## ## PP ## ## 170 -## - - - - ## ## ## ## ## ## ------------ ------------- CPU0 CPU1 CPU2 CPU3從這些計算來看,情況 1 的總能耗最低。因此,從能效角度來看,CPU 1 是最佳候選。
大核 CPU 通常比小核 CPU 更耗電,因此主要用於小核 CPU 無法滿足任務需求時。然而,小核 CPU 並非總是比大核 CPU 更節能。例如,對於某些系統,小核 CPU 的高 OPPs 可能比大核 CPU 的最低 OPPs 能效更低。因此,如果小核 CPU 在特定時間點恰好有足夠的利用率,此時喚醒的小任務在 big 端執行可能更能節省能耗,即使它可以在 little 端執行。
即使在大核 CPU 的所有 OPP 都比小核 CPU 能效低的情況下,在特定條件下,將小任務放到大核 CPU 上仍然可能節省能耗。事實上,將任務放到小核 CPU 上可能導致整個效能域的 OPP 升高,這將增加已經在那裡執行的任務的成本。如果喚醒任務被放置在大核 CPU 上,它自身的執行成本可能比在小核上執行更高,但它不會影響小核 CPU 的其他任務,這些任務將繼續以較低的 OPP 執行。因此,當考慮 CPU 消耗的總能耗時,在大核上執行該任務的額外成本可能小於為所有其他任務提高小核 CPU 的 OPP 的成本。
如果沒有系統上所有 CPU 在不同 OPP 下執行的成本知識,上述示例幾乎不可能以通用方式且適用於所有平臺進行正確處理。得益於其基於 EM 的設計,EAS 應該能夠正確應對這些情況而不會遇到太多麻煩。然而,為了確保在高利用率場景下對吞吐量的影響最小,EAS 還實現了另一種機制,稱為“過度利用”。
5. 過度利用¶
從總體來看,EAS 最能發揮作用的用例是那些涉及輕度/中度 CPU 利用率的場景。每當執行長時間的 CPU 密集型任務時,它們將需要所有可用的 CPU 容量,排程器幾乎無法在不嚴重損害吞吐量的情況下節省能耗。為了避免 EAS 損害效能,一旦 CPU 利用率超過其計算容量的 80%,它們就會被標記為“過度利用”。只要根域中沒有 CPU 過度利用,負載均衡就會被停用,並且 EAS 會覆蓋喚醒均衡程式碼。EAS 可能會比其他 CPU 更大地負載系統中最節能的 CPU,如果這可以在不損害吞吐量的情況下完成。因此,負載均衡器被停用,以防止它破壞 EAS 找到的節能任務放置。當系統未被過度利用時,這樣做是安全的,因為低於 80% 的臨界點意味著:
所有 CPU 都有一些空閒時間,因此 EAS 使用的利用率訊號可能準確地表示系統中各種任務的“大小”;
所有任務都應已獲得足夠的 CPU 容量,無論其 nice 值如何;
由於存在備用容量,所有任務都必須定期阻塞/休眠,並且喚醒時的均衡就足夠了。
一旦一個 CPU 超過 80% 的臨界點,上述三個假設中至少有一個變得不正確。在這種情況下,整個根域的“過度利用”標誌被設定,EAS 被停用,並且負載均衡器被重新啟用。透過這樣做,排程器在 CPU 密集型條件下回退到基於負載的喚醒和負載均衡演算法。這能更好地遵守任務的 nice 值。
由於過度利用的概念在很大程度上依賴於檢測系統中是否存在空閒時間,因此必須考慮被更高(於 CFS)排程類(以及 IRQ)“竊取”的 CPU 容量。因此,過度利用的檢測不僅考慮了 CFS 任務使用的容量,還考慮了其他排程類和 IRQ 使用的容量。
6. EAS 的依賴項和要求¶
能耗感知排程依賴於系統 CPU 具有特定的硬體屬性以及核心的其他功能被啟用。本節列出了這些依賴項並提供瞭如何滿足這些條件的提示。
6.1 - 異構 CPU 拓撲¶
如引言所述,EAS 目前僅支援異構 CPU 拓撲平臺。在排程域構建時,透過檢查是否存在 SD_ASYM_CPUCAPACITY_FULL 標誌來在執行時檢查此要求。
有關在 sched_domain 層次結構中設定此標誌所需滿足的要求,請參閱容量感知排程。
請注意,EAS 在根本上與 SMP 並非不相容,但目前尚未在 SMP 平臺上觀察到顯著的節約。如果將來證明可行,此限制可能會被修改。
6.2 - 能耗模型的存在¶
EAS 使用平臺的 EM 來估算排程決策對能耗的影響。因此,您的平臺必須向 EM 框架提供功耗成本表才能使 EAS 啟動。為此,請參閱獨立 EM 框架的文件裝置的能耗模型。
另請注意,EM 註冊後需要重建排程域才能啟動 EAS。
EAS 使用 EM 來對能耗使用做出預測性決策,因此在檢查任務放置的可能選項時,它更關注差異。對於 EAS 而言,EM 功率值是以毫瓦特表示還是以“抽象尺度”表示並不重要。
6.3 - 能耗模型的複雜性¶
EAS 不對 PDs/OPPs/CPUs 的數量施加任何複雜性限制,但將 CPU 數量限制為 EM_MAX_NUM_CPUS,以防止能耗估算期間溢位。
6.4 - Schedutil governor¶
EAS 嘗試預測 CPU 在不久的將來將執行在哪個 OPP 上,以估算其能耗。為此,假設 CPU 的 OPP 遵循其利用率。
儘管在實踐中很難提供關於此假設準確性的硬性保證(例如,因為硬體可能不按指令行事),但 schedutil 與其他 CPUFreq governor 不同,它至少_請求_使用利用率訊號計算出的頻率。因此,唯一支援與 EAS 一起使用的 governor 是 schedutil,因為它是唯一能在頻率請求和能耗預測之間提供一定程度一致性的 governor。
不支援將 EAS 與 schedutil 以外的任何其他 governor 一起使用。
6.5 尺度不變利用率訊號¶
為了在所有 CPU 和所有效能狀態下進行準確預測,EAS 需要頻率不變和 CPU 不變的 PELT 訊號。這些可以透過架構定義的 arch_scale{cpu,freq}_capacity() 回撥獲得。
不支援在未實現這兩個回撥的平臺上使用 EAS。
6.6 多執行緒 (SMT)¶
EAS 目前的形式是 SMT 無感知的,無法利用多執行緒硬體來節省能耗。EAS 將執行緒視為獨立的 CPU,這實際上可能對效能和能耗都適得其反。
不支援在 SMT 上使用 EAS。