利用率鉗制

1. 簡介

利用率鉗制,也稱為 util clamp 或 uclamp,是一種排程器特性,允許使用者空間幫助管理任務的效能需求。它在 v5.3 版本中引入,CGroup 支援在 v5.4 中合併。

Uclamp 是一種提示機制,允許排程器瞭解任務的效能需求和限制,從而幫助排程器做出更好的決策。當使用 schedutil cpufreq governor 時,util clamp 也會影響 CPU 頻率的選擇。

由於排程器和 schedutil 都由 PELT (util_avg) 訊號驅動,util clamp 透過鉗制訊號到某個點來實現其目標;因此得名。也就是說,透過鉗制利用率,我們使系統在某個特定的效能點執行。

正確的看待 util clamp 的方式是將其作為一種對效能約束提出請求或提示的機制。它由兩個可調引數組成:

  • UCLAMP_MIN,設定下限。

  • UCLAMP_MAX,設定上限。

這兩個邊界將確保任務在系統的這個效能範圍內執行。UCLAMP_MIN 表示提升任務,而 UCLAMP_MAX 表示限制任務。

可以告訴系統(排程器)某些任務需要以最低效能點執行才能提供所需的使用者體驗。或者可以告訴系統某些任務應該被限制消耗過多的資源,並且不應該超過特定的效能點。從使用者空間的角度來看,將 uclamp 值視為效能點而不是利用率是一種更好的抽象。

例如,遊戲可以使用 util clamp 與其感知的每秒幀數(FPS)形成反饋迴路。它可以動態地提高其顯示管道所需的最小效能點,以確保不會丟幀。如果它知道在接下來的幾百毫秒內將要發生計算密集型的場景,它也可以動態地“啟動”這些任務。

在裝置效能差異很大的移動硬體上,這種動態反饋迴路提供了很大的靈活性,以確保在任何系統的效能下都能提供最佳的使用者體驗。

當然,也可以進行靜態配置。具體的使用方式將取決於系統、應用程式和期望的結果。

另一個例子是在 Android 中,任務被分類為後臺、前臺、頂部應用程式等。Util clamp 可以透過限制後臺任務可以執行的效能點來限制它們消耗多少資源。這種約束有助於為重要的任務保留資源,例如屬於當前活動應用程式(頂部應用程式組)的任務。此外,這還有助於限制它們消耗的電量。這在異構系統中(例如 Arm big.LITTLE)可能更明顯;這種約束將有助於使後臺任務停留在小核心上,這將確保

  1. 大核心可以立即執行頂部應用程式任務。頂部應用程式任務是使用者當前正在互動的任務,因此是系統中最重要的任務。

  2. 即使它們是 CPU 密集型任務,它們也不會在耗電核心上執行並消耗電池電量。

注意

小核心:

容量 < 1024 的 CPU

大核心:

容量 = 1024 的 CPU

透過提出這些 uclamp 效能請求,或者更確切地說是提示,使用者空間可以確保系統資源得到最佳利用,從而提供最佳的使用者體驗。

另一個用例是幫助**克服排程器利用率訊號計算中固有的上升延遲**。

另一方面,例如,一個需要以最大效能點執行的繁忙任務,將需要大約 200 毫秒的延遲(PELT HALFIFE = 32 毫秒)才能讓排程器意識到這一點。已知這會影響移動裝置上的遊戲等工作負載,在這些工作負載中,由於選擇任務及時完成工作所需的更高頻率的響應時間較慢,幀會掉落。設定 UCLAMP_MIN=1024 將確保此類任務在開始執行時始終看到最高的效能級別。

如果使用得當,整體可見效果將超越更好的感知使用者體驗/效能,並擴充套件到有助於實現更好的整體效能/瓦特。

使用者空間還可以與熱子系統形成反饋迴路,以確保裝置不會升溫到需要節流的程度。

SCHED_NORMAL/OTHER 和 SCHED_FIFO/RR 都尊重 uclamp 請求/提示。

在 SCHED_FIFO/RR 的情況下,uclamp 提供了以任何效能點執行 RT 任務的選項,而不是始終繫結到最大頻率。這在執行在電池供電裝置上的通用系統中非常有用。

請注意,根據設計,RT 任務沒有每個任務的 PELT 訊號,並且必須始終以恆定頻率執行,以對抗不確定的 DVFS 上升延遲。

