前回作成した有限要素法プログラムを GCC, IntelLLVM, NVHPC の 3 種のコンパイラでコンパイルして性能を比較します。そのために CMake (v3.24) を使用します。
CMakeLists.txt の作成
find_package
システムにインストールされている LAPACK ライブラリの探索を find_package を使用して行います。IntelLLVM コンパイラを使用するときは,LAPACK ではなく MKL ライブラリを使用することにします。また,OpenMP も使用できるようにしておきます。
CMakeLists.txt
# Lapack
find_package(LAPACK REQUIRED)
# MKL
if(CMAKE_Fortran_COMPILER_ID MATCHES "^Intel")
find_package(MKL REQUIRED)
endif()
# OpenMP
find_package(OpenMP COMPONENTS Fortran REQUIRED)
target_compile_options
コンパイルオプションを設定します。
CMakeLists.txt
target_compile_options(heat_lu_gb PUBLIC
## GNU ##
$<$<Fortran_COMPILER_ID:GNU>: -O2 -fopenmp>
## Intel ##
$<$<OR:$<Fortran_COMPILER_ID:IntelLLVM>,$<Fortran_COMPILER_ID:Intel>>:
-O2 -xHost -qopenmp $<TARGET_PROPERTY:MKL::MKL,INTERFACE_COMPILE_OPTIONS>>
## NVIDIA ##
$<$<Fortran_COMPILER_ID:NVHPC>: -O2 -mp -Minfo=mp -Mpreprocess>
)
target_include_directories / target_link_libraries
インクルードパスとリンクパスを設定します。
CMakeLists.txt
target_include_directories(heat_lu_gb PUBLIC
## Intel ##
$<$<OR:$<Fortran_COMPILER_ID:IntelLLVM>,$<Fortran_COMPILER_ID:Intel>>:
$<TARGET_PROPERTY:MKL::MKL,INTERFACE_INCLUDE_DIRECTORIES>>
)
target_link_libraries(heat_lu_gb PUBLIC
## GNU ##
$<$<Fortran_COMPILER_ID:GNU>: OpenMP::OpenMP_Fortran LAPACK::LAPACK>
## Intel ##
$<$<OR:$<Fortran_COMPILER_ID:IntelLLVM>,$<Fortran_COMPILER_ID:Intel>>:
$<LINK_ONLY:MKL::MKL>>
## NVIDIA ##
$<$<Fortran_COMPILER_ID:NVHPC>: -llapack -lblas>
)
実質,以下のオプションが設定されたことになっています。CMake だと簡潔に書けていいですね(特に MKL 周り)。なお,gfortran の LAPACK は システム(OS)標準の LAPACK ですが,nvfortran の方は NVHPC に実装されたライブラリであることに注意が必要です。
コンパイルオプション | リンクオプション | |
---|---|---|
gfortran | -O2 -fopenmp | -llapack -lblas |
ifx | -O2 -xHost -qopenmp -qmkl | -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread |
nvfortran | -O2 -mp -Minfo=mp -Mpreprocess | -llapack -lblas |
ビルド
ビルドします。
cmake -B build --fresh -DCMAKE_Fortran_COMPILER=gfortran
cmake --build build
ベンチマーク
メッシュ数 4096,計算ステップ数 100 の条件で処理速度を比較しました(単位は秒)。今回の計測ではシングルコアの使用に制限しています。
GCC | IntelLLVM | NVHPC |
---|---|---|
3.5 | 0.7 | 2.9 |
なお,環境は以下のものを使用しました。
- CPU
- Intel Xeon W-1270
- 開発環境
- GCC 13.2.1 / Intel oneAPI 2023.1.0 / NVIDIA HPCSDK 23.5