Intel Powerclamp 驅動程式

作者:

簡介

考慮這樣一種情況:由於功率預算、散熱限制或噪音水平,系統在執行時必須降低功耗,並且不傾向於採用主動散熱。此時必須執行軟體管理的被動降功耗,以防止硬體為災難性場景而設計的動作。

目前,P-狀態、T-狀態(時鐘調製)和 CPU 下線用於 CPU 節流。

在 Intel CPU 上,C-狀態提供了有效的功耗降低,但到目前為止,它們僅根據工作負載進行機會性使用。隨著 intel_powerclamp 驅動程式的開發,引入了跨所有線上 CPU 執行緒同步空閒注入的方法。目標是實現強制和可控的 C-狀態駐留。

已在功耗、效能、可擴充套件性和使用者體驗方面進行了測試/分析。在許多情況下,與 CPU 下線或調製 CPU 時鐘相比,顯示出明顯的優勢。

操作理論

空閒注入

在現代 Intel 處理器(Nehalem 或更新版本)上,包級 C-狀態駐留可在 MSR 中獲得,因此核心也能獲得。

這些 MSR 是:

#define MSR_PKG_C2_RESIDENCY      0x60D
#define MSR_PKG_C3_RESIDENCY      0x3F8
#define MSR_PKG_C6_RESIDENCY      0x3F9
#define MSR_PKG_C7_RESIDENCY      0x3FA

如果核心也可以向系統注入空閒時間,那麼就可以建立一個管理包級 C-狀態的閉環控制系統。intel_powerclamp 驅動程式被設想為這樣一個控制系統,其中目標設定點是使用者選擇的空閒率(基於功耗降低),誤差是實際包級 C-狀態駐留率與目標空閒率之間的差異。

注入由為每個線上 CPU 生成的高優先順序核心執行緒控制。

這些具有 SCHED_FIFO 類別的核心執行緒被建立用於執行受控佔空比和持續時間的鉗制操作。每個每 CPU 執行緒根據 jiffies 的取整同步其空閒時間和持續時間,從而可以防止累積誤差以避免抖動效應。執行緒也繫結到 CPU,以便它們不能遷移,除非 CPU 下線。在這種情況下,屬於下線 CPU 的執行緒將立即終止。

以 SCHED_FIFO 執行且優先順序相對較高,也使得該方案適用於可搶佔和不可搶佔的核心。空閒時間圍繞 jiffies 對齊確保了 HZ 值的可擴充套件性。這種效果可以透過 Perf 時間圖更好地視覺化。下圖顯示了核心執行緒 kidle_inject/cpu 的行為。在空閒注入期間,它執行 monitor/mwait 空閒給定的“持續時間”,然後將 CPU 讓給其他任務,直到下一個時間間隔。

在空閒期間,NOHZ 排程時鐘被停用,但中斷未被遮蔽。測試表明,來自排程器時鐘的額外喚醒對大型系統(具有 80 個處理器的 Westmere 系統)上 powerclamp 驅動程式的效率有巨大影響。

CPU0
                  ____________          ____________
kidle_inject/0   |   sleep    |  mwait |  sleep     |
        _________|            |________|            |_______
                               duration
CPU1
                  ____________          ____________
kidle_inject/1   |   sleep    |  mwait |  sleep     |
        _________|            |________|            |_______
                              ^
                              |
                              |
                              roundup(jiffies, interval)

只允許一個 CPU 收集統計資料和更新全域性控制引數。這個 CPU 在本文件中被稱為控制 CPU。控制 CPU 在執行時選舉,策略偏向 BSP,並考慮了 CPU 熱插拔的可能性。

就空閒控制系統的動態而言,包級空閒時間在很大程度上被認為是一個非因果系統,其行為不能基於過去或當前的輸入。因此,intel_powerclamp 驅動程式試圖根據給定輸入(目標空閒率)立即強制執行所需的空閒時間。注入後,powerclamp 在給定時間視窗內監控實際空閒情況,並相應調整下一次注入,以避免過量/不足校正。

