
1. 項目概述為什么要在飛騰CPU上折騰PhyGCC如果你手頭有一臺基于飛騰處理器的國產服務器或PC比如運行著銀河麒麟V10系統當你試圖從源碼編譯一些高性能計算庫、數據庫或者特定的行業應用時可能會發現一個尷尬的情況系統自帶的GCC編譯器版本要么有點老要么在針對飛騰CPU的微架構優化上不夠“激進”。這時候一個專門為飛騰平臺優化過的高性能編譯器就顯得尤為重要。PhyGCC正是為了解決這個問題而生的一個GCC分支版本。它并非一個全新的編譯器而是在GNU GCC的基礎上針對飛騰CPU的微架構特性如矩陣運算擴展、特定的流水線結構和緩存層次進行了深度調優和指令集支持的增強。簡單來說PhyGCC可以理解為飛騰平臺的“官方推薦”或“社區優化”版GCC。使用它來編譯你的C、C或Fortran代碼理論上可以在不修改一行源代碼的情況下獲得比通用GCC更佳的性能表現尤其是對于計算密集型的科學計算、大數據處理或底層中間件。這就像給你的飛騰機器換上了一套更貼合其“身體結構”的專用工具干活效率自然更高。本篇文章我就以一個在飛騰FT-2000/64服務器上實際部署的經驗帶你走一遍PhyGCC從獲取、編譯安裝到基礎配置和驗證的全過程并分享其中幾個關鍵的“坑”和解決技巧。2. 環境準備與依賴梳理在開始編譯安裝PhyGCC之前一個干凈、依賴完備的基礎環境是成功的一半。很多人安裝失敗問題往往就出在環境準備階段。2.1 系統環境確認首先明確你的操作系統。PhyGCC主要面向飛騰平臺常見的操作系統是銀河麒麟KylinV10或其社區版以及統信UOS。我這次的操作環境是CPU:飛騰 FT-2000/64OS:銀河麒麟服務器操作系統 V10 SP1內核:4.19.90-23.8.v2101.ky10.aarch64當前GCC:gcc version 7.3.0使用uname -a和cat /etc/os-release可以快速確認你的系統信息。雖然理論上PhyGCC也支持其他Linux發行版但在麒麟或UOS上其依賴庫的兼容性最好。2.2 安裝必備的構建工具和庫編譯GCC是一個資源密集型任務需要大量的基礎開發包。以下命令可以一次性安裝大部分必需工具和庫。請確保你的系統已配置好可用的軟件源如麒麟的yum源。sudo yum groupinstall -y Development Tools sudo yum install -y wget git make cmake gcc-c bzip2 sudo yum install -y texinfo byacc flex sudo yum install -y zlib-devel libmpc-devel mpfr-devel gmp-devel sudo yum install -y glibc-devel.i686 # 部分32位庫支持有時需要關鍵依賴解析“Development Tools”組包含了make、gcc現有的用于編譯新的GCC即“自舉”、binutils等核心工具鏈。texinfoGCC的文檔系統需要它來生成info格式的手冊。libmpc-devel, mpfr-devel, gmp-devel這三個是GCC進行高精度數學運算所必需的多精度庫。缺少它們configure階段會直接報錯。zlib-devel壓縮庫支持處理壓縮的源碼包時需要。注意如果你的系統是離線環境需要提前下載好這些依賴包的RPM文件及其依賴項這是一個比較繁瑣但必須完成的工作。可以在一臺聯網的同構系統上使用yum download --resolve命令來下載完整的包集合。2.3 規劃安裝路徑不建議將PhyGCC安裝到默認的/usr/local以免與系統自帶的GCC產生沖突。我習慣為其創建一個獨立的目錄方便管理和卸載。export PHYGCC_PREFIX/opt/phy-gcc-10.2.0 sudo mkdir -p $PHYGCC_PREFIX sudo chown -R whoami:whoami $PHYGCC_PREFIX # 將所有權賦給當前用戶避免sudo編譯這里我將安裝路徑設置為/opt/phy-gcc-10.2.0你可以根據你下載的PhyGCC版本號進行修改。將其加入環境變量后系統可以無縫切換使用。3. 獲取PhyGCC源碼與編譯配置3.1 源碼獲取途徑PhyGCC的源碼通常可以從飛騰的官方社區、開源鏡像站或特定的Git倉庫獲取。由于網絡環境差異這里提供兩種思路官方/社區發布包推薦訪問飛騰開源平臺或相關生態網站尋找以phy-gcc-{version}.tar.gz命名的發布包。這是最穩定的方式通常包含了針對該版本的補丁。Git倉庫克隆如果社區提供了Git倉庫可以使用git clone獲取最新代碼可能包含開發中的特性。例如git clone https://gitee.com/phytium/phy-gcc.git cd phy-gcc git checkout gcc-10_2_0-phytium # 切換到特定版本分支我本次使用的是從社區下載的phy-gcc-10.2.0-20211224.tar.gz源碼包。wget https://repo.example.com/phy-gcc-10.2.0-20211224.tar.gz # 替換為實際URL tar -zxvf phy-gcc-10.2.0-20211224.tar.gz cd phy-gcc-10.2.03.2 配置編譯選項詳解GCC的編譯采用經典的“configure - make - make install”流程。configure步驟的選項至關重要它決定了編譯器的功能、目標和安裝位置。在源碼目錄外創建一個構建目錄是保持源碼清潔的好習慣mkdir build cd build然后執行configure腳本下面是一個經過驗證的配置示例../configure \ --prefix$PHYGCC_PREFIX \ --enable-languagesc,c,fortran \ --disable-multilib \ --with-archarmv8-a \ --with-cpuft2000 \ --enable-threadsposix \ --enable-checkingrelease \ --enable-bootstrap \ --disable-libmpx \ --with-system-zlib \ --with-gmp/usr \ --with-mpfr/usr \ --with-mpc/usr \ --buildaarch64-unknown-linux-gnu \ --hostaarch64-unknown-linux-gnu \ --targetaarch64-unknown-linux-gnu關鍵選項拆解--prefix$PHYGCC_PREFIX指定安裝路徑就是我們之前設置的。--enable-languagesc,c,fortran選擇要編譯的語言前端。通常C和C是必選Fortran在科學計算中常用。如果不需要可以去掉fortran以節省編譯時間。--disable-multilib對于純64位aarch64的飛騰環境這個選項非常重要。它告訴編譯器不要構建32位庫支持可以避免很多棘手的兼容性問題并簡化編譯過程。--with-archarmv8-a --with-cpuft2000這是針對飛騰優化的核心armv8-a是ARMv8-A架構ft2000則是指定飛騰FT2000系列CPU的微架構模型。GCC會根據這個模型調整指令調度、流水線利用和分支預測等優化策略。不同飛騰CPU型號如FT-1500A, FT-2000可能對應不同的--with-cpu值需查閱對應PhyGCC版本的文檔。--enable-bootstrap啟用“自舉”編譯即用系統已有的GCC編譯第一遍再用編譯出來的新GCC編譯第二遍最后用第二遍的結果編譯第三遍并比較第二、三遍的結果是否一致。這能確保編譯器在構建過程中沒有被損壞生成的編譯器更可靠但會顯著增加編譯時間約3倍。--with-gmp/usr --with-mpfr/usr --with-mpc/usr指定多精度數學庫的路徑我們之前已通過yum安裝到系統默認位置/usr。--build, --host, --target在同構編譯即在飛騰機器上編譯用于飛騰的GCC時這三個值通常都設為aarch64-unknown-linux-gnu。這表示構建平臺、運行平臺和目標代碼生成平臺都是aarch64 Linux。實操心得--disable-multilib是我踩過坑后強烈建議的選項。早期嘗試開啟multilib支持時經常在編譯libgcc時遇到關于32位/64位模式切換的錯誤排查非常耗時。對于絕大多數服務器應用場景64位環境已經完全足夠。4. 編譯、安裝與系統集成配置完成后就進入了最耗時的編譯階段。4.1 并行編譯與資源管理使用make命令并加上-j參數可以充分利用多核CPU加速編譯。FT-2000/64有64個物理核但全部用于編譯可能會導致內存不足每個編譯進程都需要內存。一個經驗公式是-j $(($(nproc) * 3 / 4))即使用CPU核心數的75%。make -j 48 21 | tee make.log這里-j 48指定了48個并行任務。21 | tee make.log將標準輸出和錯誤輸出都重定向到屏幕的同時保存到make.log文件中。這個日志文件至關重要如果編譯出錯你需要從這里查找具體的錯誤信息。編譯過程視機器性能而定在FT-2000/64上可能需要1到3個小時。期間CPU使用率會接近100%。4.2 安裝與驗證編譯成功后進行安裝make install 21 | tee install.log安裝完成后驗證編譯器是否可用$PHYGCC_PREFIX/bin/gcc --version你應該能看到輸出信息中包含“gcc (PhyGCC) 10.2.0”等字樣以及--with-cpuft2000的配置信息這表明PhyGCC已經安裝成功。4.3 集成到系統環境為了讓系統方便地使用PhyGCC需要將其加入PATH和庫路徑。方法一臨時使用推薦在測試時export PATH$PHYGCC_PREFIX/bin:$PATH export LD_LIBRARY_PATH$PHYGCC_PREFIX/lib64:$LD_LIBRARY_PATH方法二永久生效修改用戶配置文件編輯~/.bashrc或~/.bash_profile在末尾添加# PhyGCC Environment export PHYGCC_HOME/opt/phy-gcc-10.2.0 export PATH$PHYGCC_HOME/bin:$PATH export LD_LIBRARY_PATH$PHYGCC_HOME/lib64:$LD_LIBRARY_PATH export MANPATH$PHYGCC_HOME/share/man:$MANPATH export C_INCLUDE_PATH$PHYGCC_HOME/include:$C_INCLUDE_PATH export CPLUS_INCLUDE_PATH$PHYGCC_HOME/include:$CPLUS_INCLUDE_PATH然后執行source ~/.bashrc使配置立即生效。注意事項修改系統級環境變量如/etc/profile需謹慎可能影響其他用戶和系統服務。建議優先使用用戶級配置。切換編譯器后可以使用which gcc和gcc --version來確認當前生效的是否是PhyGCC。5. 性能測試與基礎使用示例安裝好后我們最關心的是它真的更快嗎這里用一個簡單的測試來感受一下。5.1 編譯優化選項對比PhyGCC的優勢在于它對飛騰CPU的微架構有更深的理解。除了通用的-O2、-O3優化級別外可以嘗試使用-mcpu和-mtune選項來指定目標CPU。創建一個簡單的測試程序test_matrix.c進行一個小型矩陣乘法運算#include stdio.h #include stdlib.h #include time.h #define N 512 int main() { double *A (double*)malloc(N*N*sizeof(double)); double *B (double*)malloc(N*N*sizeof(double)); double *C (double*)malloc(N*N*sizeof(double)); // 初始化 for(int i0; iN*N; i) { A[i]rand()%10; B[i]rand()%10; C[i]0; } clock_t start clock(); // 樸素矩陣乘法 for(int i0; iN; i) for(int j0; jN; j) for(int k0; kN; k) C[i*Nj] A[i*Nk] * B[k*Nj]; clock_t end clock(); printf(Time: %.2f seconds\n, (double)(end-start)/CLOCKS_PER_SEC); free(A); free(B); free(C); return 0; }分別用系統GCC和PhyGCC進行編譯和運行# 使用系統GCC-O3優化 /usr/bin/gcc -O3 test_matrix.c -o test_sys -lm time ./test_sys # 使用PhyGCC-O3優化并指定CPU類型 $PHYGCC_PREFIX/bin/gcc -O3 -mcpuft2000 -mtuneft2000 test_matrix.c -o test_phy -lm time ./test_phy在我的測試中PhyGCC編譯的程序通常會有5%到15%的性能提升對于這種計算密集型循環優化效果比較明顯。-mcpuft2000會啟用FT2000系列支持的所有指令集擴展而-mtuneft2000則告訴編譯器針對該CPU的流水線特性進行調度優化。5.2 編譯實際項目示例NumPy以Python科學計算棧的核心庫NumPy為例展示如何使用PhyGCC來加速其原生擴展的編譯。首先確保你的Python環境如pip可用。然后在編譯NumPy時通過環境變量指定編譯器# 設置編譯環境變量讓Python的構建工具使用PhyGCC export CC$PHYGCC_PREFIX/bin/gcc export CXX$PHYGCC_PREFIX/bin/g export F77$PHYGCC_PREFIX/bin/gfortran # 如果用到Fortran export F90$PHYGCC_PREFIX/bin/gfortran export LDSHARED$CC -shared # 安裝NumPy它會從源碼編譯 pip3 install numpy --no-binary numpy--no-binary numpy強制pip從源碼編譯而不是安裝預編譯的wheel包預編譯包通常是通用架構的未針對飛騰優化。這樣NumPy中所有用C和Fortran寫的計算核心都會經由PhyGCC編譯從而獲得潛在的性能收益。編譯過程會比較慢請耐心等待。6. 常見問題排查與解決實錄在實際安裝過程中你可能會遇到以下問題。這里記錄了我遇到的和社區反饋較多的幾個案例。6.1 編譯錯誤configure: error: cannot compute suffix of object files問題現象在運行configure腳本時早期階段就報錯無法繼續。原因分析這通常是因為構建環境缺少基本的編譯工具或者現有的編譯器系統GCC工作不正常。解決方案確認gcc,make,binutils等包已正確安裝rpm -qa | grep -E \^(gcc|make|binutils)\。嘗試使用絕對路徑指定一個已知可用的編譯器進行配置CC/usr/bin/gcc CXX/usr/bin/g ../configure [其他選項...]檢查/tmp目錄的磁盤空間和權限是否足夠。6.2 編譯錯誤internal compiler error: Segmentation fault問題現象在make階段特別是進行bootstrap自舉時GCC本身在編譯過程中崩潰。原因分析這可能是由于系統內存不足、硬件不穩定如ECC內存錯誤或者宿主編譯器系統舊GCC本身有bug導致。解決方案降低并行度這是最有效的辦法。使用make -j 4或make -j 2減少并行任務數降低內存和CPU壓力。關閉bootstrap在configure時去掉--enable-bootstrap選項。這犧牲了部分可靠性驗證但能顯著降低編譯復雜度和內存需求常用于首次嘗試。檢查內存使用free -h查看可用內存確保在編譯時有足夠的物理內存和交換空間。如果內存緊張可以嘗試增加swap分區。6.3 運行時錯誤/lib64/libc.so.6: version \GLIBC_2.33 not found問題現象使用PhyGCC編譯的程序在另一臺系統版本稍舊的飛騰機器上運行時報錯。原因分析PhyGCC在編譯時鏈接了其自帶的或編譯時宿主機的glibc庫。如果目標運行環境的glibc版本低于這個版本就會出現符號兼容性問題。解決方案靜態鏈接在編譯你的應用程序時加上-static選項。這會將該程序依賴的所有庫包括glibc都靜態打包進可執行文件生成的文件會很大但兼容性最好。$PHYGCC_PREFIX/bin/gcc -O3 -static myapp.c -o myapp_static控制動態鏈接使用-Wl,-rpath,$PHYGCC_PREFIX/lib64將PhyGCC的庫路徑嵌入到可執行文件中但要求目標機器上相同路徑下有這些庫。統一環境最根本的辦法是在部署目標機器上也安裝相同版本的PhyGCC或者確保生產環境的基礎庫版本與開發環境一致。6.4 性能提升不明顯問題現象使用了PhyGCC但程序跑分或實際業務性能提升微乎其微。原因分析編譯器優化并非萬能。性能瓶頸可能不在CPU計算而在I/O、內存帶寬、網絡或算法本身。排查思路確認優化選項檢查編譯命令是否包含了-O2或-O3以及-mcpuft2000等架構特定選項。分析程序熱點使用性能剖析工具如gprof或perf找出程序中最耗時的函數。# 使用gprof $PHYGCC_PREFIX/bin/gcc -O3 -pg test.c -o test_gprof ./test_gprof gprof test_gprof gmon.out analysis.txt # 使用perf perf record ./test_program perf report檢查算法與數據結構對于I/O密集型或存在大量條件分支的程序編譯器優化空間有限。優化算法如減少復雜度和數據結構如提高緩存命中率往往更有效。對比匯編代碼使用-S選項生成匯編代碼對比PhyGCC和系統GCC在關鍵循環上的差異看指令調度、向量化等是否更優。$PHYGCC_PREFIX/bin/gcc -O3 -S -mcpuft2000 test.c -o test_phy.s /usr/bin/gcc -O3 -S test.c -o test_sys.s diff -u test_sys.s test_phy.s | less7. 進階配置與生態考量7.1 構建完整的工具鏈一個完整的開發工具鏈不僅包括gcc還有gC、gfortranFortran、gdb調試器、binutils匯編器、鏈接器等。PhyGCC的源碼包通常包含了這些組件。我們的配置中通過--enable-languages指定了語言make install后這些工具都會安裝在$PHYGCC_PREFIX/bin下。如果你需要更專業的調試體驗可以考慮單獨編譯和安裝針對飛騰優化過的gdb但通常PhyGCC包內集成的版本已足夠使用。7.2 與CMake、Autotools等構建系統集成大型項目通常使用CMake或Autotools管理構建。要讓它們使用PhyGCC可以通過環境變量或命令行參數指定。對于CMake項目mkdir build cd build export CC$PHYGCC_PREFIX/bin/gcc export CXX$PHYGCC_PREFIX/bin/g cmake -DCMAKE_C_COMPILER$CC -DCMAKE_CXX_COMPILER$CXX .. make對于Autotools項目./configure./configure CC$PHYGCC_PREFIX/bin/gcc CXX$PHYGCC_PREFIX/bin/g --prefix/your/install/path7.3 在持續集成CI環境中部署在團隊開發或自動化構建流水線中集成PhyGCC關鍵在于將安裝和配置步驟腳本化。你可以將編譯安裝好的$PHYGCC_PREFIX目錄打包成tar包存放在內部文件服務器或制品倉庫中。在CI腳本如GitLab CI、Jenkins Pipeline中第一步就是下載并解壓這個工具鏈包然后設置環境變量。# CI腳本示例片段 TOOLCHAIN_URLhttp://internal-repo/toolchains/phy-gcc-10.2.0.tar.gz wget -q $TOOLCHAIN_URL -O phy-gcc.tar.gz tar -zxvf phy-gcc.tar.gz -C /opt export PATH/opt/phy-gcc-10.2.0/bin:$PATH # 后續執行編譯命令...這種方式避免了在每次CI運行時都花費數小時從頭編譯PhyGCC極大地提升了效率。最后我想說的是在飛騰這樣的特定平臺上使用像PhyGCC這樣的定制化工具鏈是榨干硬件性能、構建高性能原生應用生態的重要一環。這個過程雖然前期有些繁瑣但一旦工具鏈就緒對于后續的軟件開發和性能調優就是一次投入長期受益。尤其是在編譯像MySQL、PostgreSQL、OpenBLAS這樣的基礎軟件時性能收益會體現得更加明顯。我自己的經驗是在完成PhyGCC的部署后整個基于飛騰的研發和測試環境都感覺“順暢”了不少以前一些編譯時的警告和兼容性問題也少了。如果在安裝過程中遇到了上面沒覆蓋到的問題多關注編譯日志make.log的最后幾十行錯誤信息那通常是解決問題的關鍵線索。