RFC-0114:內嵌於 FIDL 信封中的小值 | |
---|---|
狀態 | 已接受 |
區域 |
|
說明 | 這個 RFC 建議變更 FIDL 線路格式,將 <= 4 個位元組的值內嵌在信封內文中。 |
變更 | |
作者 | |
審查人員 | |
提交日期 (年/月) | 2021-06-24 |
審查日期 (年/月) | 2021-07-21 |
摘要
這個 RFC 提議採用 FIDL 傳輸格式變更,將 <= 4 個位元組的值內嵌在信封主體中。
提振精神
這項變更的原因是改善 FIDL 資料表和聯集 (即目前使用信封的版面配置) 的效能。
FIDL 聯集和資料表使用稱為信封的非行外物件共用表示法。外線指標是編碼和解碼的已知負擔來源。小型物件可以內嵌在信封本身中,無需擔心外列的負擔。
此外,在某些情況下,也可以減少分配金額。您可以直接將物件儲存在信封中,不必為物件分配出外線位置,並將其從信封指向該位置。
設計
這個 RFC 設計假設 RFC-0113 已獲核准,防護效率高的信封。
以下類型將採用新的內嵌值格式:
- 布林值
- 浮點值 32
- uint8、uint16、uint32
- int8、int16、int32
- 版面配置為 uint8、uint16、uint32、int8、int16、int32 的列舉
- 位元 s with layout uint8、uint16、uint32、int8、int16、int32
- 控制代碼、client_end、server_end
- struct 小於 4 個位元組
- 陣列大小小於 4 個位元組
如果日後新增的值類型小於 4 個位元組,則除非另有說明,否則這些新類型的值也會使用內嵌值格式。
新格式可透過 C-struct 表示法描述:
// An envelope corresponds to a union value or an entry in a table.
struct Envelope {
union {
// Inlined values have the same envelope structure for both wire and
// decoded formats.
InlinedValueEnvelope inlined_value_envelope;
// Out-of-line values have a different structure on the wire and in
// decoded format.
union OutOfLineEnvelope {
// Wire representation.
OutOfLineWireEnvelope out_of_line_wire_envelope;
// Decoded representation.
void* decoded_data;
};
};
};
struct InlinedValueEnvelope {
// A <= 4-byte value stored little-endian and 0-padded up to 4-bytes.
uint8_t value[4];
// Number of handles within the envelope.
uint16_t num_handles;
// Bit 0 of flags is 1 to indicate the inline representation is used and
// the envelope is present.
uint16_t flags;
};
struct OutOfLineWireEnvelope {
// Number of bytes recursively within the envelope.
uint32_t num_bytes;
// Number of handles recursively within the envelope.
uint16_t num_handles;
// Bit 0 of flags is 0 to indicate the out-of-line representation is used.
uint16_t flags;
}
InlinedValueEnvelope
和 OutOfLineWireEnvelope
的線形表示法都有重疊的 flags
欄位。flags
中的 LSB 會指出是否使用內嵌表單:1
代表內嵌表單,0
代表非行。所有未使用的標記位元都必須為 0
。
FIDL 中只有單一標準資料表示法。 存在大小最多 4 個位元組的值,且值超過 4 個位元組的值「必須」使用外行表示法。收到錯誤表示法的值「必須」觸發解碼錯誤。缺少的信封會繼續使用零信封表示法,也就是說,它們一律會以外框表示。
實作
這項變更需要複雜的遷移作業。不過,這項遷移可搭配其他傳輸格式遷移作業,大幅降低實務成本。
效能
內嵌欄位時,LLPP 的編碼時間會大幅縮短 (CL):
設定所有欄位的編碼時間 (以奈秒為單位):
# 個欄位 | 使用前 | 使用後 |
---|---|---|
1 | 178 奈秒 | 147 奈秒 |
16 | 720 奈秒 | 325 奈秒 |
256 | 9396 奈秒 | 2909 奈秒 |
這張圖表顯示的編碼時間取決於資料表所含欄位數量的函式。表格中所有欄位皆已設定。
先前未測量解碼時間,但由於解碼演算法遵循與編碼類似的一系列步驟,因此也會大幅改善。
此外,在某些情況下,繫結可以避免為小型值進行配置,進一步提升效能。
人體工學
這個 RFC 允許繫結避免進行小數值配置,但不規定必須進行配置。如果繫結變更,用於處理這些類型的 API 最終可能會與處理需要分配的其他類型 API 有所不同。這種不一致可能會導致人體工學降低,因此必須謹慎行事以避免這種情況。
回溯相容性
這項變更所需的遷移程序會破壞 ABI 相容性。
不過,變更生效後,對類型變更的 ABI 相容性並不會產生任何影響。這項變更前後所有 <= 4 位元組的類型都無法保證 ABI 的 ABI 相容性。
這項變更可能破壞來源相容性。RFC 無須變更原始碼相容性變更,但如果繫結 MAY 改善繫結效能或其他原因,或許會選擇進行來源相容性破壞性變更。
安全性考量
這對安全性沒有影響。
隱私權注意事項
這不會影響隱私權。
測試
系統會使用多種策略來測試變更:
- 每個繫結的自訂單元測試。
- GIDL 合規套件。
- FIDL 相容性測試。
說明文件
傳輸格式說明文件需要更新。
您必須在 API 評分量表中記錄效能的取捨,才能據以做出欄位大小決策。
缺點、替代方案和未知
缺點
這個提案的主要缺點是複雜度提高。現在有兩種值的表示法:內嵌和外行,視類型而定,而切換行為可能有 4 位元組的閾值。
替代方法:8 位元組內嵌值
這個 RFC 建議使用 4 個位元組以下的內嵌值。這是因為至少在實作與高效信封時一併實作時,可能無法內嵌 8 位元組值。
這是因為繫結必須支援未知的信封。不明信封送達時,無法得知類型資訊。因此,這會指出其是否指向外線物件,進而變更解碼器的行為。因此,值本身需要有一些資訊,用來指出它是以內嵌或外行格式進行結構。
如果信封大小為 8 個位元組,且內嵌的值是 8 個位元組,則如果該值是內嵌或外行格式,就不需要儲存任何備用值。
因此,8 位元組的內嵌值與有效率的信封不相容。必須選擇不使用有效率的信封,或縮減可內嵌的值的大小。這個 RFC 選擇了第二種選擇,因為這個方向最有可能改善效能。
先前的圖片和參考資料
RFC-0113 引入有效率的信封,成為此 RFC 中使用的信封結構的基礎。