請注意,使用 schedutil 始終意味著在 RT 任務喚醒時修改頻率會有一個延遲。使用 uclamp 不會改變此成本。Uclamp 僅有助於選擇要請求的頻率,而不是 schedutil 始終為所有 RT 任務請求 MAX。

有關預設值,請參見第 3.4 節,有關如何更改 RT 任務預設值,請參見3.4.1

2. 設計

Util clamp 是系統中每個任務的屬性。它設定其利用率訊號的邊界;充當影響排程器內某些決策的偏差機制。

實際上,任務的實際利用率訊號永遠不會被鉗制。如果在任何時間點檢查 PELT 訊號,應該繼續看到它們保持不變。鉗制僅在需要時發生,例如:當任務喚醒並且排程器需要選擇合適的 CPU 來執行它時。

由於 util clamp 的目標是允許為任務請求最低和最高效能點來執行,因此它必須能夠影響頻率選擇以及任務放置才能最有效。這兩者都對 CPU 執行佇列(簡稱 rq)級別的利用率值產生影響,這給我們帶來了主要的設計挑戰。

當任務在 rq 上喚醒時,rq 的利用率訊號將受到所有排隊在其上的任務的 uclamp 設定的影響。例如,如果一個任務請求以 UTIL_MIN = 512 執行,那麼 rq 的 util 訊號需要尊重此請求以及所有排隊任務的所有其他請求。

為了能夠聚合附加到 rq 的所有任務的 util clamp 值,uclamp 必須在每次入隊/出隊時執行一些內務處理,這是排程器的熱路徑。因此,必須小心,因為任何減速都會對許多用例產生重大影響,並且可能會阻礙其在實踐中的可用性。

處理此問題的方法是將利用率範圍劃分為儲存桶(struct uclamp_bucket),這使我們可以將搜尋空間從 rq 上的每個任務減少到僅頂部儲存桶中的任務子集。

當任務入隊時,匹配儲存桶中的計數器會遞增,而出隊時則遞減。這使得跟蹤 rq 級別的有效 uclamp 值變得容易得多。

當任務入隊和出隊時,我們跟蹤 rq 的當前有效 uclamp 值。有關其工作方式的詳細資訊,請參見第 2.1 節

稍後,在任何想要識別 rq 的有效 uclamp 值的路徑中,它只需要讀取 rq 的這個有效 uclamp 值,以做出決策。

對於任務放置,目前只有能量感知和容量感知排程(EAS/CAS)利用 uclamp,這意味著它僅應用於異構系統。當任務喚醒時,排程器將檢視每個 rq 的當前有效 uclamp 值,並將其與任務排隊到那裡時的潛在新值進行比較。偏向於最終會產生最具能源效率組合的 rq。

同樣,在 schedutil 中,當需要進行頻率更新時,它將檢視 rq 的當前有效 uclamp 值,該值受到當前排隊在那裡的任務集的影響,並選擇滿足請求約束的適當頻率。

其他路徑(例如設定過度利用狀態(有效地停用 EAS))也利用 uclamp。這些情況被認為是必要的內務處理,以允許上述 2 個主要用例,並且由於它們可能會隨著實現細節而變化,因此在此處將不詳細介紹。

2.1. 儲存桶

                         [struct rq]

(bottom)                                                    (top)

  0                                                          1024
  |                                                           |
  +-----------+-----------+-----------+----   ----+-----------+
  |  Bucket 0 |  Bucket 1 |  Bucket 2 |    ...    |  Bucket N |
  +-----------+-----------+-----------+----   ----+-----------+
     :           :                                   :
     +- p0       +- p3                               +- p4
     :                                               :
     +- p1                                           +- p5
     :
     +- p2

注意

上圖是一個說明,而不是內部資料結構的真實描述。

為了在嘗試確定 rq 的有效 uclamp 值時減少搜尋空間,當任務入隊/出隊時,整個利用率範圍被劃分為 N 個儲存桶,其中 N 透過設定 CONFIG_UCLAMP_BUCKETS_COUNT 在編譯時配置。預設情況下,它設定為 5。

rq 具有每個 uclamp_id 可調引數的儲存桶:[UCLAMP_MIN, UCLAMP_MAX]。

每個儲存桶的範圍為 1024/N。例如,對於預設值 5,將有 5 個儲存桶,每個儲存桶將覆蓋以下範圍