當用於因果控制系統(如溫度控制)時,該驅動程式的使用者需要實現將過去樣本和輸出納入反饋的演算法。例如,基於 PID 的溫度控制器可以使用 powerclamp 驅動程式,根據過去樣本的積分和微分增益來維持所需的目標溫度。

校準

在可擴充套件性測試期間,觀察到隨著核心數量的增加,CPU 之間的同步操作變得具有挑戰性。系統進入包級 C 狀態的能力也是如此。

為了確保 intel_powerclamp 驅動程式能夠很好地擴充套件,實現了線上校準。進行此類校準的目標是:

  1. 確定空閒注入比的有效範圍

  2. 確定每個目標比率所需的補償量

對每個目標比率的補償由兩部分組成:

  1. 穩態誤差補償

    這是為了抵消系統在沒有額外喚醒(如外部中斷)的情況下進入空閒時發生的錯誤。

  2. 動態誤差補償

    當空閒期間發生過多的喚醒時,可以透過減慢 CPU 活動來新增額外的空閒比率以抑制中斷。

提供了一個 debugfs 檔案供使用者檢查補償進度和結果,例如在 Westmere 系統上:

[jacob@nex01 ~]$ cat
/sys/kernel/debug/intel_powerclamp/powerclamp_calib
controlling cpu: 0
pct confidence steady dynamic (compensation)
0       0       0       0
1       1       0       0
2       1       1       0
3       3       1       0
4       3       1       0
5       3       1       0
6       3       1       0
7       3       1       0
8       3       1       0
...
30      3       2       0
31      3       2       0
32      3       1       0
33      3       2       0
34      3       1       0
35      3       2       0
36      3       1       0
37      3       2       0
38      3       1       0
39      3       2       0
40      3       3       0
41      3       1       0
42      3       2       0
43      3       1       0
44      3       1       0
45      3       2       0
46      3       3       0
47      3       0       0
48      3       2       0
49      3       3       0

校準在執行時進行。沒有離線方法可用。穩態補償僅在所有相鄰比率的置信水平達到滿意水平時才使用。置信水平是根據執行時收集的乾淨資料累積的。在沒有額外中斷的期間收集的資料被認為是乾淨的。

為了補償空閒期間過多的喚醒,當檢測到此類情況時,會注入額外的空閒時間。目前,我們有一個簡單的演算法將注入比率加倍。一個可能的增強可能是限制觸發中斷,例如延遲電平觸發中斷的 EOI。但這對於排程器或 IRQ 核心程式碼來說,要做到非侵入性是一個挑戰。

CPU 上線/下線

每 CPU 核心執行緒在收到 CPU 熱插拔活動的通知後啟動/停止。intel_powerclamp 驅動程式會跟蹤鉗制核心執行緒,即使它們在 CPU 下線事件後遷移到其他 CPU。

效能分析

本節描述了在多個系統上收集的一般效能資料,包括 Westmere (80P) 和 Ivy Bridge (4P, 8P)。

有效性和侷限性

允許的空閒注入最大範圍限制在 50%。如前所述,由於在強制空閒期間允許中斷,過多的中斷可能會導致效率降低。極端情況可能是執行 ping -f 來生成氾濫的網路中斷而沒有太多 CPU 確認。在這種情況下,空閒注入執行緒幾乎無能為力。在大多數正常情況下,例如 scp 大檔案時,應用程式可以透過 powerclamp 驅動程式進行節流,因為減慢 CPU 也會減慢網路協議處理,從而減少中斷。

當控制 CPU 在執行時改變控制引數時,其餘 CPU 可能需要額外的時間來跟上這些改變。在此期間,空閒注入會不同步,因此無法以預期的比率進入包 C 狀態。但這種影響很小,因為在大多數情況下,目標比率的改變頻率遠低於空閒注入頻率。

可擴充套件性

測試還顯示,在 50% 空閒比率下,4P/8P Ivy Bridge 系統和 80P Westmere 伺服器之間存在微小但可測量的差異。Westmere 需要更多的補償才能達到相同的目標空閒比率。並且補償隨著空閒比率的增加而增加。上述原因構成了校準程式碼的必要性。

