Linux 2.6 核心中的電源管理技術綜述

來源:互聯網
上載者:User

 前言

 

本系列文章將結合近年來不斷在各種硬體(包括 CPU、晶片集、PCI Express 等各種最新匯流排標準以及外設)上新增的節能技術。

      從 Linux 2.6核心及整個 software stack (包括 kernel、middleware 以及各種使用者態
utility)如何添加對這些創新的節能技術的支援這一角度,為讀者介紹 Linux
作業系統近幾年來在電源管理方面所取得的長足進步以及未來的發展方向。

        作為本系列文章的開篇之作,首先要向大家介紹的是 cpufreq,它是 Linux 2.6核心為了更好的支援近年來在各款主流CPU 處理器中出現的變頻技術而新增的一個核心子系統。

        Cpufreq 的由來

       隨著 energy efficient computing 和 performance per watt
等概念的推廣以及進階配置與電源介面ACPI(Advanced Configuration and Power
Interface)標準的發展,目前市場上的主流 CPU 都提供了對變頻(frequency
scaling)技術的支援。例如Intel處理器所支援的 Enhanced SpeedStep 技術和 AMD 處理器所支援的
PowerNow! 技術,另外像最新的PowerPC、ARM、SPARC 和 SuperH
等處理器中也提供了類似的支援。參考資料中列出了當前 Linux
2.6核心所支援的具備變頻技術的處理器。需要注意的是,這裡要討論的變頻技術與大家以前所熟知的超頻是兩個不同的概念。超頻是指通過提高核心電壓等手段
讓處理器工作在非標準頻率下的行為,這往往會造成 CPU 使用壽命縮短以及系統穩定性下降等嚴重後果。

       而變頻技術是指CPU硬體本身支援在不同的頻率下運行,系統在運行過程中可以根據隨時可能發生變化的系統負載情況動態在這些不同的運行頻率之間進行切換,從而達到對效能和功耗做到二者兼顧的目的。

      
雖然多個處理器生產廠家都提供了對變頻技術的支援,但是其硬體實現和使用方法必然存在著細微甚至巨大的差別。這就使得每個處理器生產廠家都需要按照其特殊
的硬體實現和使用方法向核心中添加代碼,從而讓自己產品中的變頻技術在 Linux
中得到支援和使用。然而,這種核心開發模式所導致的後果是各個廠家的實現代碼散落在 Linux
核心代碼樹的各個角落裡,各種不同的實現之間沒有任何代碼是共用的,這給核心的維護以及將來添加對新的產品的支援都帶來了巨大的開銷,並直接導致了
cpufreq 核心子系統的誕生。實際上,正如前文所說,發明變頻技術的目的是為了能夠讓系統在運行過程中隨時根據系統負載的變化動態調整 CPU
的運行頻率。這件事情可以分為兩個部分,一部分是“做什麼”的問題,另一部分是“怎麼做”的問題。“做什麼”是指如何根據系統負載的動態變化挑選出
CPU 合適的運行頻率,而“怎麼做”就是要按照選定的運行頻率在選定的時間對 CPU
進行設定,使之真正工作在這一頻率上。這也就是我們在軟體設計中經常會遇到的機制 mechanism 與策略 policy
的問題,而設計良好的軟體會在架構上保證二者是被清晰的隔離開的並通過規範定義的介面進行通訊。

       Cpufreq 的設計和使用

       為瞭解決前文所提到的問題,一個新的核心子系統—— cpufreq 應運而生了。Cpufreq 為在Linux 核心中更好的支援不同 CPU 的變頻技術提供了一個統一的設計架構,其軟體結構 1 所示。 

         圖 1. Cpufreq 的軟體結構
 

        1 所示,cpufreq 在設計上主要分為以下三個模組:

        Cpufreq 模組(cpufreq module)對如何在底層控制各種不同CPU
所支援的變頻技術以及如何在上層根據系統負載動態選擇合適的運行頻率進行了封裝和抽象,並在二者之間定義了清晰的介面,從而在設計上完成了前文所提到的對
mechanism 與policy 的分離。 

       在 cpufreq 模組的底層,各個CPU 生產廠商只需根據其變頻技術的硬體實現和使用方法提供與其 CPU
