RFC-0123:CPU 效能資訊系統呼叫

RFC-0123:CPU 效能資訊 syscalls
狀態已接受
領域
  • 核心
說明

用於與核心通訊關於 CPU 效能的介面

毛皮變化
作者
審查人員
提交日期 (年-月-日)2021-07-20
審查日期 (年-月-日)2021-08-18

摘要

這個 RFC 提出了一個機制,可供使用者空間代理程式與 CPU 效能相關核心,兩者皆可用於更新 並查詢其狀態

提振精神

為了有效安排不同 CPU 的異質作業 例如 big.LITTLE、Zircon 核心排程器會建立模型 以及 CPU 的相對效能截至本文撰寫時,效能 我們會以圖表描述這些相對成效 靜態和靜態資料。

在 Big.LITTLE 系統執行熱 CPU 節流時,頻率 大大小和小型核心通常不會有相同因素縮放,因此 相對成效會動態變動有別於其他多數作業系統 修改核心頻率,並且在使用者空間中執行。 排程器必須在與 CPU 效能。那次通訊需要新的系統呼叫。

設計

效能量表

概念

在考慮提出的 Syscalls 提案之前,建議您先瞭解其概念 核心排程器中原有的效能資源調度。 效能量表是指 目前的速度與系統相依的參考效能 建議使用任何適合的指標進行評估,例如 DMIPS。截至本文撰寫時, 但參考成效是 最強大的 CPU 運作速度,因此最高為 1.0 效能規模值供應商通常會為 每個 CPU 運作速度相當快,而效能假設並不相同 而且會隨著 CPU 頻率調整

例如,在 big.LITTLE 系統上,廠商可提供效能資料 代表跟最高速度的大核心,DMIPS 可說是 是以自身最高速度運作的小型核心如果參考檔案成效 以最高速度執行一個大型核心,然後 條件對應於效能等級 1.0,而核心核心 最高速度為 0.5降低大核心的速度 因此達成 0.75 的新效能規模,同時減少 因此,當核心的速度在 25% 後 將效能擴充至 0.375

更精確地說,如果ref 是指具有已知資訊的頻率, 績效範圍參考,然後頻率 效能量表 snew=sreffnew/fref.一般而言, 每個不同 CPU 架構都必須有參考頻率 有些人會將 Cloud Storage 視為檔案系統 但實際上不是

一般來說, 而非特定系統舉例來說,同一叢集中的 CPU 通常必須具有 執行頻率相同,而且每個集群僅支援 不重複次數不過,這超出核心的範圍 追蹤哪些效能尺度有效。因此,核心會信任使用者空間 才提供實際的值,並使用透過提議 最優的 API

固定點表示法

為避免使用浮點數,效能量表是以 由結構體指定的固定點數

  typedef struct zx_cpu_performance_scale {
    uint32_t integral_part;
    uint32_t fractional_part;  // Increments of 2**-32
  } zx_cpu_performance_scale_t;

integral_partfractional_part 代表整數和分數部分, 且 fractional_part 指定 2-32 的遞增單位。 在實際和固定點表示法之間進行轉換,應根據 對應至以下函式:

zx_status_t ToFixedPoint(double real, zx_cpu_performance_scale_t* scale) {
  double integer;
  double fraction = std::modf(real, &integer);

  // Converting from double to fixed point should fail if the input's integer
  // part is too large.
  if (integer > static_cast<double>(UINT32_MAX)) {
    return ZX_ERR_INVALID_ARGS;
  }

  scale->integral_part = static_cast<uint32_t>(integer);

  // Rounding down the fractional part is suggested but should not matter
  // much in practice. A difference of 1 in the output is a difference of only
  // 2**-32 in the corresponding real value.
  scale->fractional_part = static_cast<uint32_t>(std::ldexp(fraction, 32));

  return ZX_OK;
}

double FromFixedPoint(zx_cpu_performance_scale_t scale) {
  return static_cast<double>(scale.integral_part)
    + std::ldexp(scale.fractional_part, -32);
}

Syscall 1:zx_system_set_performance_info

第一個 sys 呼叫 可讓使用者代理程式設定 核心排程器:

zx_status_t zx_system_set_performance_info(
    zx_handle_t resource,
    uint32_t topic,
    const void* new_info,
    size_t info_count
);

