-インテルコンパイラ・レシピ-
株式会社HPCソリューションズ
2012年12月12日
インテルC++コンパイラ、Fortranコンパイラには最適化オプション「-fast」があり、 これを使えば細かい最適化の指定をせずに最高のパフォーマンスを得ることが出来ます。 ここでは「-fast」に含まれる意味を説明し、インテルコンパイラにおける最適化方法をご紹介します。
最適化オプション「-fast」はいくつかのオプションのセットになっています。 icc、ifortに「-help」をつけるとコンパイラ・オプション一覧が出てきますが、 それによると「-fast」は次の様に説明されています。
-fast
enable -xHOST -O3 -ipo -no-prec-div -static
options set by -fast cannot be overridden with the exception of
-xHOST, list options separately to change behavior
この5つのコンパイルオプション「-xHOST -O3 -ipo -no-prec-div -static」と 「-fast」は同じ働きをします。 5つのコンパイルオプションの意味は以下の通りです。
xHOST
generate instructions for the highest instruction set and processor
available on the compilation host machine
CPUの拡張命令セットに適した最適化を行う「-x(code)」というオプションがあります。 例えば、「-xSSE2」、「-xAVX」など。 これらはベクトル化オプションと呼ばれることもあります。 「-xHOST」は搭載されているCPUを調べ、最適なベクトル化オプションを自動的に選択します。
インテルコンパイラのベクトル化オプションには「-ax(code)」というものもあります。 例えば「-xAVX」でコンパイルされた実行モジュールはAVX命令に対応していないCPUで実行すると異常終了しますが、 「-axAVX」でコンパイルされた場合は互換コードを追加するため、AVX命令に対応していないCPUでも実行してくれます。 例えば、AMDのOpteronなど他社製互換CPUでインテルコンパイラの実行モジュールを実行する場合などに利用できます。
-O3
optimize for maximum speed and enable more aggressive optimizations that may not improve performance on some programs
最適化オプション「-O(N)」はGCCなど他のコンパイラでもよく使われる形式です。 インテルコンパイラでは「-O3」が最も高い最適化レベルです。(-O4はありません) 最適化レベルが高くなるほど最適化は進みますが、コンパイルに時間がかかります。 デフォルトは「-O2」。 「-O0」は最適化を行いません。
-ipo enable multi-file IP optimization between files
プロシージャ間の最適化を行います。 「-O(N)」はプロシージャ(オブジェクトや関数)単位の最適化を行うのに対し、 「-ipo」は更にプロシージャ間の最適化を行います。 一度オブジェクトをビルドした後に更に最適化を行うため、コンパイルに非常に時間がかかります。
-[no-]prec-div improve precision of FP divides (some speed impact)
「-no-prec-div」は割り算の演算精度を低くし計算スピードを高めるためのオプションです。 コンピュータは掛け算に比べ割り算に非常に時間がかかります。 このオプションはたいていのプログラムでは計算スピードが向上します。 ただし、精度を落としているため、演算結果に違いが出ることがあります。
-static prevents linking with shared libraries
静的(static)ライブラリをリンクして実行モジュールを作成します。 インテルコンパイラはデフォルトでは動的(shared)ライブラリを使用します。 動的ライブラリをリンクした実行モジュールの場合、実行時にライブラリのオブジェクトを読みに行くため、一般的に計算スピードが遅くなると言われています。
インテルコンパイラがリンクするライブラリはインテルコンパイラに付属するものだけでなく、 glibcをはじめ、OS標準のライブラリを多く使用します。 ところが、最新のRHEL6.xでは静的ライブラリをバンドルしないライブラリ・パッケージが増えています。 また、2GB以上のメモリを使用するプログラムの場合、動的ライブラリを指定する必要があります。 この様な場合に「-fast」オプションを使うとリンクエラーを起こします。 回避するには、以下の様に「-static」を外した「-xHOST -O3 -ipo -no-prec-div」でコンパイルする必要があります。 インテルコンパイラにバンドルされるライブラリだけをスタティックリンクする場合は「-static-intel」を使用します。
コンパイル実行例
icc -xHOST -O3 -ipo -no-prec-div test.c
ifort -xHOST -O3 -ipo -no-prec-div test.f90
インテルMPIライブラリを使用されている場合は、ラッパーコンパイルコマンド「mpiicc」や「mpiifort」を使われていると思います。 これらはコンパイラとしては「icc」、「ifort」を内部で使用しますが、 MPIライブラリやインクルードファイルのディレクトリを自動的に指定してくれます。 これらのコマンドにも「-fast」オプションがありますが、「icc」、「ifort」の 「-fast」オプションに加え、「-static_mpi」というオプションが追加されています。 mpiiccのヘルプによる説明は以下の通りです。
-fast the same as -static_mpi + pass -fast option to a compiler
「-static_mpi」の説明は以下の通りです。
-static_mpi link the Intel(R) MPI Library statically
コンパイル実行例
mpiicc -xHOST -O3 -ipo -no-prec-div -static_mpi test.c
mpiifort -xHOST -O3 -ipo -no-prec-div -static_mpi test.f90