Go Wiki:AssemblyPolicy
本文档描述了何时以及如何将汇编代码添加到 Go 加密包中。
一般来说,规则如下:
- 我们更喜欢可移植的 Go 代码,而不是汇编代码。使用汇编代码意味着需要维护 (N 个包 * M 种架构),而不是仅仅维护 N 个包。
- 尽量减少汇编代码的使用。我们宁愿为 50% 的加速使用少量汇编代码,也不愿为 55% 的加速使用两倍的汇编代码。在提交消息中解释将汇编/Go 边界放置在当前位置的决定,并用基准测试进行支持。
- 使用更高级别的程序生成大量的汇编代码,无论是独立的 Go 程序还是可以使用
go get
获取的程序,例如 avo。其他可复现流程(例如正式验证的代码生成器)的输出也将被考虑。请提前在问题跟踪器上讨论实施策略。 - 使用由用 Go 编写的更高级别逻辑调用的、小而可测试的单元(25-75 行)。如果使用从用 Go 编写的逻辑调用的、小而可测试的函数速度太慢,则使用具有 Go 兼容包装器的小而可测试的汇编单元,以便 Go 测试仍然可以测试各个单元。
- 任何汇编函数都需要一个参考 Go 实现,该实现与汇编代码并行测试。请遵循 TargetSpecific 中的结构和测试实践。
- 汇编单元和参考 Go 实现的接口必须在所有架构之间相同,除非平台具有根本不同的功能(例如高级加密指令)。
- 除非 Go 安全团队明确承诺拥有特定实现,否则外部贡献者必须承诺维护它。如果需要进行更改(例如作为更广泛重构的一部分)并且维护人员不可用,则将删除汇编代码。
- 代码必须在我们的 CI 中进行测试。这意味着需要支持这些指令的构建器,如果存在多个(或回退)路径,则必须分别对其进行测试。(提示:使用
GODEBUG=cpu.X=off
禁用 CPU 特性检测。) - 在 Go 代码中记录为什么实现需要汇编代码(特定的性能优势、对指令的访问等),以便随着编译器的改进我们可以重新评估。
标准库中目前并非所有汇编代码都符合此策略。在将现有汇编代码更新为符合策略之前,将不鼓励对其进行更改。新的汇编代码必须符合策略。
此内容是 Go Wiki 的一部分。