將 AutoFDO 用於 Linux 核心

這在使用 Clang 編譯器時啟用核心的 AutoFDO 構建支援。 AutoFDO(自動反饋定向最佳化)是一種配置檔案引導最佳化 (PGO),用於增強二進位制可執行檔案的效能。 它使用硬體取樣來收集二進位制檔案中各種程式碼路徑執行頻率的資訊。 然後,此資料用於指導編譯器的最佳化決策,從而產生更高效的二進位制檔案。 AutoFDO 是一種強大的最佳化技術,資料顯示它可以顯著提高核心效能。 它對於受前端停頓影響的工作負載特別有益。

對於 AutoFDO 構建,與非 FDO 構建不同,使用者必須提供配置檔案。 獲取 AutoFDO 配置檔案可以透過多種方式完成。 AutoFDO 配置檔案是透過使用“perf”工具轉換硬體取樣來建立的。 至關重要的是,用於建立這些 perf 檔案的工作負載具有代表性; 它們必須表現出與旨在最佳化的工作負載相似的執行時特性。 否則將導致編譯器針對錯誤的目標進行最佳化。

AutoFDO 配置檔案通常封裝了程式的行為。 如果效能關鍵程式碼與架構無關,則可以將該配置檔案應用於跨平臺,以實現效能提升。 例如,使用在 Intel 架構上生成的配置檔案來構建 AMD 架構的核心也可以產生效能改進。

有兩種方法可以獲取有代表性的配置檔案:(1)使用生產環境中的實際工作負載進行取樣。(2)使用有代表性的負載測試生成配置檔案。 在啟用 AutoFDO 構建配置而不提供 AutoFDO 配置檔案時,編譯器只會修改核心中的 dwarf 資訊,而不會影響執行時效能。 建議使用使用相同的 AutoFDO 配置構建的核心二進位制檔案來收集 perf 配置檔案。 雖然可以使用使用不同選項構建的核心,但可能會導致效能下降。

可以使用先前核心的 AutoFDO 構建來收集配置檔案。 AutoFDO 採用相對行號來匹配配置檔案,從而為原始碼更改提供了一定的容忍度。 此模式通常用於生產環境中進行配置檔案收集。

在基於負載測試的配置檔案收集過程中,AutoFDO 收集過程包括以下步驟

  1. 初始構建:使用 AutoFDO 選項構建核心,但不使用配置檔案。

  2. 分析:然後使用上述核心執行有代表性的工作負載以收集執行頻率資料。 此資料透過 perf 使用硬體取樣來收集。 AutoFDO 在支援高階 PMU 功能(例如 Intel 機器上的 LBR)的平臺上最為有效。

  3. AutoFDO 配置檔案生成:Perf 輸出檔案透過離線工具轉換為 AutoFDO 配置檔案。

該支援需要 Clang 編譯器 LLVM 17 或更高版本。

準備工作

使用以下命令配置核心

CONFIG_AUTOFDO_CLANG=y

定製

預設的 CONFIG_AUTOFDO_CLANG 設定涵蓋 AutoFDO 構建的核心空間物件。 但是,可以透過將類似於以下內容的行新增到相應的核心 Makefile 中來啟用或停用單個檔案和目錄的 AutoFDO 構建

  • 對於啟用單個檔案 (例如 foo.o)

    AUTOFDO_PROFILE_foo.o := y
    
  • 對於啟用一個目錄中的所有檔案

    AUTOFDO_PROFILE := y
    
  • 對於停用一個檔案

    AUTOFDO_PROFILE_foo.o := n
    
  • 對於停用一個目錄中的所有檔案

    AUTOFDO_PROFILE := n
    

工作流程

以下是 AutoFDO 核心的示例工作流程

  1. 在主機上啟用 LLVM 構建核心,例如,

    $ make menuconfig LLVM=1
    

    啟用 AutoFDO 構建配置

    CONFIG_AUTOFDO_CLANG=y
    

    使用啟用 LLVM 的配置,使用以下命令

    $ scripts/config -e AUTOFDO_CLANG
    

    獲得配置後,使用以下命令構建

    $ make LLVM=1
    
  2. 將核心安裝在測試機上。

  3. 執行負載測試。 perf 中的 '-c' 選項指定取樣事件週期。 我們建議為此目的使用合適的素數,例如 500009。

    • 對於 Intel 平臺

      $ perf record -e BR_INST_RETIRED.NEAR_TAKEN:k -a -N -b -c <count> -o <perf_file> -- <loadtest>
      
    • 對於 AMD 平臺

      支援的系統有:帶有 BRS 的 Zen3 或帶有 amd_lbr_v2 的 Zen4。 要檢查,

      對於 Zen3

      $ cat proc/cpuinfo | grep " brs"
      

      對於 Zen4

      $ cat proc/cpuinfo | grep amd_lbr_v2
      

      以下命令生成 perf 資料檔案

      $ perf record --pfm-events RETIRED_TAKEN_BRANCH_INSTRUCTIONS:k -a -N -b -c <count> -o <perf_file> -- <loadtest>
      
  4. (可選) 將原始 perf 檔案下載到主機。

  5. 要生成 AutoFDO 配置檔案,可以使用兩個離線工具:create_llvm_prof 和 llvm_profgen。 create_llvm_prof 工具是 AutoFDO 專案的一部分,可以在 GitHub 上找到 (https://github.com/google/autofdo),版本 v0.30.1 或更高版本。 llvm_profgen 工具包含在 LLVM 編譯器本身中。 重要的是要注意 llvm_profgen 的版本不需要與 Clang 的版本匹配。 它需要是 Clang 的 LLVM 19 版本或更高版本,或者只是來自 LLVM 主幹。

    $ llvm-profgen --kernel --binary=<vmlinux> --perfdata=<perf_file> -o <profile_file>
    

    $ create_llvm_prof --binary=<vmlinux> --profile=<perf_file> --format=extbinary --out=<profile_file>
    

    請注意,可以透過以下方式將多個 AutoFDO 配置檔案合併為一個

    $ llvm-profdata merge -o <profile_file> <profile_1> <profile_2> ... <profile_n>
    
  6. 使用 AutoFDO 配置檔案(使用與步驟 1 相同的配置)重建核心,(注意 CONFIG_AUTOFDO_CLANG 需要啟用)

    $ make LLVM=1 CLANG_AUTOFDO_PROFILE=<profile_file>