DELTA = round_closest(1024/5) = 204.8 = 205

Bucket 0: [0:204]
Bucket 1: [205:409]
Bucket 2: [410:614]
Bucket 3: [615:819]
Bucket 4: [820:1024]

當具有以下可調引數的任務 p

p->uclamp[UCLAMP_MIN] = 300
p->uclamp[UCLAMP_MAX] = 1024

被排隊到 rq 中時,UCLAMP_MIN 的儲存桶 1 和 UCLAMP_MAX 的儲存桶 4 將會遞增,以反映 rq 在此範圍內有一個任務的事實。

然後,rq 跟蹤每個 uclamp_id 的當前有效 uclamp 值。

當任務 p 入隊時,rq 值變為

// update bucket logic goes here
rq->uclamp[UCLAMP_MIN] = max(rq->uclamp[UCLAMP_MIN], p->uclamp[UCLAMP_MIN])
// repeat for UCLAMP_MAX

同樣,當 p 出隊時,rq 值變為

// update bucket logic goes here
rq->uclamp[UCLAMP_MIN] = search_top_bucket_for_highest_value()
// repeat for UCLAMP_MAX

當所有儲存桶都為空時,rq uclamp 值將重置為系統預設值。有關預設值的詳細資訊,請參見第 3.4 節

2.2. 最大聚合

Util clamp 被調整為尊重需要最高效能點的任務的請求。

當多個任務附加到同一個 rq 時,util clamp 必須確保需要最高效能點的任務能夠獲得它,即使有另一個任務不需要它或不允許達到此點。

例如,如果附加到具有以下值的 rq 有多個任務

p0->uclamp[UCLAMP_MIN] = 300
p0->uclamp[UCLAMP_MAX] = 900

p1->uclamp[UCLAMP_MIN] = 500
p1->uclamp[UCLAMP_MAX] = 500

那麼假設 p0 和 p1 都排隊到同一個 rq,則 UCLAMP_MIN 和 UCLAMP_MAX 都變為

rq->uclamp[UCLAMP_MIN] = max(300, 500) = 500
rq->uclamp[UCLAMP_MAX] = max(900, 500) = 900

正如我們將在第 5.1 節中看到的那樣,這種最大聚合是使用 util clamp 時的限制之一的原因,特別是對於 UCLAMP_MAX 提示,當用戶空間想要節省電量時。

2.3. 分層聚合

如前所述,util clamp 是系統中每個任務的屬性。但是實際應用(有效)值不僅可能受到任務提出的請求或代表其(中介軟體庫)的另一個參與者的影響。

任何任務的有效 util clamp 值都受到以下限制

  1. 如果存在,則受其附加到的 cgroup CPU 控制器定義的 uclamp 設定的限制。

  2. (1)中的受限值然後受到系統範圍的 uclamp 設定的進一步限制。

第 3 節討論了介面,並將對此進行進一步擴充套件。

現在足以說明,如果任務提出請求,則其實際有效值將必須遵守 cgroup 和系統範圍設定施加的一些限制。

即使實際上超出了約束,系統仍將接受該請求,但是一旦任務移動到不同的 cgroup 或系統管理員修改了系統設定,只有當請求在新約束範圍內時,該請求才能得到滿足。

換句話說,當任務更改其 uclamp 值時,此聚合不會導致錯誤,而是系統可能無法根據這些因素滿足請求。

2.4. 範圍

Uclamp 效能請求的範圍為 0 到 1024(含)。

對於 cgroup 介面,使用百分比(即 0 到 100(含))。與其他 cgroup 介面一樣,可以使用“max”代替 100。

3. 介面

3.1. 每個任務介面

sched_setattr() 系統呼叫已擴充套件為接受兩個新欄位

  • sched_util_min:請求系統在此任務執行時應執行的最低效能點。或更低的效能邊界。

  • sched_util_max:請求系統在此任務執行時應執行的最大效能點。或更高的效能邊界。

例如,以下場景具有 40% 到 80% 的利用率約束

attr->sched_util_min = 40% * 1024;
attr->sched_util_max = 80% * 1024;

當任務 @p 執行時,**排程器應盡最大努力確保它以 40% 的效能級別開始**。如果任務執行的時間足夠長,以至於其實際利用率超過 80%,則利用率或效能級別將被限制。

特殊值 -1 用於將 uclamp 設定重置為系統預設值。