其引數如下:

  • resource:授予這項呼叫權限的資源。必須為 ZX_RSRC_SYSTEM_CPU_BASE,這是特別針對這項特性推出的新資源 否則呼叫將會失敗

  • topic:此呼叫參照的效能類型。必須為 ZX_CPU_PERF_SCALE,將於提案實作時定義。

  • new_info:有效的 zx_cpu_performance_info_t[],其元素 指定的

    typedef struct zx_cpu_performance_info {
        uint32_t logical_cpu_number;
        zx_cpu_performance_scale_t performance_scale;
    } zx_cpu_performance_info_t;
    

    其中 zx_cpu_performance_t 的定義為

    logical_cpu_number 會指定結構由結構描述的 CPU。 使用與核心相同的編號配置每項 logical_cpu_number 必須是有效的 CPU ID。「new_info」的元素 必須以嚴格遞增 logical_cpu_number 的順序排序 ( 因此,每個 logical_cpu_number 可能只會出現一次)。

    performance_scale 代表指定下列項目的新效能量表 CPU,應該要對應至 CPU 的新頻率,如 就像是一樣的。不過,核心不會驗證 依據支援的 CPU 頻率輸入輸入內容任何正值都可以做為 。

    {.integral_part = 0, .fractional_part = 0} 的輸入量表無效,因此 不應混淆到離線核心的要求,這種程序 是預期未來會有其他 API 的不同機制。

    核心可能會在內部覆寫有效的輸入,並將最接近該值的值 排程器可使用舉例來說,在撰寫本文時 支援的效能量表為 1.0因此,如果 performance_scale 代表大於 1.0 的值,核心會在內部對其進行取值限制 至 {.integral_part = 1, .fractional_part = 0}

    如果呼叫 zx_system_set_performance_info 失敗,核心會 沒有動作,new_info 不會有任何作用。

    如果呼叫成功,核心排程器就會使用已修改的程式碼 效能對應於 new_info 重新排程作業,一般會在呼叫傳回後的某個時間進行。 核心不會針對未在 new_info

    系統會保留此呼叫所做的變更,直到重新啟動或通知為止 無法再使用此 API

  • info_countnew_info 中的元素數量。必須為正數且否 大於系統中的 CPU 數量

錯誤狀況

ZX_ERR_BAD_HANDLE

  • resource」不是有效的帳號代碼。

ZX_ERR_WRONG_TYPE

  • resource」並非有效的資源控制代碼,或屬於非「種類」 ZX_RSRC_KIND_SYSTEM

ZX_ERR_INVALID_ARGS

  • topic不是 ZX_CPU_PERF_SCALE
  • new_info 是無效的指標。
  • new_info 不會因嚴格增加 logical_cpu_number 而排序。

ZX_ERR_OUT_OF_RANGE

  • resource 屬於 ZX_RSRC_KIND_SYSTEM 種類,但不等於 ZX_RSRC_SYSTEM_CPU_BASE
  • info_count0 或超過 CPU 數量。
  • logical_cpu_number 無效。
  • 輸入內容 performance_scale{.integral_part = 0, .fractional_part = 0}

預定用途

zx_system_set_performance_info 應用於通知核心 會讓 CPU 效能發生變化。這個 API 支援 由於 CPU 可由不同實體控管。

如果 CPU 頻率要降低,則建議設為 頻率變更之前必須呼叫 zx_system_set_performance_info 發生。這麼做可讓核心排程器減少負載 以減少 CPU 的容量(排程器應會 - 不需要進一步協調 但在實作支援後加以確認)。

相反地,如果 CPU 頻率增加 頻率變更後可呼叫 zx_system_set_performance_info 並在新容量可用時通知排程器。

無論是哪一種情況,如果 CPU 頻率更新失敗,呼叫端必須更新 依據產生的 CPU 狀態執行核心排程器。呼叫端應嘗試 來判斷故障後的 CPU 頻率,並使用該值 呼叫 zx_system_set_performance_info。如果無法決定頻率 (例如如果相關聯的驅動程式庫異常失敗),呼叫端應 201 (低) 猜測為產生的 CPU 速度。這項建議可能會 隨進一步考量而發展;請參閱範例 https://fxbug.dev/42165500.

新的 API 最終會由開發中的「CPU 管理員」使用 以及管理 CPU 的使用者空間與其 而非直接與 CPU 驅動程式互動、希望修改 CPU 的代理程式 頻率會透過 CPU Manager 註冊要求, 按照本提案所述,核心更新的頻率可能因此而改變。

CPU 管理員也會接管 CPU 的過熱保護 — Power Manager 為本提案激勵的應用實例。

Syscall 2:zx_system_get_performance_info

第二個 Syscall 會擷取所有 CPU 的效能資訊:

