RFC-0113:有效信封

RFC-0113:高效率信封
狀態已接受
區域
  • FIDL
說明

這個 FTP 會為信封提供更精簡的編碼。

Gerrit 變更
作者
審查人員
提交日期 (年-月-日)2021-06-21
審查日期 (年-月-日)2021-07-21

「將信封轉換為明信片」

摘要

本 RFC 提出了 FIDL 的更精簡編碼1

提振精神

信封是可擴充、可進化的資料結構 (表格和可擴充的聯集) 的基礎。封套的線路格式更精簡且高效,因此可在效能和線路大小較重要的更多情境中使用這些可擴充的結構。

設計

建議的封套格式可用下列 C 結構體來描述:

struct Envelope {
    uint32_t byte_size;
    uint32_t handle_count;
};

現有的封套格式相比:

  • 位元組大小欄位保持不變 (32 位元)。
    • 大小包括任何可能遞迴編碼的子物件大小。
    • 舉例來說,vector<string> 的大小包含外部向量內部字串子物件的大小。
    • 這與目前信封實作大小欄位的現有行為相符。
  • 句柄計數欄位保持不變 (32 位元)。
    • handle_count 包含所有遞迴子物件的句柄計數。
  • 「有/無」欄位已刪除。
    • 在 size 或 handle_count 欄位中,非零值代表存在。
    • 大小和句柄計數欄位都為零,表示沒有。
  • 位元組大小欄位驗證
    • 位元組大小欄位必須經過驗證,確認為 8 的倍數。

假設解碼器知道信封內容的靜態類型 (結構定義),則可能會使用指向信封資料的指標覆寫信封。如要瞭解如何處理內容類型不明的封套,請參閱「不明資料」一節中的建議。

用於編碼/解碼表單的 C/C++ 結構體

信封的編碼或解碼形式可描述為 C 聯集:

typedef union {
  struct {
    uint32_t byte_size;
    uint32_t handle_count;
  } encoded;
  void* data;
} fidl_envelope_t;

static_assert(sizeof(fidl_envelope_t) == sizeof(void*));

不明資料

接收器 (驗證器和解碼器) 在可進化的資料結構中使用時,可能不知道封套的類型。如果接收端不瞭解類型,則可對信封進行最少的剖析,並略過信封。

  • 信封的大小決定要略過的離線資料量。
  • 如果信封的句柄數量不為零,驗證工具就必須儲存或關閉每個句柄。
  • 如果解碼器想要就地解碼,則可能會使用指向信封內容的指標覆寫不明信封。
    • 如果解碼器確實使用指標覆寫封套,就會遺失封套中的大小和句柄計數資訊。繫結可能會提供機制,讓解碼器在覆寫封套之前儲存大小和句柄計數資訊;這份 RFC 不會針對此機制的運作方式發表意見。

導入策略

這項 RFC 是破壞性的線路格式變更。

我們將進行複雜的電報格式遷移作業,以便切換至高效的封包。這項線路格式變更將與其他遷移作業結合,以降低每項功能的遷移成本。

回溯相容性

所提議的傳輸格式變更與 API (來源) 相容。任何手動編譯的 FIDL 程式碼都必須更新,才能處理新的線路格式。

傳輸格式變更與 ABI 不相容

成效

CL 中執行了效能評估,這個原型可實現高效的封包實作。在這個測試中,輸入內容是已設定所有欄位的資料表。其他輸入內容也會產生類似結果。

下列時間以奈秒為單位。沒有效率信封的時間在箭頭前方,有效率信封的時間則在箭頭後方。

# 欄位 編碼 Decode
16 64 -> 40 176 -> 146
64 165 -> 121 321 -> 221
256 567 -> 368 923 -> 527
1024 2139 -> 1429 3284 -> 1636

視輸入內容而定,使用高效信封的速度似乎比一般信封快 1.1 到 2 倍

