一文介紹Linux EAS
能量感知調(diào)度(Energy Aware Scheduling,簡稱EAS)是目前Android手機中Linux線程調(diào)度器的基礎(chǔ)功能,它使調(diào)度器能預(yù)測其決策對CPU能耗的影響。依靠CPU的能量模型(Energy Model,簡稱EM),EAS能為每個線程選擇一個最能節(jié)約能量的CPU,并把對系統(tǒng)性能的影響降到最低。
EAS僅在異構(gòu)CPU拓撲(如Arm big.LITTLE)上運行,因為這是EAS節(jié)約能量潛力最大的CPU拓撲結(jié)構(gòu)。
注:本文分析整理基于OPPO Reno9 Pro+的開源代碼https://github.com/oppo-source/android_kernel_oppo_sm8475
一、關(guān)鍵概念
1.1capacity
算力(capacity)是CPU調(diào)度中的一個基礎(chǔ)概念,它反映的是一個CPU的計算能力,是個規(guī)格化的值,可以通過讀取Android手機的文件節(jié)點
/sys/devices/system/cpu/cpu*/cpu_capacity獲得每個CPU的最大算力。

CPU的最大計算能力= capacity-dmips-mhz * cpuinfo_max_freq / 1000。
其中”capacity-dmips-mhz”表示該cpu在1mHz頻率下運行時可以執(zhí)行多少個dmips,可以從處理器的device tree文件中獲取到;
”cpuinfo_max_freq”表示該CPU支持的最大頻率,單位kHz,所以上面的公式才除以1000,把計算單位kHz轉(zhuǎn)為mHz。
為了便于算力的比較與計算,把處理器中計算能力最強的CPU的最大算力規(guī)格化為了1024。
在CPU算力與頻率呈線性關(guān)系的處理器中:CPU某一頻率點的算力 =
(該CPU某一頻點頻率 / 該CPU最大頻率)* 該CPU的最大算力。
1.2 opp
Operating Performance Point (OPP),表示每個CPU支持的電壓頻率對(voltage/frequency tuple)。CPU的每個運行頻率點,都有一個對應(yīng)的電壓。頻率與電壓正相關(guān),頻率越高,需要的電壓越大。
1.3 power
在弄清了CPU某一頻率點的算力后,再來看看CPU某一頻率點的功率。CPU的Energy Model模塊提供了相關(guān)文件節(jié)點,可以用來讀取到CPU某一頻率點的功率。
讀取文件節(jié)點/sys/kernel/debug/energy_model/pd0/*/power,可以獲取小核簇CPU各個頻率點的功率(mW)

Energy Model代碼中通過如下公式來計算CPU每個頻率點的功率:
P = C * V^2 * f,其中C是CPU的電容(可以從處理器的device tree文件中讀取“dynamic-power-coefficient”獲取到),V和f是一個OPP的電壓和頻率。
1.4 能效比
CPU每個頻率點對應(yīng)的power/capacity值越低,其能效比越好,同一CPU,低頻率比高頻率的能效比好。整體上來說,小核簇CPU的能效比優(yōu)于大核簇CPU的能效比,大核簇CPU的能效比優(yōu)于超大核簇CPU的能效比;但是小核簇CPU高頻段能效比差于大核簇CPU低頻段的能效比,大核簇CPU高頻段的能效比差于超大核簇CPU低頻段的能效比。

從上圖的能效比曲線上,可以清楚地看出如下特點:
在同為200 util算力時,小核簇CPU比大核簇CPU更耗電,因此在系統(tǒng)負載不重時,可以讓線程傾向性的運行在大核CPU的低頻段,從而不讓小核CPU的頻率運行在高頻率段,來到達到省電而不影響系統(tǒng)性能的目的。
超大核簇CPU比大核簇CPU的能效比差很多,超大核CPU能不用需盡量不要用。
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【749907784】整理了一些個人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)??


二、能量可感知的線程選核
EAS代替CFS的線程喚醒負載均衡代碼(task wake-up balancing code
),利用CPU的Energy Model和PELT/WALT統(tǒng)計到的CPU、線程負載信息為喚醒線程選擇一個最能省電的CPU來運行。
EAS為線程選運行CPU的代碼流程如下:

2.1find_energy_efficient_cpu
find_energy_efficient_cpu()為喚醒任務(wù)找到最節(jié)能的目標CPU。在每個性能域中查找空閑算力最大的CPU,并將其作為線程運行的潛在候選CPU。然后,使用Energy Model來確定哪個CPU候選是最節(jié)能的。
一個性能域一般對應(yīng)一個CPU簇,如果線程調(diào)度到性能域空閑算力最大的那個CPU上運行,能保證該簇的CPU能運行在需求的最低頻率。
因為線程遷移的性能代價比較大(比如cache失效),只有選出的最節(jié)能CPU比線程當前運行的CPU節(jié)約能量大于6%時,線程才會遷移到該CPU運行。
下圖列出了find_energy_efficient_cpu()中最核心的代碼,并對代碼進行了詳細的注釋。


2.2compute_energy
compute_energy()預(yù)估線程p遷移到dst_cpu運行時,性能域pd的能量消耗。compute_energy()預(yù)估線程p遷移后,pd里util最大的cpu的max
_util及所有cpu的util之和sum_util,并調(diào)用Energy Model提供的API em_cpu_energy()計算線程遷移到性能域pd時的能量消耗。
下圖列出了compute_energy ()的代碼,并對代碼進行了詳細的注釋。

2.3em_cpu_energy
em_cpu_energy() 是Energy Model提供的估算性能域所有cpu的能量消耗之和的api。它有4個參數(shù),@pd需要估算能量消耗的性能域;@max_util性能域中利用率最高的CPU的利用率,它決定了整個性能域CPU的運行頻率;@sum_util性能域中所有CPU的利用率之和,用于估算整個性能域的能量消耗;@allowed_cpu_cap 性能域允許的CPU的最大算力(可能由于thermal的限制,比原始值?。?/p>
em_cpu_energy()運行流程如下:
根據(jù)性能域中利用率最高的CPU的利用率max_util估算性能域CPU需要的最低運行頻率,這里有兩點需要注意,估算頻率用的利用率是1.25倍max_util,同時預(yù)期的CPU調(diào)頻Governor是Schedutil或者與其類似的CPU的頻率遵循它的利用率的Governor。
在CPU能量模型中找到滿足frequency需求的最低性能狀態(tài)ps。
根據(jù)性能域中所有CPU的利用率之和sum_util,cpu的算力,性能狀態(tài)ps中的cost變量,估算整個性能域的能量消耗。計算公式:
ps->cost * sum_util / cpu的算力,其中ps->cost = ps->power * cpu最大頻率 / ps->frequency,其值在能量模型初始化CPU各個性能狀態(tài)時已計算好。
下圖列出了em_cpu_energy ()的代碼,并對代碼進行了詳細的注釋。

三、EAS與負載均衡
從一般的角度來看,EAS最能提供幫助的是那些輕中等CPU利用率的場景。當重載CPU-bound任務(wù)在運行時,它們需要盡可能多的CPU算力,EAS很難做到在不嚴重損害性能的情況下節(jié)約能量。為了避免EAS影響性能,一旦某個CPU的利用率超過其算力的80%,整個根域標記為‘overutilized’,EAS被禁用。當根域里所有CPU的利用率小于其算力的80%,負載均衡被禁用,EAS覆蓋了喚醒負載均衡代碼。在不影響系統(tǒng)性能時,EAS會選擇最省電的CPU來運行。因此,負載均衡被禁用來阻止其對EAS選核規(guī)則的破壞。當系統(tǒng)沒有overutilized時,這樣做是安全的。因為低于80%臨界點意味著:
所有cpu都有空閑時間,因此EAS使用的utilization信號可以準確地代表系統(tǒng)中各種任務(wù)的“大小”;
所有任務(wù)都被提供了足夠的CPU算力,不管它們的nice值是多少;
因為有空閑CPU算力,所有任務(wù)能滿足規(guī)律的blocking/sleeping,在喚醒時,做了足夠的負載均衡。
一旦某個cpu的算力超過80%這個臨界點,上面三個假設(shè)至少有一個是不正確的。在這種情況下,整個根域的overutilized標志被置為true,EAS被禁用,負載均衡被重新使能。
由于overutilization的概念很大程度上依賴于檢測系統(tǒng)中是否有空閑時間,因此必須考慮由更高(比CFS)調(diào)度類(以及IRQ)“竊取”的CPU算力。因此,overutilization的檢測不僅包括CFS任務(wù)使用的CPU算力,還包括其他調(diào)度類和IRQ使用的CPU算力。
四、小結(jié)
EAS只在系統(tǒng)負載不重時,即系統(tǒng)中每個CPU的利用率都低于其算力的80%時才被啟用,而且選出的最節(jié)能CPU只有比線程當前運行的CPU節(jié)約能量大于6%時,線程才會遷移到該CPU運行。因此EAS為線程選擇最節(jié)約能量的CPU來運行的前提條件是很苛刻的,針對重載場景(比如游戲),EAS的功能應(yīng)該很少被使用起來,針對重載場景的功耗優(yōu)化,這里可能是一個值得嘗試的點。
原文作者:內(nèi)核工匠
