| 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>的大小包括 外部向量的内部字符串子对象的大小。 - 这与当前信封实现的 size 字段的现有行为一致。
- 句柄计数字段保持不变(32 位)。
- handle_count 包括所有递归子对象的句柄计数。
- 存在/缺失字段已删除。
- 存在由 size 或 handle_count 字段中的非零值表示。
- 缺失由 size 和句柄计数字段均为零表示。
- 我们将其称为“零信封” 。
- 零信封等同于
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 的共识不足而被拒绝。