相關的變頻驅動程式(CPU-specific drivers),例如 Intel 需要提供支援Enhanced SpeedStep 技術的
CPU 驅動程式,而 AMD 則需要提供支援 PowerNow! 技術的 CPU 驅動程式。 

      在 cpufreq 模組的上層,governor 作為選擇合適的目標運行頻率的決策者,根據一定的標準在適當的時刻選擇出 CPU
適合的運行頻率,並通過 cpufreq 模組定義的介面操作底層與 CPU 相關的變頻驅動程式,將 CPU 設定運行在選定的運行頻率上。

        目前最新的 Linux 核心中提供了 performance 、powersave
、userspace、conservative 和 ondemand 五種 governors 供使用者選擇使用,它們在選擇 CPU
合適的運行頻率時使用的是各自不同的標準並分別適用於不同的應用情境。使用者在同一時間只能選擇其中一個 governor
使用,但是可以在系統運行過程中根據應用需求的變化而切換使用另一個 governor 。 

        這種設計帶來的好處是使得 governor 和 CPU
相關的變頻驅動程式的開發可以相互獨立進行,並在最大限度上實現代碼重用,核心開發人員在編寫和實驗新的 governor 時不會再陷入到某款特定
CPU 的變頻技術的硬體實現細節中去,而 CPU 生產廠商在向 Linux 核心中添加支援其特定的 CPU
變頻技術的代碼時只需提供一個相對來說簡單了很多的驅動程式,而不必考慮在各種不同的應用情境中如何選擇合適的運行頻率這些複雜的問題。

      核心中的 cpufreq 子系統通過 sysfs 檔案系統向上層應用提供了使用者介面,對於系統中的每一個 CPU 而言,其
cpufreq 的 sysfs 使用者介面位於 /sys/devices/system/cpu/cpuX/cpufreq/ 目錄下,其中 X 代表
processor id ,與 /proc/cpuinfo 中的資訊相對應。以cpu0 為例,使用者一般會在該目錄下觀察到以下檔案:

$ ls -F /sys/devices/system/cpu/cpu0/cpufreq/
affected_cpus
cpuinfo_cur_freq
cpuinfo_max_freq

                cpuinfo_min_freq
ondemand/
scaling_available_frequencies
scaling_available_governors
scaling_cur_freq
scaling_driver
scaling_governor
scaling_max_freq
scaling_min_freq
stats/ 
 

      這其中的所有可讀檔案都可以使用 cat 命令進行讀操作,另外所有可寫檔案都可以使用 echo
命令進行寫操作。其中cpuinfo_max_freq 和 cpuinfo_min_freq 分別給出了CPU
硬體所支援的最高運行頻率及最低運行頻率, cpuinfo_cur_freq 則會從 CPU 硬體寄存器中讀取 CPU 當前所處的運行頻率。雖然
CPU 硬體支援多種不同的運行頻率,但是在有些場合下使用者可以只選擇使用其中的一個子集,這種控制是通過scaling_max_freq 和
scaling_min_freq 進行的。Governor在選擇合適的運行頻率時只會在 scaling_max_freq
和scaling_min_freq 所確定的頻率範圍內進行選擇,這也就是scaling_available_frequencies
所顯示的內容。與cpuinfo_cur_freq 不同, scaling_cur_freq 返回的是cpufreq 模組緩衝的 CPU
當前運行頻率,而不會對 CPU 硬體寄存器進行檢查。 scaling_available_governors 會告訴使用者當前有哪些
governors 可供使用者使用,而 scaling_driver 則會顯示該 CPU 所使用的變頻驅動程式。 Stats 目錄下給出了對
CPU 各種運行頻率的使用統計情況,例如 CPU 在各種頻率下的已耗用時間以及在各種頻率之間的變頻次數。 Ondemand 目錄則與
ondemand governor 相關,在後文會進行相應的介紹。

       通過以上的介紹,大家對如何使用 cpufreq 通過 sysfs
