RFC-0151:針對 CPU 指定的編譯器調整標記 | |
---|---|
狀態 | 已接受 |
區域 |
|
說明 | 建議變更控管 CPU 指定目標的編譯器旗標,以及這些變更對平台和 SDK 建構作業的影響。 |
問題 | |
Gerrit 變更 | |
作者 | |
審查人員 | |
提交日期 (年-月-日) | 2022-01-04 |
審查日期 (年-月-日) | 2022-02-02 |
摘要
建議變更控管 CPU 指定目標的編譯器旗標,以及這些變更對平台和 SDK 建構作業的影響。
提振精神
Fuchsia 的建構作業會產生許多構件,這些構件包含不同架構的可執行機器碼。舉例來說,預先建構的共用程式庫,可供 SDK 使用發布,或是平台和產品系統映像檔中包含的可執行 C/C++ 或 Rust 二進位檔。在編譯器中產生機器碼時,請務必指出下列事項:
目標架構:要使用哪種指令集架構?例如 x86-64 或 AArch64 ISA。此外,編譯器可能會指定 ISA 修訂版本。修訂版可能會提供額外指令或現有指令的變化版本,例如新的浮點或 SIMD 指令,或是更廣泛的原子記憶體作業,這些指令可大幅提升效能。您必須瞭解目標架構,才能產生可確保在指定裝置上運作的程式碼。升級目標架構可使用新功能,但會犧牲與舊硬體的回溯相容性。
以上:ARM 指令集的演進歷程 (來源)
目標微型架構:如何實作 ISA?這通常會以指令是否依序執行或非順序執行、解碼頻寬、快取載入延遲等方式表示。指定目標微架構可讓編譯器產生機器碼,在指定硬體上執行速度更快,且不會限制硬體相容性。
上圖:Intel Core 2 微架構模組圖(來源)
編譯器可讓使用者以我們稍後會審查的方式指定這些目標。Fuchsia 的建構系統可針對全域或個別二進位檔設定編譯器。Fuchsia 版本中現有的 CPU 指定目標實作方式有幾項缺點,本 RFC 旨在解決這些問題:
選擇 arm64 的基準設定時,請指定特定 CPU (Cortex-A53),而非 ISA 和使用的功能。這會導致平台基準定義不佳。
由於缺乏先前藝術作品,也沒有政策或最佳做法文件,因此無法確定如何為此基準值設定覆寫值。因此,Fuchsia 建構作業會盡可能採用基準,包括以明確超出基準的硬體為目標的建構設定。
這些缺點自 2016 年建構作業開始以來就存在,而在此之前,這些缺點也存在於 Fuchsia 演變自先前技術的情況。目前的系統是在第一個裝置上推出 Fuchsia (該裝置恰好使用與現今平台 arm64 基準相同的微型架構)。
近期的發展顯示,現在是時候進行全面檢查了。具體來說,除了鎖定 Cortex-A53 的 Astro 和 Sherlock 板設定外,Fuchsia 現已支援 Nelson 板設定 (Cortex-A55) 和 Atlas 板設定 (Intel Amber Lake)。不過,這些版本目前並未設定為利用基準和實際目標之間的差異。
此外,越來越多人希望能進一步細化平台硬體基準的定義,或提高基準。更清楚定義基準設定和特定主機板設定,有助於加快相關工作。另請參閱:
為因應現在和未來的挑戰,此 RFC 建議在版本中對 CPU 指定目標進行即時變更,以及在可預見的未來管理指定目標的機制和政策。
相關人員
協助人員: cpu@google.com
審查者:
aaronwood@google.com
- 系統組合digit@google.com
- 建構mcgrathr@google.com
- 核心mvanotti@google.com
- 安全性maniscalco@google.com
- 核心phosek@google.com
- 工具鍊travisg@google.com
- 核心
諮詢:
由於提議的變更會影響大部分平台,因此我們鼓勵所有相關方自行任命諮詢對象。我特別歡迎來自圖形、媒體和 SDK 等團隊的意見回饋。
社會化:
這項提案的重點最初是在 Fuchsia 的 Kernel Evolution Working Group 中,以 60 分鐘的簡報和公開討論的形式進行審查。
背景
編譯時間調整旗標
Fuchsia 會使用 clang 編譯 C/C++,其中部分 Fuchsia 程式碼也會持續使用 gcc 進行建構和測試。這兩種工具都提供下列標記:
-march
:設定目標架構,例如 x86-64-v2
(根據 RFC-0073 的現行 x64 基準) 或 ARMv8-A。您也可以選擇指定其他架構功能,例如 +avx2
,用於指示比 x64 基準更進階的 Intel Haswell 擴充功能。
-mtune
:設定目標微架構,例如 cortex-a53
或 haswell
。如果未使用 -mtune
或 -mcpu
,則會將這個值設為 generic
,以便在一系列指定 CPU 中達到平衡。
-mcpu
:設定目標 CPU。可接受與 -mtune
類似的值。對於 ARM CPU,這相當於將目標架構 (-march
) 和目標微架構 (-mtune
) 設為與目標 CPU 相符。在 x86 上,這會視為已淘汰,且指定的值會重新導向至 -mtune
。
Rust 編譯器提供以下 codegen 選項:
target-cpu
:與 -mcpu
類似,可接受 cortex-a53
等例項。
target-features
:類似 -march
功能,例如 +avx2
。
目前狀態
目前所有 x64 版本都是使用 -march=x86-64-v2
編譯,而所有 ARM 版本則是使用 -mcpu=cortex-a53
編譯。
透過名為 board_configs
的 GN 引數,可透過機制覆寫這項設定,而這項設定可由 .gni
檔案中的板卡設定覆寫。某些電路板 (特別是 Astro 和 Sherlock) 會手動指定上述的 Cortex-A53 設定,但這目前是無操作,因為如果未定義覆寫值,同樣的設定也會用於備用。大多數的板卡設定都不會設定 board_configs
。
調整目標和權衡
本節將簡要介紹設定 CPU 指定目標選項時應考量的不同目標,以及這些目標之間的部分取捨。
硬體相容性:指定較早版本的 ISA,即可與舊版硬體相容。雖然相容性會提升,但您將無法使用可帶來效能或安全性優勢的新 ISA 功能。
效能:新指令可提升效能:更快或更廣泛的原子運算、加速運算 (FPU、SIMD 改善),以及常用演算法 (例如 CRC 和 AES) 的內建加速器。針對特定 CPU 調整機器碼,可產生在目標 CPU 上執行速度更快的程式碼,但通常會犧牲目標參數以外的其他 CPU 效能。
與二進位大小的互動:在某些情況下,我們發現調整會增加二進位大小,例如,當以順序處理器為目標的指令排程最佳化作業增加了註冊壓力時。
二進位檔大小:部分 codegen 功能會在特定 CPU 功能啟用後解鎖。舉例來說,SIMD 會啟用自動向量化功能,這項功能的效果與循環展開相似,會產生速度更快但體積更大的程式碼。針對順序 CPU 調整的指令排程作業,通常會產生較大的程式碼,因為它會增加更多排程限制,並可能增加暫存器壓力和暫存器溢位。
其他 codegen 功能可以縮減二進位檔大小。舉例來說,將 CRC 和 AES 等演算法替換為專用指令,就能產生速度更快且體積更小的程式碼。
輕鬆排解疑難,例如二進位元多樣性:針對不同 CPU 進行調整,意味著隨著時間的推移,同一個邏輯構件會產生更多二進位元變化版本。舉例來說,可提供多個「變種」的核心映像檔或預先建構的共用程式庫,每個都針對不同的目標進行最佳化。這可能會使重現問題變得更複雜,或讓 Fuchsia 暴露於某些二進位變數中出現的問題,而非其他變數。
公平競爭環境:除了基準版本之外,Fuchsia 可能會提供針對特定 CPU 調整的 SDK 預先建構 (系統映像檔、可重新發布的共用程式庫)。這樣做可讓部分硬體選項享有較少的權限。我們可以合理地假設,建立針對某些 CPU 調整的 SDK 版本,將可在日後提供更多經過調整的 SDK 發布管道。
簡單:上述所有內容都會增加瞭解 Fuchsia、在 Fuchsia 上開發,以及維護 Fuchsia 的複雜度。上述權衡是為了設定 CPU 指定選項,在可行情況下,針對特定硬體 (例如針對特定使用者硬體的 OTA 管道指定 OTA 管道的建構和發布管道) 推出二進位元多樣性。在撰寫本文時,系統或套件提交機制並未提供多個二進位檔,以便將正確的二進位檔與正確的裝置配對,以便將多個二進位檔提供給不同的目標硬體。
提案
您可以參閱這項變更,瞭解立即建議的修改內容。請參閱下方其他說明。
新的 arm64 基準硬體目標
arm64 目前的基準定義為鎖定 Cortex-A53,如下所示:
-mcpu=cortex-a53
從技術層面來說,這等同於根據精確的 Cortex-A53 功能集來表示 -march
,並為 Cortex-A53 調整 codegen。
-march=<armv8a + Cortex-A53 features>
-mtune=cortex-a53
相反地,基準會表示平台實際執行的 ARMv8-A ISA 功能,因此會視為基準,然後為通用 armv8a CPU 調整程式碼產生作業。
-march=armv8-a+simd+crc+crypto
-mtune=generic
對 -march
的影響實際上是無操作,因為移除 Cortex-A53 支援但程式碼未執行的 -march
功能是無操作。
對 -mtune
的影響微乎其微,甚至沒有影響,因為一般調校目標會針對傳統的順序 ARMv8-A CPU (例如 Cortex-A53) 進行最佳化。
現有 x64 基準硬體目標的變更
x64 目前的基準如下:
-march=x86-64-v2
這個主題先前已在上述 RFC-0073:將 x86-64 平台需求提高至 x86-64-v2 中討論過。
這會變更為下列標記集:
-march=x86-64-v2
-mtune=generic
這並非行為變更,因為如前文所述,如果未指定 -mtune
或 -mcpu
,-mtune
預設為 generic
。不過,新增 -mtune=generic
可讓這項行為明確化,並與 arm64 基準的定義一致。
板卡專屬設定
在特定板卡 .gni
檔案 (例如 //boards/
中找到的檔案) 中指定的 board_configs
板卡引數,將繼續用於使用板卡專屬設定覆寫基準設定。
具體來說,使用 Cortex-A53 的主機板設定 (例如 astro.gni
和 sherlock.gni
) 將繼續鎖定 Cortex-A53,並保留目前的 -mcpu=cortex-a53
設定。
本質上,此 RFC 會採用以 Cortex-A53 為目標的現有 arm64 設定,並將其從平台基準值擷取至板卡專屬設定,適用於搭載此類 CPU 的 Astro 和 Sherlock 板卡。接著,本 RFC 會以 ARM ISA 術語重新定義平台基準,以便將其推廣至許多硬體選項,而非單一 ARM CPU。
此外,在 SDK 的未來版本中,您也可以新增針對不同架構變化版本 (例如 ARM Cortex-A73 或 Intel AVX 擴充功能) 的最佳化支援功能。這項議題值得進一步討論,但超出本議題的範圍。
核心設定
board_configs
引數將不再套用至核心映像檔。原因如下:
需要在 codegen 時瞭解的新指令或其他 CPU 功能,目前不會為核心提供任何好處。
以微型架構為基礎調整核心程式碼,並不會帶來任何好處,反而會增加二進位程式多樣性和複雜度。
核心可以繼續提供支援的硬體功能相關資訊,例如使用 zx_system_get_features
系統呼叫。
此外,核心仍可利用一些較新的硬體功能,例如 64kB 記憶體頁面,這類功能不需要產生不同的程式碼,只需在執行階段查詢這些功能是否存在即可。如果這類新功能需要板卡專屬設定,那麼您可以輕鬆導入新的引數 kernel_board_configs
,藉此定義相關聯的旗標。
回溯相容性
這份 RFC 中提出的立即變更不會提高 Fuchsia 的最低硬體需求,因此不會影響回溯相容性。日後若有變更將提高最低要求,這項 RFC 建議的政策可能會有所助益。
安全性考量
Fuchsia 使用或打算使用多項 CPU 功能,以提升安全性或支援使用消毒劑 (進而提升安全性)。這些通常不會受到本文討論的編譯器旗標控制,因此不必擔心。
特別注意:
- Userspace Top-Byte-Ignore (請參閱 RFC-0143) 在 AArch64 中普遍支援。
- 可改善消毒劑支援功能 (例如 ARM MTE) 或確保控制流程完整性 (例如 指標驗證和分支目標識別或 Intel 控制流程強制執行技術) 的新指令會位於 NOP 空間,因此可回溯相容 (意即舊版 CPU 會將其視為 NOP 執行)。因此,使用這些操作說明時,不需要提高平台或 SDK 版本的最低支援 ISA。
測試
正確性:CPU 指定目標的變更不得影響正確性。我們會透過持續提交前和提交後測試來驗證這項資訊。現有系統已足以確保這一點。
效能:CPU 指定目標的變更通常會影響效能。如同先前的做法,Fuchsia 的 Perfcompare 系統會用於驗證任何這類變更。
二進位檔大小:CPU 指定目標的變更通常會對二進位檔大小造成微妙的影響。具體來說,Fuchsia 目前會密切追蹤 Astro 圖片的大小,因為這是我們最受限制的目標。立即變更不會導致這個大小下降。未來若有影響特定產品圖片的異動,這些產品定義的擁有者可以審查並仔細考量取捨。
缺點、替代方案和未知事項
在有時會發生衝突的目標中,CPU 指定目標會提供許多工程和業務權衡。如上所述,日後的變更會改變這些權衡,而日後的調整機會和考量因素則不在本 RFC 的範圍內。