4. コンパイラーの比較

4.1 moduleコマンド

コンパイラー(とそのバージョン)によって開発時と実行時に必要な環境変数が異なりますが、 FOCUSではmoduleコマンドにより一括設定できるようになっています。
設定するには以下のコマンドを実行します。
$ module load モジュール名
解除するには以下のコマンドを実行します。
$ module unload モジュール名
moduleコマンドのその他の使い方は以下の通りです。
$ module --help (使い方の説明)
$ module avail (使用可能なモジュール一覧を表示する)
$ module list (現在登録されているモジュールを表示する)
初期状態ではgcc4.4.7のみが使用可能になっています。

4.2 コンパイラーのバージョンの比較

表4.1にコンパイラーのバージョンと計算時間の関係を示します。
コンパイルオプションについては後に述べるよう最も速い設定にしています。 これからgccとIntel C/C++(icc)ではバージョンによる違いは小さいと言えます。
以下では標準のバージョン(gcc 4.4.7, icc 16.0.2)を使用します。

表4.1 コンパイラーのバージョンと計算時間の関係(1スレッド、benchmark1.ofd)
モジュール名コンパイラーコンパイルオプション計算時間
なしgcc 4.4.7-O326.764秒
PrgEnv-gnu482gcc 4.8.2-O325.800秒
PrgEnv-intel-14.0.0.080Intel C/C++ 14.0.0-O3 -ipo19.814秒
PrgEnv-intel-14.0.2.144Intel C/C++ 14.0.2-O3 -ipo19.870秒
PrgEnv-intel-15.0.1.133Intel C/C++ 15.0.1-O3 -ipo23.894秒
PrgEnv-intel-16.0.2.181Intel C/C++ 16.0.2-O3 -ipo18.883秒

4.3 コンパイルオプション

表4.2にコンパイルオプションと計算時間の関係を示します。
gccではコンパイルオプションによる差はありませんが、 iccでは"-ipo"をつけると約1.5倍速くなります。 これからOpenFDTDではiccではコンパイルオプション"-ipo"をつけたほうが望ましいです。 ("-ipo"はファイル間のメモリー利用を効率化するオプションです)
以下ではgccのコンパイルオプションは"-O3"、 iccのコンパイルオプションは"-O3 -ipo"とします。

表4.2 コンパイルオプションと計算時間の関係(1スレッド、benchmark1.ofd)
コンパイラーコンパイルオプション計算時間
gcc 4.4.7-O226.238秒
gcc 4.4.7-O326.764秒
icc 16.0.2-O228.941秒
icc 16.0.2-O327.463秒
icc 16.0.2-O3 -ipo18.883秒

4.4 MPIライブラリー

表4.3にMPIライブラリーを変えたときの1プロセスと4プロセスの計算時間を示します。
これから以下のことがわかります。
・MPIライブラリーによる違いはない
・Intel C/C++ではコンパイルオプション"-ipo"をつけているにも関わらず表4.2の"-ipo"がない場合と計算時間が同じである。
・いずれの場合も4プロセスでは1プロセスの約4倍速くなっている。
以下ではMPIを使用するときはコンパイラーはgcc 4.4.7、 MPIライブラリーはOpenMPI 1.6.5とします。

表4.3 MPIライブラリーと計算時間の関係(benchmark1.ofd)
コンパイラーMPIライブラリーコンパイルオプション1プロセス計算時間4プロセス計算時間備考
gcc 4.4.7 (mpicc)gnu/mpich2141p1-O328.193秒8.217秒
gcc 4.4.7 (mpicc)gnu/openmpi142-O326.636秒8.391秒
gcc 4.4.7 (mpicc)gnu/openmpi165-O331.170秒7.317秒
icc 16.0.2 (mpiicc)impi410-O3 -ipo29.908秒7.497秒mpdが必要
icc 16.0.2 (mpiicc)impi411-O3 -ipo29.147秒7.474秒mpdが必要
icc 16.0.2 (mpiicc)impi502-O3 -ipo29.537秒7.539秒mpdが必要
icc 16.0.2 (mpiicc)impi513-O3 -ipo28.648秒7.431秒mpdが必要

4.5 並列化手法の比較

表4.4と図4.1に並列化手法として、マルチスレッド、OpenMP、MPIの3通りの計算時間を示します。
コンパイラーはgcc 4.4.7、MPIのライブラリーはOpenMPI 1.6.5です。
これからコア数が多いときはMPIが最も速いことがわかります。 マルチスレッドはスレッド起動のオーバーヘッドが大きいため性能が低いことがわかります。 MPIでは問題のサイズが大きくなったときさらに高い速度比が得られることが期待できます。

表4.4 並列化手法と計算時間の関係(gcc 4.4.7, benchmark1.ofd)
コア数マルチスレッドOpenMPMPI
128.090秒28.488秒28.038秒
232.089秒13.892秒13.921秒
427.944秒8.005秒7.114秒
817.234秒4.532秒4.264秒
1214.585秒3.451秒3.095秒
1613.455秒3.047秒2.516秒
2014.889秒3.244秒2.029秒

図4.1 並列化手法と速度比の関係(gcc 4.4.7, benchmark1.ofd)

4.6 OpenMPとMPIの併用

共有メモリー並列化であるOpenMPと分散メモリー並列化であるMPIは併用することができます。
表4.5に総コア数=16を一定とし、OpenMPとMPIの配分を変えたときの計算時間を示します。
これからMPIのプロセス数が多い方が速いことがわかります。 従って、OpenMPIとMPIを併用するよりMPI単独の方が速い、と言えます。

表4.5 OpenMPとMPIの併用(総コア数=16一定, gcc 4.4.7, benchmark1.ofd)
OpenMPスレッド数MPIプロセス数計算時間
1162.611秒
282.876秒
443.099秒
823.481秒
1614.459秒

4.7 まとめ

本章でわかったことをまとめると以下のようになります。

  1. gccもIntel C/C++もバージョンによる違いは小さい。
  2. コンパイルオプションはgccでは"-O3"、Intel C/C++では"-O3 -ipo"がよい。
  3. MPIライブラリによる違いは小さい。
  4. 並列化手法としてはMPIはOpenMPより少し速く、コア数が大きいとき差が大きくなる。 マルチスレッドは遅いので使用する価値はない。
  5. OpenMPとMPIを併用するよりMPI単独の方が速い。
以上から現時点での開発環境は、gcc 4.4.7 + OpenMPI 1.6.5が最適と言えます。