提供的使用者介面已經有了大致的瞭解,但是對於絕大部分使用者而言,逐一操作這些檔案既費力又耗時。因此 Dominik
等人開發了cpufrequtils 工具包[2],為使用者提供了更加簡便的對核心cpufreq 子系統的操作介面。通過 cpufreq-info
的輸出,讀者可以很清楚的看到剛剛在上面介紹過的/sys/devices/system/cpu/cpuX/cpufreq/ 目錄下各個檔案的內容。

$ cpufreq-info
cpufrequtils 002: cpufreq-info (C) Dominik Brodowski

2004-2006
Report errors and bugs to
linux@brodo.de
, please.
analyzing CPU 0:
  driver: acpi-cpufreq
  CPUs which need to switch frequency at the same time:

0 1
  hardware limits: 1000 MHz - 1.67 GHz
  available frequency steps: 1.67 GHz, 1.33 GHz, 1000

MHz
  available cpufreq governors: userspace, conservative,

ondemand, powersave, performance
  current policy: frequency should be within 1000 MHz

and 1.67 GHz.
              The governor "ondemand" may decide which

speed to use
              within this range.
  current CPU frequency is 1000 MHz.
analyzing CPU 1:
  driver: acpi-cpufreq
  CPUs which need to switch frequency at the same time:

0 1
  hardware limits: 1000 MHz - 1.67 GHz
  available frequency steps: 1.67 GHz, 1.33 GHz, 1000

MHz
  available cpufreq governors: userspace, conservative,

ondemand, powersave, performance
  current policy: frequency should be within 1000 MHz

and 1.67 GHz.
              The governor "ondemand" may decide which

speed to use
              within this range.
  current CPU frequency is 1000 MHz.
 

         Ondemand governor 的由來及其實現剛剛我們在 cpufreq-info 的輸出中可以看到 cpufreq
子系統一共提供了五種 governors 供使用者選擇使用,它們分別是
userspace,conservative,ondemand,powersave
和performance。在最新的核心中如果使用者不進行額外設定的話,ondemand 會被作為預設的 governor
使用。為了理解是什麼原因造成了這種現狀,我們在這裡帶領讀者回顧一下 cpufreq 子系統中的governor在核心中的開發曆史。

       Cpufreq 作為一個子系統最早被加入到 Linux 核心中時只配備了三個governors
,分別是performance、powersave 和userspace。當使用者選擇使用 performance governor
時,CPU會固定工作在其支援的最高運行頻率上;當使用者選擇使用powersave governor
時,CPU會固定工作在其支援的最低運行頻率上。因此這兩種 governors 都屬於靜態 governor ,即在使用它們時 CPU
的運行頻率不會根據系統運行時負載的變化動態作出調整。這兩種 governors 對應的是兩種極端的應用情境,使用 performance
governor 體現的是對系統高效能的最大追求,而使用 powersave governor
則是對系統低功耗的最大追求。雖然這兩種應用需求確實存在,但大多數使用者在大部分時間裡需要的是更加靈活的變頻策略。最早的 cpufreq 子系統通過
userspace governor 為使用者提供了這種靈活性。正如它的名字一樣,使用 userspace governor
時,系統將變頻策略的決策權交給了使用者態應用程式,並提供了相應的介面供使用者態應用程式調節 CPU 運行頻率使用。通過使用 cpufrequtils
工具包中的 cpufreq-set 將 userspace 設定為 cpufreq 子系統所使用的 governor
後,我們可以看到與之前相比在 /sys/devices/system/cpu/cpuX/cpufreq/ 目錄下多出了一個名為
scaling_setspeed 的檔案,這正是 userspace governor 所提供的特殊使用者介面。使用者可以通過向該檔案寫入任何一個
scaling_available_frequencies 中所支援的運行頻率,從而將 CPU 設定在該頻率下運行。

# cpufreq-set -g userspace
# cat cpuinfo_cur_freq
1000000
# cat scaling_available_frequencies
1667000 1333000 1000000
# echo 1333000 >scaling_setspeed
# cat cpuinfo_cur_freq
1333000 
        

       剛剛提到在使用 userspace governor