在 IVB 8P 系統上,與下線 CPU 相比,powerclamp 可以實現每瓦高達 40% 的更好效能。(透過對為所有執行 CPU 生成的每 CPU 計數執行緒求和的自旋計數器進行測量)。

使用和介面

powerclamp 驅動程式作為冷卻設備註冊到通用熱層。目前,它未繫結到任何熱區。

jacob@chromoly:/sys/class/thermal/cooling_device14$ grep . *
cur_state:0
max_state:50
type:intel_powerclamp

cur_state 允許使用者設定所需的空閒百分比。向 cur_state 寫入 0 將停止空閒注入。寫入 1 到 max_state 之間的值將開始空閒注入。讀取 cur_state 將返回實際和當前的空閒百分比。這可能與使用者設定的值不同,因為當前空閒百分比取決於工作負載幷包含自然空閒。當空閒注入被停用時,讀取 cur_state 返回值 -1 而不是 0,以避免將 100% 繁忙狀態與停用狀態混淆。

使用示例

  • 注入 25% 的空閒時間

    $ sudo sh -c "echo 25 > /sys/class/thermal/cooling_device80/cur_state
    

如果系統不忙且已有超過 25% 的空閒時間,則 powerclamp 驅動程式將不會啟動空閒注入。使用 Top 將不會顯示空閒注入核心執行緒。

如果系統繁忙(下面的自旋測試)並且自然空閒時間少於 25%,powerclamp 核心執行緒將執行空閒注入。強制空閒時間被計為正常空閒,因為採用與空閒任務相同的通用程式碼路徑。

在此示例中,顯示了 24.1% 的空閒。這有助於系統管理員或使用者在 powerclamp 驅動程式執行時確定性能下降的原因。

Tasks: 197 total,   1 running, 196 sleeping,   0 stopped,   0 zombie
Cpu(s): 71.2%us,  4.7%sy,  0.0%ni, 24.1%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   3943228k total,  1689632k used,  2253596k free,    74960k buffers
Swap:  4087804k total,        0k used,  4087804k free,   945336k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 3352 jacob     20   0  262m  644  428 S  286  0.0   0:17.16 spin
 3341 root     -51   0     0    0    0 D   25  0.0   0:01.62 kidle_inject/0
 3344 root     -51   0     0    0    0 D   25  0.0   0:01.60 kidle_inject/3
 3342 root     -51   0     0    0    0 D   25  0.0   0:01.61 kidle_inject/1
 3343 root     -51   0     0    0    0 D   25  0.0   0:01.60 kidle_inject/2
 2935 jacob     20   0  696m 125m  35m S    5  3.3   0:31.11 firefox
 1546 root      20   0  158m  20m 6640 S    3  0.5   0:26.97 Xorg
 2100 jacob     20   0 1223m  88m  30m S    3  2.3   0:23.68 compiz

測試表明,透過將 powerclamp 驅動程式用作冷卻裝置,基於 PID 的使用者空間熱控制器可以有效地管理 CPU 溫度,前提是沒有新增其他熱影響。例如,Ultrabook 使用者可以在特定溫度(低於大多數活動跳變點)下編譯核心。

模組引數

cpumask (讀寫)

一個用於注入空閒的 CPU 位掩碼。位掩碼的格式與 /proc/irq/*/smp_affinity 等其他子系統中使用的格式相同。掩碼是逗號分隔的 32 位組。每個 CPU 對應一個位。例如,對於一個 256 CPU 系統,完整的掩碼是:ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff,ffffffff

最右邊的掩碼用於 CPU 0-32。

max_idle (讀寫)

注入空閒時間佔總 CPU 時間的最大比率,範圍從 1% 到 100%。即使冷卻裝置的 max_state 始終為 100 (100%),此引數也允許新增最大空閒百分比限制。預設值為 50,以匹配 powerclamp 驅動程式的當前實現。如果 cpumask 包含系統中所有存在的 CPU,則不允許值超過 75。