請注意,使用 -1 將 uclamp 值重置為系統預設值與手動將 uclamp 值設定為系統預設值不同。這種區別很重要,因為正如我們將在系統介面中看到的那樣,RT 的預設值可能會被更改。SCHED_NORMAL/OTHER 將來也可能會獲得類似的旋鈕。

3.2. cgroup 介面

CPU cgroup 控制器中有兩個與 uclamp 相關的值

  • cpu.uclamp.min

  • cpu.uclamp.max

當任務附加到 CPU 控制器時,其 uclamp 值將受到以下影響

  • cpu.uclamp.min 是保護,如cgroup v2 文件的第 3-3 節中所述。

    如果任務 uclamp_min 值低於 cpu.uclamp.min,則任務將繼承 cgroup cpu.uclamp.min 值。

    在 cgroup 層次結構中,有效的 cpu.uclamp.min 是 (子級,父級) 的最大值。

  • cpu.uclamp.max 是限制,如cgroup v2 文件的第 3-2 節中所述。

    如果任務 uclamp_max 值高於 cpu.uclamp.max,則任務將繼承 cgroup cpu.uclamp.max 值。

    在 cgroup 層次結構中,有效的 cpu.uclamp.max 是 (子級,父級) 的最小值。

例如,給定以下引數

p0->uclamp[UCLAMP_MIN] = // system default;
p0->uclamp[UCLAMP_MAX] = // system default;

p1->uclamp[UCLAMP_MIN] = 40% * 1024;
p1->uclamp[UCLAMP_MAX] = 50% * 1024;

cgroup0->cpu.uclamp.min = 20% * 1024;
cgroup0->cpu.uclamp.max = 60% * 1024;

cgroup1->cpu.uclamp.min = 60% * 1024;
cgroup1->cpu.uclamp.max = 100% * 1024;

當 p0 和 p1 附加到 cgroup0 時,這些值變為

p0->uclamp[UCLAMP_MIN] = cgroup0->cpu.uclamp.min = 20% * 1024;
p0->uclamp[UCLAMP_MAX] = cgroup0->cpu.uclamp.max = 60% * 1024;

p1->uclamp[UCLAMP_MIN] = 40% * 1024; // intact
p1->uclamp[UCLAMP_MAX] = 50% * 1024; // intact

當 p0 和 p1 附加到 cgroup1 時,這些值變為

p0->uclamp[UCLAMP_MIN] = cgroup1->cpu.uclamp.min = 60% * 1024;
p0->uclamp[UCLAMP_MAX] = cgroup1->cpu.uclamp.max = 100% * 1024;

p1->uclamp[UCLAMP_MIN] = cgroup1->cpu.uclamp.min = 60% * 1024;
p1->uclamp[UCLAMP_MAX] = 50% * 1024; // intact

請注意,cgroup 介面允許 cpu.uclamp.max 值低於 cpu.uclamp.min。其他介面不允許這樣做。

3.3. 系統介面

3.3.1 sched_util_clamp_min

允許的 UCLAMP_MIN 範圍的系統範圍限制。預設情況下,它設定為 1024,這意味著任務允許的有效 UCLAMP_MIN 範圍為 [0:1024]。例如,將其更改為 512 會將範圍縮小到 [0:512]。這對於限制允許任務獲取多少提升非常有用。

任務提出的高於此旋鈕值的請求仍然會成功,但是在它大於 p->uclamp[UCLAMP_MIN] 之前,它們不會得到滿足。

該值必須小於或等於 sched_util_clamp_max。

3.3.2 sched_util_clamp_max

允許的 UCLAMP_MAX 範圍的系統範圍限制。預設情況下,它設定為 1024,這意味著任務允許的有效 UCLAMP_MAX 範圍為 [0:1024]。

例如,將其更改為 512 會將有效允許範圍縮小到 [0:512]。這意味著沒有任務可以高於 512 執行,這意味著所有 rq 也受到限制。換句話說,整個系統的效能容量都被限制為一半。

這對於限制系統的整體最大效能點非常有用。例如,當電池電量不足時,或者當系統想要限制訪問更耗能的效能級別時(當系統處於空閒狀態或螢幕關閉時),它可以方便地限制性能。

任務提出的高於此旋鈕值的請求仍然會成功,但是在它大於 p->uclamp[UCLAMP_MAX] 之前,它們不會得到滿足。

