PGIコンパイラ 並列化機能、OpenMP、MPI、OpenACC
PGI の F77, F2003, C, C++ の全ての言語コンパイラには、マルチ(コア)・プロセッサに対応する自動並列化機能および、OpenMP を用いた並列化コンパイル機能が実装されております。また、2009 年には、GPUをアクセラレータとして構成するハードウェアに対する PGIアクセラレータ機能(ディレクティブでコンパイラにGPU上の並列化を行う場所を指示する方法)も、コンパイラメーカとして業界で初めて提供しました。この機能は、2011年策定された OpenACC 規約のベースとなりました。さらに、マルチプロセス用の並列化である MPI ライブラリを利用した実行モジュールも簡単に作成できます。その他、汎用商用コンパイラで唯一提供する PGHPF コンパイラ(Linux 版のみ)を用いた HPF 言語による並列化も可能です。
以下に述べる三つの並列化方法のうち、一台のシステム内のマルチコア環境で、簡単に実行でき、ある程度の性能が得られるのは、"-Mconcur" オプションによる自動並列化です(プログラムによっては性能が得られない場合もあります)。"-Minfo" オプションを付けてコンパイルを行うと、プログラム中のどの部分が並列化されたか分かりますので、更に性能を向上させたい場合は、さらに OpenMP 指示行を入れてみるなどの指示行ベースの並列化を行うことができます。なお、自動並列化機能とOpenMP 指示行による並列化は、その混在使用が可能です。マルチコア上で可能となる並列化コンパイラ・オプションの詳細は、こちらのページでご覧ください。オープンソースの MPI ライブラリを利用すると、マルチコア上の並列実行だけでなく、マルチノード上での並列実行も可能となります。この場合は、プログラムは MPI 化する必要があります。
(1) 自動並列化によるスレッド並列化
コンパイル時にコンパイル・オプション "-Mconcur" を付けます。また、実行前にシェル環境変数 NCPUS もしくは OMP_NUM_THREADS にて、並列実行スレッド数を設定することにより、並列実行が可能です。この並列化は、コンパイラが、プログラム中で並列化可能な部分(DO / forループ部分等)の依存性解析を行い、可能であればを並列化行います。そのため、並列化による効果が少ない場合、並列化による性能向上が図れない場合があります(逆に、プログラム特性によっては性能が落ちる場合もありますので、性能の検証を行うことが必要です)。 並列化実行で指定できる スレッド数の上限は 256までとなっております。
(例) $ pgfortran -o test -Mconcur -Minfo test.f $ export OMP_NUM_THREADS=2 (bash 使用時で、スレッド数 2を指定) $ ./test
(2) OpenMP によるスレッド並列化
ユーザプログラム中に OpenMP 指示行 (http://www.openmp.org ご参照下さい)を挿入することにより、コンパイラは、当該ディレクティブ(Cの場合はプラグマ)で指定された部分のスレッド並列化を行います。 コンパイル時のコンパイル・オプションとして、"-mp" を付けます。 実行前にシェル環境変数 NCPUS もしくは OMP_NUM_THREADS にて、並列実行スレッド数を設定することにより、並列実行が可能です。特徴としては、自動並列化に較べ、並列化の場所をユーザが明示的に指定し最適化できるので、性能がより向上させることができます。ただし OpenMP 指示行の宣言子(宣言句)を理解していないと、正常に動作しないプログラムになる場合があります(性能低下、計算結果が異なる等)。OpenMP 宣言子(宣言句)は、コンパイラに対して補足情報(あるいはヒント)を与えるためのものではなく、明示的に宣言子を指定し並列化を指示するためのものです。従って、誤った指示を与えた場合でも、忠実に並列化を行いますので、並列計算に依存性が内在する場合、計算結果が不正となります。また、OpenMP 指示行を入れたにも拘らず、「性能向上しない」と言った問題は OpenMP のデータ環境宣言句(SHARED、PRIVATE 等)の設定の誤り等が原因の場合が多いです。並列化実行で指定できる スレッド数の上限は 256までとなっております。
(例)ユーザプログラム例 (test.f) ---------------------------------- C USER PROGRAM INTEGER A(1056,1024) C$OMP PARALLEL SHARED ... ← OpenMP指示行(通常のコンパイラで C$OMP DO はコメントと見なされます) DO J = 1, 1024 ... END DO C$OMP END DO NOWAIT ---------------------------------- $ pgfortran -o test -mp -Minfo test.f $ export OMP_NUM_THREADS=2 (bash 使用時で、CPU数 2 を指定) $ ./test
(3) MPIライブラリによる並列化
PGI コンパイラ製品には、直ぐに MPI プログラムをコンパイルできるように、MPICH1 ライブラリがバンドルされております。コンパイルオプションを付加することにより、MPIライブラリを使用した実行モジュールが生成できます。また、PGI CDK 製品には、MPICH1、MPICH2、MVAPICH1 等のライブラリもバンドルされております。MPIライブラリを使用する方法関しては、以下のページをご覧下さい。
(4) GPUアクセラレータ用並列化
汎用アクセラレータとしてグラフィックス・プロセッシング・ユニット(GPU) 上で、そのGPUコアを使用して並列計算を行うための並列化機能を提供します。これは、PGI Accelerator™ 機能と称します。PGI Accelerator™ 機能は、NVIDIA社の GPU/GPGPU とその CUDA 開発環境を実装したシステム上で、GPUを活用するためのコンパイラを含めたプログラム開発環境を提供します。具体的には、OpenMP 形式のようなディレクティブ挿入による x64+GPU 用実行バイナリの自動生成機能(OpenACC準拠)、PGI CUDA Fortran 機能、そして、CUDA C/C++ プログラムを GPU を有しないマルチコア x64 プロセッサ上で動作させる機能を有します。この詳細に関しては、「GPU対応 PGI アクセラレータ™ コンパイラ」をご覧下さい。
(5) HPF言語による並列化 (PGHPFの使用:Linux環境のみ)
PGHPFコンパイラの提供は終息しました。現在は、サポートとしておりません。
ユーザプログラム中に HPF 指示行 (PGHPF Reference manual ご参照下さい) を挿入することで、ユーザ指定の並列化を行ないます。 HPF 言語による並列化は、SMP マシンのみだけでなく、複数の分散メモリ型のアーキテクチャ(PCクラスタ等)でも並列実行が可能です。 複数のマシン間での並列実行の際は、MPI 等の並列通信ライブラリが別途必要となります。 実行時には、環境変数 PGHPF_HOST に使用するマシン名を指定する必要があります。PGHPF のコンパイル方法、実行環境の設定の仕方は、こちらのページをご覧ください。HPF 言語を用いると複数のマシン間での並列実行が可能となりますが、OpenMP 自動並列化と同様に、HPF 指示行の記述を慎重に行なう必要があります。なお、HPF言語体系は過去の体系となっていますので、今後は、OpenMP/OpenACC/MPI等の並列化手法を採用することを推奨します。
(例)ユーザプログラム例 (test.F) ---------------------------------- C USER PROGRAM INTEGER A(1056,1024) !HPF$ DISTRIBUTE A(BLOCK) ← HPF指示行(通常のコンパイラで !HPF$ ALIGN X(1) WITH Y(1) はコメントと見なされます) DO J = 1, 1024 ... END DO ---------------------------------- $ pghpf -o test -Msmp test.F (同一マシン内 shared memory を使用する場合) $ pghpf -o test -Mmpi test.F (複数のマシンで MPIを用いる場合) $ export PGHPF=node01,node01 (bash 使用時で、node01 の 2CPU 使用時) $ ./test -pghpf -np 2 (同一マシン内の場合) $ mpirun -np 2 ./test -pghpf (MPI使用時)