# 🚀 MPICH 效能評估與 GCC 升級規劃筆記 ## 🎯 HPC 軟體堆疊相依關係圖: Compiler → MPI → Parallel Libraries(pnetcdf, netcdf-c, hdf5) ```mermaid flowchart LR %% Compiler oneAPI["🧩 oneAPI (icc/ifort)"] GNU["🧩 GNU (gcc/gfortran)"] NV["🧩 NVIDIA HPC (nvc/nvfortran)"] Fujitsu["🧩 Fujitsu (fcc/frt)"] %% MPI Library oneAPI_OpenMPI["📦 OpenMPI (w/ oneAPI)"] oneAPI_MPICH["📦 MPICH (w/ oneAPI)"] GNU_OpenMPI["📦 OpenMPI (w/ GNU)"] GNU_MPICH["📦 MPICH (w/ GNU)"] NV_OpenMPI["📦 OpenMPI (w/ NV)"] NV_MPICH["📦 MPICH (w/ NV)"] Fujitsu_OpenMPI["📦 OpenMPI (w/ Fujitsu)"] Fujitsu_MPICH["📦 MPICH (w/ Fujitsu)"] %% MPI Libraries → High-level Libs %% pnetcdf oneAPI_OpenMPI --> P1["📚 pnetcdf (oneAPI+OpenMPI)"] oneAPI_MPICH --> P2["📚 pnetcdf (oneAPI+MPICH)"] GNU_OpenMPI --> P3["📚 pnetcdf (GNU+OpenMPI)"] GNU_MPICH --> P4["📚 pnetcdf (GNU+MPICH)"] NV_OpenMPI --> P5["📚 pnetcdf (NV+OpenMPI)"] NV_MPICH --> P6["📚 pnetcdf (NV+MPICH)"] Fujitsu_OpenMPI --> P7["📚 pnetcdf (Fujitsu+OpenMPI)"] Fujitsu_MPICH --> P8["📚 pnetcdf (Fujitsu+MPICH)"] %% netcdf-c oneAPI_OpenMPI --> N1["📘 netcdf-c (oneAPI+OpenMPI)"] GNU_MPICH --> N2["📘 netcdf-c (GNU+MPICH)"] Fujitsu_MPICH --> N3["📘 netcdf-c (Fujitsu+MPICH)"] %% hdf5 GNU_MPICH --> H1["📗 hdf5 (GNU+MPICH)"] Fujitsu_OpenMPI --> H2["📗 hdf5 (Fujitsu+OpenMPI)"] %% Compiler → MPI oneAPI --> oneAPI_OpenMPI oneAPI --> oneAPI_MPICH GNU --> GNU_OpenMPI GNU --> GNU_MPICH NV --> NV_OpenMPI NV --> NV_MPICH Fujitsu --> Fujitsu_OpenMPI Fujitsu --> Fujitsu_MPICH ``` ## 📊 效能比較(GCC 8.3.1 vs Fujitsu frt) | 項目 | GCC 8.3.1 | Fujitsu frt | |------|-----------|-------------| | ✅ 是否使用 SVE | ❌ 無(僅 scalar) | ✅ 已啟用 SVE + FMA | | ✅ SIMD 向量化 | ❌ 無 fmla 指令 | ✅ 有 fmla 指令 | | ✅ Loop 分析與向量註記 | ❌ 無 `DW_TAG_loop` | ✅ 有 `DW_TAG_FJ_loop` | | ✅ 自動記憶體對齊與 prefetch | ❌ 無 | ✅ 使用內建 `__jwe_xalc` | | 🚀 整體 GFLOP/s | 🐢 約 **378 GFLOP/s** | 🚀 約 **596,000 GFLOP/s** | --- ## 🔍 問題分析 - GCC 8.3.1 太舊,**無法啟用 A64FX 的 SVE 架構特性** - 沒有向量化、無法使用 fmla 指令 - 無 loop metadata,profiler 難以分析瓶頸 - 無 Tofu interconnect 支援,僅支援傳統 TCP 通訊 - 結果導致效能極差,遠不如 frt 編譯器 --- ## ✅ 解決方案 ### 1️⃣ 升級至 **GCC 13.2.0** 建議手動建置 GCC 13.2.0 以取得 SVE 與 auto-vectorization 支援: ```bash # 安裝必要套件 sudo yum groupinstall 'Development Tools' sudo yum install gcc-c++ gmp-devel mpfr-devel libmpc-devel # 解壓與建置 GCC tar -xvf gcc-13.2.0.tar.xz cd gcc-13.2.0 ./contrib/download_prerequisites mkdir build && cd build # 編譯與安裝 ../configure --prefix=/opt/gcc-13.2.0 --enable-languages=c,c++,fortran --disable-multilib make -j $(nproc) sudo make install ``` ## 📊 MPI 傳輸效能測試結果彙整(384 MPI processes) ```mermaid flowchart TD A[開始: MPI_Init] --> B{rank == 0?} B -- Yes --> C1[初始化 send_buffer 資料] C1 --> C2[配置 stat_bandwidth/stat_elapsed] C2 --> loop_start loop_start[For node in 1..N] loop_start --> D1[MPI_Send: 發送給 node] D1 --> D2[MPI_Recv: 接收回傳資料] D2 --> D3[計算耗時與頻寬] D3 --> D4[驗證資料正確性] D4 --> loop_check{還有其他 node 嗎?} loop_check -- 是 --> loop_start loop_check -- 否 --> C3[統計 avg/max/min] C3 --> C4[輸出 Summary] C4 --> G[結束訊息] B -- No --> E1[MPI_Recv: 從 rank 0 接收資料] E1 --> E2[memcpy 傳回 send_buffer] E2 --> E3[MPI_Send: 傳回給 rank 0] E3 --> G G --> H[MPI_Barrier] H --> I[MPI_Finalize] ``` ### 🚀 測試摘要(384 MPI Processes) | Case | Compiler | Base Compiler | MPI Library | Avg Bandwidth (MB/s) | Max Bandwidth (MB/s) | Min Bandwidth (MB/s) | Avg Time (s) | |------------------|-----------|----------------|--------------|-----------------------|-----------------------|-----------------------|--------------------| | **fjmpi_frt** | `mpifrt` | `Fujitsu FRT` | `fjmpi` | 525.91 | 695.24 | 444.04 | 1.547×10⁻³ | | **mpich_frt** | `mpif90` | `Fujitsu FRT` | `mpich` | 511.63 | 522.59 | 101.97 | 1.603×10⁻³ | | **mpich_gcc8_f** | `mpif90` | `GCC 8.3.1` | `mpich` | 1048.23 | 1101.50 | 45.13 | 8.954×10⁻⁴ | | **mpich_gcc13_f** | `mpif90` | `GCC 13.2.0` | `mpich` | 1079.25 | 1119.36 | 816.27 | 7.417×10⁻⁴ | | **fjmpi_fcc** | `mpifcc` | `Fujitsu FCC` | `fjmpi` | 1465.55 | 1962.08 | 1104.33 | 5.519×10⁻⁴ | | **mpich_fcc** | `mpicc` | `Fujitsu FCC` | `mpich` | 1949.79 | 2020.05 | 1139.96 | 4.110×10⁻⁴ | | **mpich_gcc8** | `mpicc` | `GCC 8.3.1` | `mpich` | 1281.48 | 1338.78 | 603.53 | 6.254×10⁻⁴ | | **mpich_gcc13** | `mpicc` | `GCC 13.2.0` | `mpich` | 1277.84 | 1349.30 | 935.73 | 6.266×10⁻⁴ | ### MPI 384 Processes ![image](https://hackmd.io/_uploads/ByAyfJTCJx.png) ### MPI 3456 Processes ![image](https://hackmd.io/_uploads/Hk8rNHCCJx.png) --- ### 📌 備註 - 測試 MPI 行程數(processes):**384** - 傳輸類型:**Double Precision 傳輸** - 測試工具:`mpi_node_test_performance` 自定 MPI 傳輸效能測試工具 - 系統架構:Fujitsu FX1000 - 平均傳輸時間單位:秒(sec) - 所有測試均使用 `mpich_exec` 或 `mpirun` 執行 --- ### Lmod **初始化 Lmod 環境管理器** ```lua source /package/fx1000/lmod-8.7.14/lmod/8.7.14/init/profile ``` **加入 fx1000-gnu 支援路徑** ```lua module use /users/xb80/privatemodules/fx1000-gnu/compiler ``` **檢查可用的 GNU Compiler** ```lua module av ---------------------- /users/xb80/privatemodules/fx1000-gnu/compiler ---------------------- gnu/11.5.0 (L) gnu/12.4.0 gnu/13.2.0 gnu/13.3.0 (D) ``` **載入 GNU Compiler 並檢查對應的 MPI Library** :warning: provide gnu-11.5.0 supoort only so far ```lua $ module load gnu/11.5.0 $ module av ------------------- /users/xb80/privatemodules/fx1000-gnu/mpi/gnu/11.5.0 ------------------- mpich/3.4.0/tofu-nv-gcc-mt ``` **載入 MPICH Module** ```lua $ module load mpich/3.4.0/tofu-nv-gcc-mt ------------------- /users/xb80/privatemodules/fx1000-gnu/mpi/gnu/11.5.0 ------------------- mpich/3.4.0/tofu-nv-gcc-mt (L) ``` **module load Script** ```bash #!/usr/bin/env bash # # fx1000_env.sh — 初始化 Lmod,並依參數載入 GCC & MPICH 模組 # # Usage: # source fx1000_env.sh [GCC_VERSION] [MPI_VERSION] [FLAVOR] # Example: # source fx1000_env.sh 12.4.0 3.4.0 tofu-nv-gcc-mt #—— 參數預設值 ——————————————————————————————————————————————— GCC_VERSION=${1:-11.5.0} MPI_VERSION=${2:-3.4.0} FLAVOR=${3:-tofu-nv-gcc-mt} #—— 初始化 Lmod —————————————————————————————————————————————— # (如有不同路徑請自行調整) source /package/fx1000/lmod-8.7.14/lmod/8.7.14/init/profile #—— 設定 Modulepath ——————————————————————————————————————————— module use /users/xb80/privatemodules/fx1000-gnu/compiler #—— 載入 GCC ——————————————————————————————————————————————— echo "Loading GCC ${GCC_VERSION}..." module load gnu/${GCC_VERSION} #—— 自動加入對應的 MPI modulepath ————————————————————————————— module use /users/xb80/privatemodules/fx1000-gnu/mpi/gnu/${GCC_VERSION} #—— 載入 MPICH —————————————————————————————————————————————— echo "Loading MPICH ${MPI_VERSION}/${FLAVOR}..." module load mpich/${MPI_VERSION}/${FLAVOR} #—— 顯示已載入模組 ——————————————————————————————————————————— echo "目前已載入的模組:" module list ``` # 🧮 Fujitsu FX1000 MPAS 效能比較報告 ## 🔍 GCC + MPICH vs. Fujitsu TCSDS --- ## 🧱 總體效能比較 | 項目 | GCC + MPICH | Fujitsu TCSDS | 效能差距 (%) | |------|--------------|----------------|---------------| | ⏱️ 總執行時間 | 4456.37 秒 | 2607.18 秒 | **+71% GCC 較慢** | | ⏳ 初始化時間 | 55.91 秒 | 32.04 秒 | **+74% GCC 較慢** | | 🔄 time integration | 3388.70 秒 | 1245.84 秒 | **+172% GCC 較慢** | | 🧮 diagnostic_fields | 831.25 秒 | 1141.13 秒 | **-27% Fujitsu 較慢** | > 📌 **結論:Fujitsu TCSDS 整體執行效能優於 GCC + MPICH,總耗時減少約 41.5%。** --- ## 🧬 子模組效能對比分析(節錄重點模組) ### 🧠 Physics Driver 子模組(GCC vs. Fujitsu) | 子模組 | GCC+MPICH 時間 (s) | Fujitsu TCSDS 時間 (s) | 效能差距 | |--------|---------------------|--------------------------|----------| | `rrtmg_swrad` | 35.20 | 31.04 | Fujitsu 較快 | | `rrtmg_lwrad` | 27.55 | 30.60 | GCC 較快 | | `Kain-Fritsch` | 41.76 | 17.04 | Fujitsu 較快 **(GCC 花費多 2.5 倍)** | | `sf_noah` | 7.49 | 5.20 | Fujitsu 較快 | | `CWBGCE` | 107.59 | 117.56 | GCC 較快 | > 🔎 部分物理模組在 GCC 下耗時明顯偏高(如 Kain-Fritsch),CWBGCE 模組在兩版本中都佔了 microphysics 模組中大量時間(GCC: 86.3%、Fujitsu: 92.2%)。 --- ## 🧭 Parallel 性能與效率 | 項目 | GCC + MPICH | Fujitsu TCSDS | |------|--------------|----------------| | 平均並行效率(整體) | 高達 1.00(總體) | 高達 1.00(總體) | | `diagnostic_fields` 並行效率 | 0.98 | 0.99 | | `time integration` 並行效率 | 1.00 | 0.99 | | `microphysics → CWBGCE` 並行效率 | 0.47 | 0.49 | > 🚀 大多數模組在 Fujitsu 上的並行效率與 GCC 類似甚至更好,顯示 Fujitsu 編譯器與 MPI stack 對大規模計算的並行支援具優勢。 --- ## 📊 效能圖示(節錄模組層級) ```mermaid %% 效能耗時比較圖 (節錄部分模組) graph LR A1[GCC - total: 4456s] --> A2[initialize: 55.9s] A1 --> A3[diagnostic_fields: 831.2s] A1 --> A4[time integration: 3388.7s] A4 --> A5[physics driver: 157.5s] A5 --> A6[CWBGCE: 107.6s] B1[Fujitsu - total: 2607s] --> B2[initialize: 32.0s] B1 --> B3[diagnostic_fields: 1141.1s] B1 --> B4[time integration: 1245.8s] B4 --> B5[physics driver: 107.7s] B5 --> B6[CWBGCE: 117.6s] ``` ![image](https://hackmd.io/_uploads/rJUhSzD1el.png) ![image](https://hackmd.io/_uploads/B163rzvygg.png) ![image](https://hackmd.io/_uploads/Hkb6HGPklx.png) ![image](https://hackmd.io/_uploads/BkX7jzv1xg.png) ## 🔚 結語與建議 * ✅ Fujitsu TCSDS 展現更佳的整體效能,尤其在 time integration 階段明顯優於 GCC。 * 🔬 建議對 GCC 組建環境進行優化調整(如提升向量化、改善編譯旗標、MPICH 設定),特別針對 Kain-Fritsch、atm_advance_scalars_mono、CWBGCE 模組進行 profiling。 * 📦 若環境許可,推薦於實際運算部署上採用 Fujitsu TCSDS toolchain,以最大化運算效能。 ## Run Script ```bash #!/bin/bash -x #PJM -L elapse=02:00:00 #PJM -L rscgrp=large #PJM -L node=96:mesh #PJM -L node-mem=unlimited #PJM -j #PJM -s #PJM -x PATH=/usr/local/bin:/usr/bin #PJM --mpi "proc=4608" # Initial module . /package/fx1000/lmod-8.7.14/lmod/8.7.14/init/profile module purge # Loading Fujitsu modules module use /users/xb80/privatemodules/fx1000 module load tcsds/1.2.40 # Loading MPI=4608 GNU_VERSION=11.5.0 module use /users/xb80/privatemodules/fx1000-gnu/compiler module load gnu/${GNU_VERSION} module load mpich/3.4.0/tofu-nv-gcc-mt # Loading hpc-stack modules export HPC_OPT=/users/xb80/opt/hpc_stack module use /users/xb80/opt/hpc_stack/modulefiles/core module load hpc-gnu/${GNU_VERSION} module load hpc-mpich-tofu/1.0.0 module load netcdf module load hdf5 module load pnetcdf module list date echo "Starting..." # MPI RUN OMP=1 MPI=4608 export UTF_EAGER_SIZE=65536 export UTF_MESSAGE_LOGGING=0 export UTF_DEBUG=0 export UTF_MSGMODE=1 export UTF_TRANSMODE=0 export MPIR_CVAR_CH4_OFI_EAGER_MAX_MSG_SIZE=65536 MPIEXEC="mpich_exec" EXEC=/users/xb80/testbed/c164/diagnostic_fields/MPAS-Model-GNU/atmosphere_model APP="${EXEC} -Wl,-T" CMD="${MPIEXEC} -n $MPI $APP" echo $CMD eval $CMD echo "Finished !" date ```