• ノード内並列(共有メモリ並列)処理を行う方法は、「自動並列化」と「OpenMP」の2種類があります。

     

    自動並列化とは

      コンパイラがソースコードを解析し、自動的にプログラムの構造に適したノード内並列実行が可能なモジュールを作成します。コンパイル オプションを指定するのみで、簡単に並列化が可能です。

       

      基本的な利用方法

        基本的には、コンパイルを行うのみで利用することができます。

         

        コンパイル方法

        SQUIDでは intelコンパイラが利用可能です。
        プログラミング言語ごとにコマンドが異なりますので、ご注意ください。

        $ module load BaseCPU

        $ ifort -parallel [options] source_file (Fortranの場合)
        $ icc -parallel [options] source_file (Cの場合)
        $ icpc -parallel [options] source_file (C++の場合)

        並列化レポートの出力をする場合は、「-qopt-report=[n] -qopt-report-pahse=par」オプションをつけてください。
        [n]にはメッセージレベルを0~5で指定することが可能です。

         

        実行スクリプト

        実行時は OMP_NUM_THREADS という環境変数に、並列数を指定します。

        下記はノード内76並列の計算を経過時間 1時間で実行する際のスクリプト例です。

         

        利用時の注意点

        実行スクリプトにて、「OMP_NUM_THREADS」を忘れずに指定してください。
        「OMP_NUM_THREADS」を指定しない場合、あるいは間違った値を指定してしまった場合、意図しない並列数での実行となり、他の利用者の計算に影響が出る可能性があります。
        ご注意ください。

       

      参考資料

    OpenMPとは

      プログラムの中にコンパイラに対する指示行を挿入し、ノード内並列化(共有メモリ並列処理)を行う方法です。
      CとFortranで記述方法がやや異なります。以下に簡単な利用方法を記載します。

       

      基本的な利用方法

        以下にFortranで書かれたOpenMPプログラムを載せています。
        こちらを参考に説明します。

         

        ハイライトしている行(3行目-6行目)の部分がOpenMPに関連する処理となります。
        include "omp_lib.h"[3行目]、omp_get_thread_num()[5行目]、omp_get_num_threads()[5行目]は、OpenMP処理をPrint出力するために挿入した処理になりますので、入力しなくても、並列処理としての動きは変わりません。

         

        3行目: include "omp_lib.h"
        はOpenMPライブラリルーチン用のインクルードファイルの指定です。
        後述のライブラリルーチンを使用するために必要です。

         

        4行目: !$omp parallel

        6行目: !$omp end parallel
        は、OpenMPの指示行です。
        parallel指示行はend parallel指示行まで、ブロックを並列化することを示しています。
        今回の場合は5行目が並列処理されます。
        並列数は環境変数OMP_NUM_THREADSで指定することになります。

         

        5行目の omp_get_thread_numomp_get_num_threads はOpenMPのライブラリルーチンとなります。
        これらのルーチンを使用する場合は、2行目のインクルードファイルの指定が必要です。
        omp_get_thread_num では、処理を分割している数(並列スレッド数)を取得します。
        omp_get_num_threads では、分割された処理(並列スレッド)ごとにつけられた番号を取得します。番号は0から始まります。

         

        上記のプログラムを、4並列で実行した結果は下記のようになります。

        HELLO WORLD mythread= 3 ( 4 threads)
        HELLO WORLD mythread= 1 ( 4 threads)
        HELLO WORLD mythread= 0 ( 4 threads)
        HELLO WORLD mythread= 2 ( 4 threads)

         

        指示行について

        自動並列化とは異なり、ユーザ自身が「指示行」を挿入し、並列化を指示する必要があります。
        指示行は言語によって異なり、

        !$omp 指示行名 (Fortranの場合)
        #pragma omp 指示行名(C/C++の場合)

        という形式でプログラム中に埋め込みます。
        指示行については、参考資料をご覧ください。

         

        コンパイル方法

        $module load BaseCPU

        $ ifort -qopenmp [options] source_file
        $ icc -qopenmp [options] source_file
        $ icpc -qopenmp [options] source_file

        並列化レポートの出力をする場合は、「-qopt-report=[n] -qopt-report-pahse=openmp」オプションをつけてください。
        [n]にはメッセージレベルを0~2で指定することが可能です。

         

        実行スクリプト

        実行時はOMP_NUM_THREADSという環境変数に、並列数を指定します。

        下記はノード内76並列の計算を経過時間 1時間で実行する際のスクリプト例です。

         

        利用時の注意点

        実行スクリプトにて、「OMP_NUM_THREADS」を忘れずに指定してください。
        「OMP_NUM_THREADS」を指定しない場合、あるいは間違った値を指定してしまった場合、意図しない並列数での実行となり、他の利用者の計算に影響が出る可能性があります。
        ご注意ください。

       

      参考資料