該值必須大於或等於 sched_util_clamp_min。

3.4. 預設值

預設情況下,所有 SCHED_NORMAL/SCHED_OTHER 任務都初始化為

p_fair->uclamp[UCLAMP_MIN] = 0
p_fair->uclamp[UCLAMP_MAX] = 1024

也就是說,預設情況下,它們被提升到以啟動或執行時更改的最大效能點執行。尚未提出任何理由說明我們為什麼應該提供此功能,但將來可以新增。

對於 SCHED_FIFO/SCHED_RR 任務

p_rt->uclamp[UCLAMP_MIN] = 1024
p_rt->uclamp[UCLAMP_MAX] = 1024

也就是說,預設情況下,它們被提升到以系統的最大效能點執行,這保留了 RT 任務的歷史行為。

RT 任務的預設 uclamp_min 值可以透過 sysctl 在啟動或執行時修改。請參見以下部分。

3.4.1 sched_util_clamp_min_rt_default

以最大效能點執行 RT 任務在電池供電裝置上是昂貴的,並且不是必需的。為了允許系統開發人員為這些任務提供良好的效能保證,而無需將其一路推到最大效能點,此 sysctl 旋鈕允許調整最佳提升值,以滿足系統要求,而無需始終以最大效能點執行來消耗電量。

鼓勵應用程式開發人員使用每個任務的 util clamp 介面,以確保他們瞭解效能和功耗。理想情況下,系統設計人員應將此旋鈕設定為 0,並將管理效能要求的任務留給應用程式。

4. 如何使用 util clamp

Util clamp 提倡使用者空間輔助電源和效能管理的概念。在排程程式級別,無需任何資訊即可做出最佳決策。但是,透過 util clamp,使用者空間可以提示排程程式做出有關任務放置和頻率選擇的更好決策。

透過不對應用程式執行的系統做出任何假設,並將其與反饋迴圈結合使用以動態監視和調整,可以獲得最佳結果。最終,這將以更好的 perf/watt 實現更好的使用者體驗。

對於某些系統和用例,靜態設定將有助於獲得良好的結果。在這種情況下,可移植性將是一個問題。在 100、200 或 1024 處可以完成多少工作,對於每個系統都是不同的。除非有特定的目標系統,否則應避免靜態設定。

有足夠的可能性基於 util clamp 建立整個框架或直接使用它的獨立應用程式。

4.1. 提升重要且對 DVFS 延遲敏感的任務

GUI 任務可能不會忙到需要驅動頻率升高才能喚醒。但是,它需要在特定的時間範圍內完成其工作,才能提供所需的使用者體驗。它在喚醒時需要的正確頻率將取決於系統。在某些功率不足的系統上,它會很高,而在其他功率過大的系統上,它會很低或為 0。

此任務可以在每次錯過截止日期時增加其 UCLAMP_MIN 值,以確保在下次喚醒時,它以更高的效能點執行。它應該嘗試接近最低的 UCLAMP_MIN 值,該值允許在任何特定系統上滿足其截止日期,以實現該系統可能實現的最佳 perf/watt。

在異構系統上,此任務在更快的 CPU 上執行可能很重要。

通常建議將輸入視為效能級別或點,這將意味著任務放置和頻率選擇.

4.2. 限制後臺任務

就像在介紹中針對 Android 案例所解釋的那樣。任何應用程式都可以降低某些不關心效能但最終可能會很忙併消耗系統中不必要的系統資源的後臺任務的 UCLAMP_MAX。

4.3. 省電模式

sched_util_clamp_max 系統範圍的介面可用於限制所有任務以通常低效的更高效能點執行。

這並非 uclamp 所獨有,因為可以透過降低 cpufreq governor 的最大頻率來實現相同的目的。它可以被認為是更方便的替代介面。

4.4. 每個應用程式的效能限制

中介軟體/實用程式可以為使用者提供一個選項,以在每次執行應用程式時為該應用程式設定 UCLAMP_MIN/MAX,以保證最低效能點和/或限制它消耗系統電量,但會降低這些應用程式的效能。

如果你想防止你的筆記型電腦在旅途中編譯核心時發熱,並且樂於犧牲效能以節省電量,但仍然希望保持瀏覽器的效能完整,那麼 uclamp 使之成為可能。

5. 侷限性

5.1. 在某些條件下,使用 uclamp_max 限制頻率失敗

