這篇文章是我剛開始做FSC 功能的時候寫的,因為那時候都找不到主管要我報告的內容,所以報告完就順便整理一下,最近因為在修控制學,之後應該會再補一篇和控制學相關的內容
BMC的風扇控制算一個蠻重要的功能,那這個功能包含了"TACH"和"PWM"這兩個常用訊號怎麼解讀,還有控制演算法"PID(closed loop)"和"Stepwise(openloop)"還有Error control ,但因為每家做法不同,就不會在這邊作介紹
##實作程式碼是來自Facebook的openBMC,圖片都是手繪的
Why and how to do fan speed control ?
在伺服器中的風扇是非常高速也耗電的,根據統計在數據中心的運維成本上,電費佔了7成,並且如果讓風扇長期處在全轉狀態也會有噪音和耗損度的問題。
目前CPU可以達到單一耗電量200W以上,伴隨而來的高熱也會使個晶片老化速度加快,當然伺服器中的SSD, Nic card, E1.S等裝置也是有同樣的情況,因此我們希望能根據這些高熱的元件溫度來決定風扇的轉速,達到省電和正常運作的效果
風扇控制的做法如下:
- Thermal team(熱流部門) 通常會提供一個fan table,裡面會詳細描述風扇要怎麼轉
- BMC (controller) 會透過PWM訊號去設定風扇轉速
- 風扇也能透過TACH訊號來回傳目前的轉速
PWM(Pulse-Width Modulation)
PWM是透過平均電壓來傳遞類比訊號,簡單來說就是在一個cycle中,高電為占百分之多少,就表示他要傳遞的值是多少
例如在一個週期中,如果高電位占25%,低電位占75%,這樣表示我們要傳遞的值是25%,風扇就會轉25%
那如果今天我們都一直是high (高電位),這樣風扇就會全轉,因此在線路圖的位置過程中,都會注意PWM有沒有pull high,避免在BMC更新過程 或是死掉後,機器過熱
那每個周期的時間是多少呢? PWM的傳遞頻率會定義在風扇的spec中,每一顆風扇的接收頻率有可能會不一樣
TACH (Tachometer)
我們可以透過Tach來傳遞風扇的轉速,有修過機械方面的課程就會知道,馬達會有n個機械原點,傳一圈的話會產生n個pulse,一圈會產生幾個pulse也是定義在風扇的spec中
假如今天風扇轉一圈會產生兩個pulse,我們在一秒內收到1000個pulse,這樣表示風扇一秒轉了500圈,風扇轉速是用rpm(一分鐘轉幾圈)表示的,因此500*60 rpm就是我們要求的值
TACH的訊號大概就長得像底下這樣,只要統計一秒鐘有幾個訊號,就能得到風扇的轉速
Picture provided by: http://www.angelfire.com/super/ghettoretta/m90/windowswitch.htm |
System Control
在傳統控制(Classical Control )理論中,通常會用有沒有feedback 來區分open loop control 和 closed loop control,前者通常就是我們常說的stepwise,後者就是工業控制中廣泛使用的PID control,他們的示意圖如下,接下來會分別介紹這兩個算法的的內容
Open loop control 演算法 (Stepwise)
Open loop,會根據input來直接求出output並輸出,不會參考feedback或任何的actuating error
通常thermal team會給BMC一個表(fan table),表示Sensor 溫度(input)為多少的時候,風扇轉速(output)為多少,大概如下
實作也相對簡單
PID algorithm
PID分別是proportional(比例) , integral(積分) and derivative(微分) 三個單字的縮寫所組成的
我們在做風扇控制的時候,會希望我們的電腦上元件的溫度維持在幾度,以下會以CPU溫度為例子。假設今天我們希望CPU溫度維持在60度左右,那60就是set-point (S),而CPU目前溫度就是process value (P),那S和P之間的差值就是error value (E) ,他們之間的關係就是E=S-P
PID演算法就是拿求得的E分別做比例運算,積分和微分,如下圖所示,算出來的結果會輸出PWM去控制風扇
那我們現在來分別聊聊PID這三個算法
Proportional(比例)
比例控制就是依據當前溫度來決定風扇轉速,將求得的E乘上一個Kp常數
$$P_{out}=K_p\cdot(S-P)$$
因為當E 最大,表示P離S很遠,風扇的轉速需要變化大一點,舉例來說
Set-point: 60 Kp = -2
case 1 : CPU 溫度 70度 → E=60-70 = -10
case 2 : CPU 溫度 90度 → E=60-70 = -30
從兩個case當中,我們可以發現當 | E | 越大,風扇需要的轉速變化也要很大,所以風扇轉速分別就是20和60。
Integral(積分)
積分控制是根據歷史經驗來決定風扇轉速,將從剛開機到現在的Error value全部相加起來,在乘上Ki
$$I_{out}=K_i\cdot\sum_{k=0}^tE_k $$
E0~Ei相加的值越大表示目前的歷史經驗告訴我們風扇變化要大一點
那相加的值是不會為無限大的,因為E值是有正有負
但I 有個問題 就是overshoot ,在CPU溫度已經達到set-point的時候,風扇卻仍沒減少風量,造成CPU溫度持續下降,原因是因為sum(E)仍未趨近於0,這個問題是存在於PID演算法的,大部分的程式碼會在這個問題上做work around
黃色框框就是對overshoot所做的workaround
Derivative(微分)
來到最後的微分,D就是求Error value的變化量,以最近一兩次的誤差變化量來決定風扇轉速
$$D_{out}=K_d\cdot\frac{E_t-E_{t-n}}{n}$$
把這次的error和上次的error做相減在除上時間差,就是D值了
程式碼大概如下:
這篇文章非常有趣,很值得後續作參考,但想請教您幾點問題。
回覆刪除(1)kp、ki、kd是否有公式可供參考 or 此為經驗公式的常數項。
(2)可否彙整Thermal所需要提供的資料,才能滿足PWM設定條件。
Hi Joe,
刪除Q1: 參數調整是根據實際系統情況去決定出來的,演算法有很多種(e.g. Ziegler–Nichols, Cohen-Coon ...)
Q2: Fan table(哪些sensor 需要做PID及其常數值,哪些需要做stepwise)
作者已經移除這則留言。
回覆刪除Hi Iris,
回覆刪除了解,看來是利用PID公式,進而推算kp、ki、kd。另外,如果按造您的語法,得出來的值是Delta PWM,再用此數字做加減調整,不知我理解是否有誤。
是的,而按照PID的公式算出來的就是實際的PWM了,舉例來說
刪除kp -3/ ki -0.3 / kd -0.3/ setpoint 85 / CPU temp 105
PWM = (-3)(85-105) + ki*error_history + kd*(error-pre_error)/time ~= 60~70左右(這個就是風扇轉速的百分比了)
如果PID算出來的值是負數,我們就會給予風扇一個最小PWM(20 duty之類的)
作者已經移除這則留言。
回覆刪除嘗試帶入公式,將設定T=60C;Tamb=40、Tbegin=45;W=15,Set T=60,最後PWM維持89%,結果還算合理。感謝您提供的資訊,可供後續做參考。
回覆刪除請問可否介紹有關 fan speed control for closed loop?
回覆刪除不好意思,漏掉了留言,fan speed control for closed loop 目前伺服器中都是採用PID演算法加上一點變形
刪除若套用Thermal 2.0 Fan Control的機制(依照區塊溫度決定,而不是只依賴CPU),也是用同樣的演算法實現嗎?
回覆刪除理論上用區塊的溫度去決定PWM的高低,在不影響效能的前提又能節省風扇的功耗
但大廠的BMC似乎比較少做這樣的風扇設計?!