Go Wiki: AssemblyPolicy
本文件描述了何時以及如何將彙編程式碼新增到 Go 語言的加密庫中。
總的來說,規則如下:
- 我們更傾向於可移植的 Go 程式碼,而不是彙編。彙編程式碼意味著需要維護(N 個庫 * M 種架構)的工作量,而不僅僅是 N 個庫。
- 儘量減少彙編的使用。我們寧願用少量彙編實現 50% 的速度提升,也不願用兩倍的彙編來實現 55% 的速度提升。在提交資訊中解釋將彙編/Go 邊界設定在那裡,並用基準測試支援該決定。
- 使用更高級別的程式來生成非平凡的彙編程式碼,這些程式可以是獨立的 Go 程式,也可以是
go get-able 的程式,例如 avo。其他可重現的程序(如形式化驗證的程式碼生成器)的輸出也將被考慮。提前在問題跟蹤器上討論實現策略。 - 使用稱作“單元”的小型、可測試的程式碼塊(25-75 行),並由用 Go 編寫的高階邏輯呼叫。如果使用由 Go 編寫的邏輯呼叫的、小型、可測試的函式速度太慢,則使用小型、可測試的彙編單元,並配有 Go 相容的包裝器,以便 Go 測試仍然可以測試單個單元。
- 任何彙編函式都需要一個參考的 Go 實現,該實現與彙編程式碼並行測試。遵循 TargetSpecific 的結構和測試實踐。
- 彙編單元和參考 Go 實現的介面必須跨架構相同,除非平臺具有根本不同的能力(例如高階加密指令)。
- 除非 Go 安全團隊明確承諾擁有特定實現的維護權,否則外部貢獻者必須承諾維護它。如果需要更改(例如作為更廣泛重構的一部分),並且維護者不可用,則將刪除該彙編程式碼。
- 程式碼必須在我們 CI 中進行測試。這意味著需要有支援這些指令的構建器,並且如果有多個(或備用)路徑,它們必須分別進行測試。(提示:使用
GODEBUG=cpu.X=off來停用 CPU 功能檢測。) - 在 Go 程式碼中記錄實現為何需要彙編(特定的效能優勢、對指令的訪問等),以便隨著編譯器改進,我們可以重新評估。
並非所有當前在標準庫中的彙編都符合此策略。在現有彙編更新到符合規定之前,將不鼓勵更改。新的彙編必須符合規定。
此內容是 Go Wiki 的一部分。