時,系統將變頻策略的決策權交給了使用者態應用程式。該使用者態應用程式一般是一個 daemon
程式,每隔一定的時間間隔收集一次系統資訊並根據系統的負載情況使用 userspace governor 提供的 scaling_setspeed
介面動態調整 CPU 的運行頻率。作為這個daemon 程式,當時在幾個主要的 Linux 發行版中使用的一般是 powersaved 或者
cpuspeed。這兩個 daemon 程式一般每隔幾秒鐘統計一次 CPU 在這個採樣周期內的負載情況,並根據統計結果調整 CPU
的運行頻率。這種 userspace governor 加使用者態 daemon
程式的變頻方法雖然為使用者提供了一定的靈活性,但通過開源社區的廣泛使用所得到的意見反饋逐漸暴露了這種方法的兩個嚴重缺陷。第一個是效能方面的問題。例
如powersaved 每隔五秒鐘進行一次系統負載情況的採樣分析的話,我們可以分析一下在下面給出的應用情境中的使用者體驗。假設
powersaved 的採樣分析剛剛結束,而且由於在剛剛結束的採樣周期內系統負載很低,CPU 被設定在最低頻率上運行。這時使用者如果開啟
Firefox 等對 CPU 運算能力要求相當高的程式的話,powersaved 要在下一個採樣點——大約五秒鐘之後才有機會觀察到這種提高
CPU 運行頻率的需求。也就是說,在Firefox 啟動之初的五秒鐘內 CPU
的計算能力並沒有被充分發揮出來,這無疑會使使用者體驗大打折扣。第二個是系統負載情況的採樣分析的準確性問題。將監控系統負載情況並對未來 CPU
的效能需求做出判斷的任務交給一個使用者態程式完成實際上並不合理,一方面是由於一個使用者態程式很難完整的收集到所有需要的資訊,因為這些資訊大部分都儲存
在核心空間;另一方面一個使用者態程式如果想要收集這些系統資訊,必然需要進行使用者態與核心態之間的資料互動,而頻繁的使用者態與核心態之間的資料互動又會給
系統效能帶來負面影響。

      
那麼這兩個問題有沒有解決的方法呢?應該講社區中的開發人員就第二個問題比較容易達成一致,既然在使用者態對系統的負載情況進行採集和分析存在這樣那樣的問
題,那麼更加合理的做法就是應該將這部分工作交由核心負責。但是第一個問題呢?第一個問題最直觀的解決方案就是降低對系統負載進行採樣分析的時間間隔,這
樣 powersaved
就能儘早的對系統負載的變化做出及時的響應。然而這種簡單的降低採樣分析的時間間隔的方案同樣存在著兩方面的問題,一方面這意味著更加頻繁的使用者態與核心
態之間的資料互動,因此必然也就意味著對系統效能帶來更大的負面影響;另一方面的主要原因在於當時各個 CPU
生產廠家的變頻技術在硬體上仍不完善,具體體現就是在對 CPU 進行變頻設定時所需的操作時間過長,例如 Intel 早期的 Speedstep
技術在對 CPU 進行變頻設定時需要耗時 250 微秒,在此過程中 CPU 無法正常執行指令。讀者如果簡單的計算一下不難發現,即使對於一個主頻為
1GHz 的 CPU 而言, 250 微秒也意味著 250,000 個刻度,在這期間 CPU
完全可以執行完上萬條指令。因此從這個角度而言,簡單的降低採樣分析的時間間隔對系統效能帶來的負面影響更加嚴重。幸運的是隨著硬體技術的不斷完善和改
進,對 CPU 進行變頻設定所需的操作時間已經顯著降低,例如 Intel 最新的 Enhanced Speedstep 技術在對 CPU
進行變頻設定時耗時已降至 10 微秒,下降了不止一個數量級。正是這種 CPU
硬體技術的發展為核心開發人員解決這些早期的遺留問題提供了契機,Venkatesh 等人提出並設計實現了一個新的名為 ondemand 的
governor ,它正是人們長期以來希望看到的一個完全在核心態下工作並且能夠以更加細粒度的時間間隔對系統負載情況進行採樣分析的
governor。在介紹 ondemand governor 的具體實現之前,我們先來看一下如何使用 ondemand governor
及其向使用者提供了哪些操作介面。通過 cpufreq-set 將 ondemand 設定為當前所使用的 governor 之後,在
/sys/devices/system/cpu/cpuX/cpufreq 目錄下會出現一個名為 ondemand 的子目錄

