RFC-0113:高效信封 | |
---|---|
状态 | 已接受 |
领域 |
|
说明 | 此 FTP 为信封提出了一种更紧凑的编码。 |
Gerrit 更改 | |
作者 |
|
审核人 |
|
提交日期(年-月-日) | 2021-06-21 |
审核日期(年-月-日) | 2021-07-21 |
“将信封变成明信片”
总结
此 RFC 针对 FIDL1 提出了一种更紧凑的编码方式。
设计初衷
信封是可扩展、可演进的数据结构(表和可扩展的联合)的基础。针对信封采用更紧凑高效的电线格式使得这些可扩展的结构能被用于更多对性能和电线尺寸至关重要的情境。
设计
提议的信封格式可描述为以下 C 结构体:
struct Envelope {
uint32_t byte_size;
uint32_t handle_count;
};
与现有的信封格式相比:
- 字节大小字段保持不变(32 位)。
- 大小包括可能以递归方式编码的任何子对象的大小。
- 例如,
vector<string>
的大小包括外部矢量的内部字符串子对象的大小。 - 这与当前信包实现的大小字段的现有行为一致。
- 句柄计数字段保持不变(32 位)。
- process_count 包括所有递归子对象的句柄计数。
- 在线/缺失字段会被丢弃。
- 存在状态由 size 或 handle_count 字段中的非零值表示。
- 缺失表示大小和句柄计数字段都为零。
- 我们称之为零信封。
- 零包封等同于
FIDL_ALLOC_ABSENT
。
- 验证字节大小字段
- 必须验证字节大小字段是否为 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 中运行,可对高效的信封实现进行原型设计。在此测试中,输入是一个设置了所有字段的表。其他输入产生了类似的结果。
以下时间以纳秒为单位。使用高效包的时间在箭头之前,使用高效包的时间在箭头之后。
# 字段 | 编码 | 解码 |
---|---|---|
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 之前已因以下理由被拒绝(已逐字复制),并重新提交以供审核:
2019 年 2 月 21 日,我们最初接受了此 RFC。FIDL 团队努力在 2019 年的大部分时间里稳定了传输格式,最终在第三季度和第四季度全心全意投入工作。迁移已于 2019 年 12 月 1 日完成。
稳定工作涉及多项变更:
不过,随着工作的展开,并且 12 月 1 截止日期即将来临,FIDL 团队决定放弃实施高效信封变更,并希望将这项工作推到 2020 年。与稳定工作中的其他变更不同,高效的信封只是在内存中节省大小,而且体量非常小,尤其是与 FIDL 有线格式的其他方面(例如表的密集格式)相比。推迟是一种降低项目风险的计算方法,通过缩小范围,可以提高按时完成所有工作的几率。FIDL 小组的工作时间表也一样
现在,推迟实施已接近 18 个月,高效的信封早就被遗忘了。2020 年的大量性能工作表明,这一变更不会产生实质性影响。
是时候直面真相了,事情不会发生。已拒绝。
为何要立即重新审批?
FIDL 团队目前计划批量处理多项传输格式变更,然后一次性迁移所有这些变更。这意味着有机会以更低的成本(与其他迁移共担费用)来增加对高效信封的支持。
此外,由于采用高效的信封,性能提升非常明显。
由于这些因素,现在正是恢复并实现此 RFC 的好时机。
早期技术和参考资料
此 RFC 是 rfc-0026 的精简版本,由于整个 RFC 没有足够的共识,它已被拒绝。