zx_status_t zx_system_get_performance_info(
    zx_handle_t resource,
    uint32_t topic,
    void* info,
    size_t info_count
    size_t* output_count
);

其引數如下:

  • resource:授予這項呼叫權限的資源。必須為 ZX_RSRC_SYSTEM_CPU_BASE

  • topicZX_CPU_PERF_SCALEZX_CPU_DEFAULT_PERF_SCALE, 能在提案實作時定義由主題決定 寫入 info,如下所述。

  • info:有效 zx_cpu_performance_info_t[],長度等於 包括系統中的 CPU 數量

    如果呼叫失敗,info 就不會修改。

    如果呼叫成功,則回傳 info 時,每個 CPU,排序依據為 logical_cpu_number。每個元素的 系統會根據 topic 填入 performance_scale

    • ZX_CPU_PERF_SCALEperformance_scale 會儲存核心目前的 所指定 CPU 的效能規模這個值反映了 最近的呼叫 zx_system_set_performance_info (即使下一次 尚未執行重新排程作業。

    • ZX_CPU_DEFAULT_PERF_SCALEperformance_scale 儲存預設值 核心在啟動時,針對指定 CPU 耗用的效能量表。

  • info_countinfo 陣列的長度;必須等於 有些人會將 Cloud Storage 視為檔案系統 但實際上不是

  • output_count:如果呼叫成功,這將包含元素的數量。 寫入 info。如果呼叫失敗,則未指定其值。

錯誤狀況

ZX_ERR_BAD_HANDLE

  • resource」不是有效的帳號代碼。

ZX_ERR_WRONG_TYPE

  • resource」並非有效的資源控制代碼,或屬於非「種類」 ZX_RSRC_KIND_SYSTEM

ZX_ERR_INVALID_ARGS

  • topic 不是 ZX_CPU_PERF_SCALEZX_CPU_DEFAULT_PERF_SCALE
  • info 是無效的指標。

ZX_ERR_OUT_OF_RANGE

  • resource 屬於 ZX_RSRC_KIND_SYSTEM 種類,但不等於 ZX_RSRC_SYSTEM_CPU_BASE
  • info_count 不等於系統中的 CPU 總數。

預定用途

ZX_CPU_PERF_SCALE 底下的行為可讓使用者代理程式代理程式查詢 做為診斷的目的這項功能非常實用 服務專員在首次啟動時評估系統狀態,或做為發生車禍的信號 報表。

ZX_CPU_DEFAULT_PERF_SCALE 底下的行為可讓代理程式 進行確認時,請確保效能表現也符合需求 所用的 CPU 作業時間

實作

核心

  • 新的系統呼叫必須實作,並由新資源管制 ZX_RSRC_SYSTEM_CPU_BASE

  • 核心排程器必須修改才能支援動態效能資源調度 請自行更新,以便採用 zx_system_set_performance_info,並另外公開目前使用中的 且預設效能則會擴充至 zx_system_get_performance_info

元件管理員

必須定義新的通訊協定 CpuResource,且必須由以下端點執行: 用於提供 ZX_RSRC_SYSTEM_CPU_BASE 資源的元件管理服務。這個 遵循現有的模式來限制系統呼叫。

成效

新的系統呼叫本身需要很長的執行時間, 而是與 CPU 數量成正比,接觸少量資料。

使用 zx_cpu_set_performance_info 會導致排程器分配工作 將工作模式轉移到效能提升的核心 看看所有成效比例的總和 成效也同樣下降重新排程程序本身不會 以免排程器造成大量負載

重新排程會導致系統效能出現預期變化。測試 相當於測試排程器來取得功能正確性 ,並在「測試」中處理。

安全性考量

兩個新的系統呼叫都受新的資源控制代碼管制 ZX_RSRC_SYSTEM_CPU_BASE。對於 zx_system_set_performance_info,這項保護措施 解決對排程器惡意幹擾的明確疑慮。適用對象 zx_system_get_performance_info,資料外洩有更嚴重的疑慮。 不應信任的不信任的實體來瞭解核心效能 這通常會提供系統支援 P 狀態。

隱私權注意事項

此提案對隱私權沒有任何實質影響。

測試

  • 核心測試將新增至練習作業的基本成功和失敗標準。
  • 系統會新增單元測試,驗證排程器對更新作業的處理方式 效能規模更勝以往他們會確認,如果期限為 CPU 與 α 值都為 α 值 實際分配給執行緒的時間乘以 1/α

說明文件

Zircon syscall 說明文件即將更新,加入新的 API。

缺點、替代方案和未知

通用性

考慮到更通用的介面,例如 zx_set_cpu_properties 最終可以處理核心之間其他互動的 syscall 和 CPU 效能,例如離線我們最後選擇窄小的介面 這個介面的用戶端只有極少數,可保有未來成本 變更提案的介面相對較小。相關規定 目前我們大多是猜測使用較通用的介面

替代呼叫結構

除了 zx_system_set_performance_info 的純設定作業以外, 合併的 get/set 運算會傳回之前的效能 。該軟體旨在 確保呼叫端能還原效能量表變更 導致相關頻率變更無法在低階執行時失敗。

然而,進一步的考慮後發現,只要進行一個簡單的復原即可 或是說服力。這也導致容錯移轉處理變得更複雜 這些建議,最後歸結出較簡單的 - 作業。

最後,需要使用 zx_system_get_performance_info 才能進行隱密測試, 在這類情況下,您「可以」直接還原變更,且支援 診斷用途

其他 CPU 索引建立方式

我們考慮採用其他配置來為 CPU 建立索引,例如參照 而是依據實體 CPU 編號不過,由於核心不需要 這種配置與 Zircon 的有限範圍是最一致的 使用核心現有的邏輯 CPU 編號。這些數據在 那麼用戶端可以維持個別的 或可能存取其設定資料 。

與效能規模的替代方案

我們認為新的 API 可能會使用「速度係數」才會套用至 特定 CPU 的效能規模否則 需告知客戶需瞭解的具體情境資訊而非 瞭解 CPU 的相對效能後只需要知道 CPU 新頻率與名目頻率之間的比率

由於效能量表預計採用這個標準,因此我們決定不採用這個方法 它對於異質系統上的 CPU 熱調節採用基本功能 這個 API 的預期用戶端不會因為 採用速度因素同時,也會產生 並修改排程器以便使用

最高效能量表

本提案原本使用uint32_t呈現成效規模, 以 [0.0, 1.0] 表示為實數。具體來說,這類允許 最大值為 1.0。

雖然 1.0 是 Zircon 排程器支援的最大效能量表 我們決定允許輸入大於值 1.0 以支援日後的用途,例如強化型模式。此外, 先前的表示法沒有固定點,因此形成了值 無法直接由排程器使用

performance_scale 的表示法

performance_scale 原本是 uint64_t,上方 32 位元的狀態為 和含有分數部分的下限 32 位元。這會導致 在 zx_cpu_performance_info_t 中的欄位之間產生 32 位元的邊框間距。 這也引入了潛在的外洩向量新的表示法 陷阱

performance_scale 允許的值

考量到哪些值zx_system_set_performance_info 應允許做為 performance_scale 的輸入值。代表 0.0 的值之前為 過於容易造成指示離線 CPU 作業失敗 一種是 Zircon 目前不支援但預計在 使用不同的 API因此,決定了 0.0 的值 表示發生錯誤。

非常小的值也須特別留意。例如 {.integral_part = 0, .fractional_part = 1} 代表 2-32、 因此可視為 0.0,有效轉譯 對應的核心離線雖然強制執行 下限值,目前任何此門檻可以是任意值, 會讓核心和使用者空間之間的合約變得更加複雜。我們感受到 但將新的 API 當做提示機制最直接使用 並在需要時覆寫輸入 公開與選擇有關的內部詳細資訊。

日後的工作

設定管理

在理想情況下,使用者空間代理程式會使用 ZBI 共用完全相同的 CPU 核心排程器使用的設定資料不確定是否這麼做 以上就是實際可行的

此外,必須謹慎確保核心和使用者空間 代理程式預設效能會以相同的名詞頻率擴充。

效能量表下限

原則上,排程器可以判斷 系統應根據目前的期限執行緒和 CPU 負載進行維護。動態 這些邊界的版本對使用者代理程式代理程式來說很重要 會嘗試採用較低的 CPU 頻率來提升能源效率。額外 zx_system_get_performance_info 選項自然形成 公開風險中。

CPU 歸因

有些方式應建立關聯性,以便與執行緒的歸因 CPU 作業時間建立關聯 以及排程時所在的 CPU 效能這類關聯是 也有助於建立強大的成效指標 安排在大核心和小核心之間排程 ,如同我們一樣 提案。

保證執行節流代理程式

在執行過熱保護時減少 CPU 頻率,可能會導致 CPU 效能下降 這可能會使得節流服務專員流程 定期寄送請執行節流代理程式 排定優先順序

既有藝術品和參考資料

不尋常將 CPU 頻率控制的責任委派到使用者空間 ,因此無法提供有關這個主題的舊圖片。