$ sudo cpufreq-set -g ondemand
$ ls /sys/devices/system/cpu/cpu0/cpufreq/ondemand/
ignore_nice_load
powersave_bias
sampling_rate
sampling_rate_max
sampling_rate_min
up_threshold
$ sudo cat sampling_rate_min sampling_rate

sampling_rate_max
40000
80000
40000000
$ sudo cat up_threshold
30 
 

       在這個子目錄下名字以 sampling 打頭的三個檔案分別給出了ondemand governor 允許使用的最短採樣間隔,當前使用的採樣間隔以及允許使用的最長採樣間隔,三者均以微秒為單位。

      以筆者的電腦為例, ondemand governor 每隔 80 毫秒進行一次採樣。另外比較重要的一個檔案是
up_threshold ,它表明了系統負載超過什麼百分比時ondemand governor 會自動提高CPU
的運行頻率。以筆者的電腦為例,這個數值為 30% 。那麼這個表明系統負載的百分比數值是如何得到的呢?在支援Intel 最新的 Enhanced
Speedstep 技術的 CPU 中,在處理器硬體中直接提供了兩個 MSR 寄存器(Model Specific Register)供
ondemand governor 採樣分析系統負載情況使用。這兩個 MSR 寄存器的 名字分別為 IA32_MPERF 和
IA32_APERF[5] ,其中 IA32_MPERF MSR 中的 MPERF 代表Maximum Performance ,
IA32_APERF MSR 中的 APERF 代表Actual Performance 。就像這兩個 MSR 的名字一樣,
IA32_MPERF MSR 寄存器是一個當 CPU 處在 ACPI C0 狀態下時按照 CPU
硬體支援的最高運行頻率每隔一個刻度加一的計數器;IA32_APERF MSR 寄存器是一個當 CPU 處在 ACPI C0 狀態下時按照
CPU 硬體當前的實際運行頻率每隔一個刻度加一的計數器。有了這兩個寄存器的存在,再考慮上 CPU 處於ACPI C0 和處於 ACPI
C1、C2、C3 三種狀態下的時間比例,也就是 CPU 處於工作狀態和休眠狀態的時間比例, ondemand governor
就可以準確的計算出 CPU 的負載情況了。

         得到了 CPU 的負載情況,接下來的問題就是如何選擇 CPU
合適的運行頻率了。剛剛在前面提到,當系統負載超過up_threshold 所設定的百分比時, ondemand governor 將會自動提高
CPU 的運行頻率,但是具體提高到哪個頻率上運行呢?在 ondemand governor 監測到系統負載超過
up_threshold所設定的百分比時,說明使用者當前需要 CPU 提供更強大的處理能力,因此 ondemand governor
會將CPU設定在最高頻率上運行,這一點社區中的開發人員和廣大使用者都沒有任何異議。但是當 ondemand governor
監測到系統負載下降,可以降低 CPU 的運行頻率時,到底應該降低到哪個頻率呢? ondemand governor
的最初實現是在可選的頻率範圍內調低至下一個可用頻率,例如筆者使用的 CPU 支援三個可選頻率,分別為 1.67GHz、 1.33GHz 和
1GHz ,如果 CPU 運行在 1.67GHz 時ondemand governor 發現可以降低運行頻率,那麼 1.33GHz
將被選作降頻的目標頻率。這種降頻策略的主導思想是盡量減小對系統效能的負面影響,從而不會使得系統效能在短時間內迅速降低以影響使用者體驗。但是在
ondemand governor 的這種最初實現版本在社區發布後,大量使用者的使用結果表明這種擔心實際上是多餘的, ondemand
governor 在降頻時對於目標頻率的選擇完全可以更加激進。因此最新的 ondemand governor
在降頻時會在所有可選頻率中一次性選擇出可以保證 CPU 工作在 80% 以上負荷的頻率,當然如果沒有任何一個可選頻率滿足要求的話則會選擇 CPU
支援的最低運行頻率。大量使用者的測試結果表明這種新的演算法可以在不影響系統效能的前提下做到更高效的節能。在演算法改進後, ondemand
governor 的名字並沒有改變,而 ondemand governor
最初的實現也儲存了下來,並且由於其演算法的保守性而得名conservative 。

       支援 Intel Enhanced Speedstep 技術的 CPU 驅動程式的實現前文在討論cpufreq