如果任務 p0 被限制為以 512 執行

p0->uclamp[UCLAMP_MAX] = 512

並且它與 p1 共享 rq,p1 可以自由地以任何效能點執行

p1->uclamp[UCLAMP_MAX] = 1024

那麼由於最大聚合,rq 將被允許達到最大效能點

rq->uclamp[UCLAMP_MAX] = max(512, 1024) = 1024

假設 p0 和 p1 的 UCLAMP_MIN = 0,那麼 rq 的頻率選擇將取決於任務的實際利用率值。

如果 p1 是一個小任務,但 p0 是一個 CPU 密集型任務,那麼由於兩者都執行在同一個 rq 上,p1 將導致從 rq 中取消頻率限制,儘管 p1(允許以任何效能點執行)實際上不需要以該頻率執行。

5.2. UCLAMP_MAX 可以破壞 PELT (util_avg) 訊號

PELT 假設頻率會隨著訊號的增長而始終增加,以確保 CPU 上始終有一些空閒時間。但是,使用 UCLAMP_MAX,將阻止這種頻率增加,這可能導致在某些情況下沒有空閒時間。當沒有空閒時間時,任務將卡在繁忙迴圈中,這將導致 util_avg 為 1024。

結合下面描述的問題,當受到嚴重限制的任務與一個小的非限制任務共享 rq 時,這可能導致不必要的頻率峰值。

例如,如果任務 p,它具有

p0->util_avg = 300
p0->uclamp[UCLAMP_MAX] = 0

在空閒 CPU 上喚醒,那麼它將以該 CPU 能夠實現的最小頻率 (Fmin) 執行。最大 CPU 頻率 (Fmax) 在這裡也很重要,因為它指定了完成此 CPU 上任務工作的最短計算時間。

rq->uclamp[UCLAMP_MAX] = 0

如果 Fmax/Fmin 的比率為 3,則最大值將為

300 * (Fmax/Fmin) = 900

這表明 CPU 仍然會看到空閒時間,因為 900 小於 1024。但是,_實際_ util_avg 不會是 900,而是在 300 和 900 之間。只要有空閒時間,p->util_avg 更新就會有一定的偏差,但與 Fmax/Fmin 不成比例。

p0->util_avg = 300 + small_error

現在,如果 Fmax/Fmin 的比率為 4,則最大值變為

300 * (Fmax/Fmin) = 1200

這高於 1024,表明 CPU 沒有空閒時間。發生這種情況時,_實際_ util_avg 將變為

p0->util_avg = 1024

如果任務 p1 在此 CPU 上喚醒,它具有

p1->util_avg = 200
p1->uclamp[UCLAMP_MAX] = 1024

那麼根據最大聚合規則,CPU 的有效 UCLAMP_MAX 將為 1024。但是,由於受限制的 p0 任務正在執行並受到嚴重限制,因此 rq->util_avg 將為

p0->util_avg = 1024
p1->util_avg = 200

rq->util_avg = 1024
rq->uclamp[UCLAMP_MAX] = 1024

因此導致頻率峰值,因為如果 p0 沒有受到限制,我們應該得到

p0->util_avg = 300
p1->util_avg = 200

rq->util_avg = 500

並且在該 CPU 的中等效能點附近執行,而不是我們得到的 Fmax。

5.3. Schedutil 響應時間問題

schedutil 有三個侷限性

  1. 硬體需要非零的時間來響應任何頻率更改請求。在某些平臺上,可能在幾毫秒的數量級。

  2. 非快速切換系統需要工作執行緒喚醒並執行頻率更改,這會增加可測量的開銷。

  3. schedutil rate_limit_us 會在此 rate_limit_us 視窗期間刪除任何請求。

如果一個相對較小的任務正在執行關鍵作業,並且在喚醒並開始執行時需要特定的效能點,那麼所有這些侷限性都將阻止它在預期的時間範圍內獲得它想要的東西。

此侷限性不僅在使用 uclamp 時會產生影響,而且會隨著我們不再逐漸升高或降低而變得更加普遍。根據任務喚醒的順序及其各自的 uclamp 值,我們可以輕鬆地在頻率之間跳轉。

我們認為這是底層系統本身的功能限制。

有改進 schedutil rate_limit_us 行為的空間,但對於 1 或 2 沒有太多可做的。它們被認為是系統的硬性限制。