人體工學

  • 更有效率的可擴充資料結構可用於效率至關重要的更多情境,因此使用者不必太擔心效能問題,而且可在先前需要使用不可擴充結構的情況下,享有可擴充性帶來的好處。
  • 我們甚至建議您在預設情況下使用表格來處理 Fidl 資料結構,並將結構體保留給高效能情境。
    • 可擴充的聯集 (RFC-0061) 已嘗試移除靜態聯集。

說明文件

  • 需要更新線路格式說明文件。
  • 更新說明文件時,應將信封解釋為第一類概念:這樣一來,讀者遇到可選性和可延伸資料結構的電報格式時,就能進行更好的認知區塊處理
  • 我們應更新 FIDL 樣式指南,針對應使用可擴充類型的時機提供建議。

安全性

這項 RFC 不應對安全性造成任何影響。

這項 RFC 的其中一個小型安全性優點,就是移除舊版格式中大小和指標重複的資訊。先前,您可能會收到大小/句柄非零值的封套,以及 FIDL_ALLOC_ABSENT,或是大小/句柄為零的封套,以及 FIDL_ALLOC_PRESENT。這項功能需要額外的驗證檢查,但現在已不需要。

無法僅根據資料判斷信封是否為電報形式或解碼形式。這並不是問題,因為實際上,繫結中總是會分開記錄訊息是否為電報格式或解碼格式。

隱私權

這項 RFC 不應對隱私權造成任何影響。

測試

  • 由於本 RFC 會變更信封的線路格式,我們認為現有的 FIDL 測試套件 (尤其是相容性測試) 將可充分測試所有使用信封的情況。
  • 如果我們同意以軟性轉換方式導入線路格式變更 (請參閱「導入策略」一節),我們會新增測試,讓同儕進行協商,並可能改用新的線路格式。

缺點、替代方案和未知事項

如果我們認為這項提案的效率提升效果不值得實施,可以保留現有的線路格式。

先前 RFC 遭拒,並且現在提出核准的論點

這項 RFC 先前曾遭拒,原因如下 (請在此處查看逐字複製的內容),之後才重新提交審查:

這項 RFC 最初於 2019 年 2 月 21 日獲得初步接受。FIDL 團隊在 2019 年大部分時間內致力於穩定線路格式,並在第三季和第四季全力投入相關工作。遷移作業已於 2019 年 12 月 1 日完成。

穩定性改善工作涵蓋了多項變更:

不過,隨著工作進展,且 12 月 1 日的期限將至,FIDL 團隊決定暫緩實施高效信封變更,並將這項工作推遲到 2020 年。與其他變更不同,這些變更是穩定性努力的一部分,而效率高的封套只是記憶體內的大小節省,而且非常小,尤其是與 Fidl 電報格式的其他部分 (例如 tables' dense format) 相比。延後是專案風險降低計算的結果,藉由縮小範圍,可提高按時完成所有工作的機率。這也是 FIDL 團隊的工作時間表。

延後 18 個月後,我們已經快要忘記高效信封了。2020 年有重大的效能改善,這項異動不會對我們造成重大影響。

是時候面對現實了,這不會發生。已遭拒。

Why re-approve now?

FIDL 團隊目前正打算將多項線路格式變更合併為一批,並一次進行所有變更的遷移作業。這表示您有機會以較低成本的方式,為高效率信封新增支援功能 (因為成本會與其他遷移作業共用)。

此外,現在也有效率信封帶來的成效提升具體數據,而且成效提升幅度相當顯著。

基於這些因素,現在是復活這項 RFC 並加以實作的絕佳時機。

既有技術與參考資料

這個 RFC 是 rfc-0026 的簡化版本,由於整個 RFC 並未獲得足夠的共識,因此遭到拒絕。


  1. 此 RFC 是以 rfc-0026 為基礎,但採用離線信封提案。內嵌、隨處放置信封,以及將字串/向量計數器移出行外,都已移除。