的軟體結構時已經指出, cpufreq 從設計上將 CPU 變頻的 policy 與mechanism 分離開來並由上層的governor
負責決定 CPU 合適的工作頻率。但是在governor根據系統負載的變化決定調整 CPU 的運行頻率時,最終還是需要底層與 CPU
相關的特定驅動程式完成設定 CPU 運行頻率的任務。這裡向讀者介紹一下支援 Intel 最新的Enhanced Speedstep 技術的
CPU 驅動程式的實現原理,關注的重點是如何對 CPU 進行變頻設定。實際上支援 Intel Enhanced Speedstep
技術的處理器為使用者提供了非常簡單的編程介面,對 CPU 運行頻率進行設定是通過一個名為 IA32_PERF_CTL 的MSR
寄存器進行的,另外還有一個名為 IA32_PERF_STATUS 的MSR 寄存器可供檢查 CPU 當前所處的運行頻率。當使用者需要對CPU
運行頻率進行設定時只需按照 Intel 開發手冊的說明向IA32_PERF_CTL MSR 寄存器中寫入規定的數值即可。

       總結及未來的發展方向

       本文為讀者介紹了變頻技術在 CPU 硬體上的出現以及 Linux 核心中最初的實現存在的各種問題,並由此導致了
cpufreq 這一新的核心子系統的誕生。雖然早期的cpufreq模組所提供的三種 governors
能夠在一定程度下滿足使用者的需要並且提供了一定的靈活性,但是由於受到當時 CPU 硬體技術水平的限制,仍然有很多不盡如人意的地方。之後隨著 CPU
變頻硬體技術的不斷髮展,尤其是 Intel Enhanced Speedstep 技術的出現,原有的技術障礙被打破,隨之而來的是
cpufreq 核心子系統有了一個全新的更加完善而高效的 ondemand governor 。

       由此不難看出,核心中的 cpufreq 子系統是由於 CPU 硬體變頻技術的出現而出現,同時也在隨著 CPU
硬體變頻技術的發展而發展。這其實也預示著核心中 cpufreq 子系統未來的發展方向,即繼續跟隨 CPU
硬體變頻技術的發展腳步與時俱進。在本文的最後簡單為讀者介紹一下在 Intel 最新的 CPU 中針對硬體變頻支援的一項新技術。前文提到在支援
Intel 最新的Enhanced Speedstep 技術的 CPU 中提供了名字分別為IA32_MPERF 和 IA32_APERF 的兩個
MSR 寄存器,以便為cpufreq 模組所使用的 governor 動態收集系統的負載情況提供直接的硬體支援。其中 IA32_APERF
MSR 寄存器當 CPU 處在ACPI C0 狀態下時按照 CPU 硬體當前的實際運行頻率每隔一個刻度加一。 Intel
最新的處理器中進一步考慮了CPU 在運行過程中由於訪問記憶體或 IO 等原因可能會出現流水線停擺的狀況時, IA32_APERF
以前這種簡單的按照 CPU 當前實際運行頻率每隔一個刻度加一的做法並不能完全準確的反映CPU 的負載情況。在 Intel
最新的處理器中如果出現流水線停擺的情況, IA32_APERF 將暫時停止累加,而是在對使用者真正“有用”的時間周期才會遞增,這樣 CPU
硬體就可以為cpufreq 模組所使用的 governor 提供比以前更加準確的系統負載統計資訊。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.