関連情報

ナビゲーション:前へ   上へ   次へ

2 OpenMPの基礎知識

2.1 OpenMPとは

OpenMPは共有メモリ型並列プログラムを作成、実行するための枠組みです。
  • OpenMP=Open Multi-Processingの略です。
  • Fortran及びC/C++から利用可能です。
    (※本ドキュメントではFortranからの利用について説明します。)
  • コメントとして記述される指示文により並列化を行います。(Fortranの場合)
  • 多くのコンパイラ環境で利用可能なデファクトスタンダードです。
    例)NAG, Intel, gfortran, PGI, Pathscale, etc.

2.2 OpenMPの歴史

OpenMPの歴史概略を以下に示します。
Version 1.0
1997年10月 OpenMP 1.0 for Fortran が発表される
1998年10月 OpenMP 1.0 for C/C++ が発表される
Version 2.0
2000年11月 OpenMP 2.0 for Fortran が発表される
2002年3月 OpenMP 2.0 for C/C++ が発表される
Version 2.5
2005年5月 Fortran と C/C++ が統合された OpenMP 2.5 が発表される
Version 3.0
2008年5月 タスク等が導入された OpenMP 3.0 が発表される
Version 3.1
2011年7月 タスクの機能向上等を含んだ OpenMP 3.1 が発表される
Version 4.0
2013年7月 OpenMP 4.0 が発表される

2.3 OpenMPの実行モデル

OpenMPの実行モデルは fork-join モデル と呼ばれるもので、 parallel指示構文で囲まれた並列領域のみが複数のスレッドにより並列実行され、 それ以外は一つのスレッドにより逐次実行されます。

以下に参考図を示します。

ForkAndJoinModel

2.4 OpenMPの構成

OpenMPは主に以下の3つの要素から成り立ちます。
指示文
プログラムコードに同期、並列領域、処理分担等を指定する特別なコメント(指示文と呼ばれます)を記述して並列化を行います。
例)
  !$omp parallel
    print *, "Hello"
  !$omp end parallel

※上記で !$omp で始まる部分がコンパイラ指示文です。
実行時ライブラリルーチン
プログラム実行時にスレッド数を調べたり、実行時間を計測したりするためのルーチンが各種用意されています。 これらのルーチンはOpenMPを有効にするコンパイラオプション(前述)を指定することでプログラムコード内で利用可能となります。 (リンクされます)
例)
  print *, omp_num_threads()

※上記はOpenMP実行時ライブラリルーチン omp_num_threads() によりスレッド数を出力する例です。
環境変数
立ち上げるスレッド数を設定するための環境変数や、その他の実行時の設定を行うための環境変数が用意されています。
UNIX系のcsh等を利用している場合の例)
  setenv OMP_NUM_THREADS 4

Windowsのコマンドプロンプトから利用する場合の例)
  set OMP_NUM_THREADS=4

※上記は立ち上げるスレッド数を4に指定した例です。

2.5 指示文の書式

OpenMPの指示文はFortranのコメント行に記述します。 Fortranプログラムの記述方式には自由形式と固定形式がありますが、 OpenMP指示文の書式も自由形式と固定形式では若干異なります。

2.5.1 自由形式の場合の指示文の記述方法

自由形式の場合は以下の例のように行の先頭に !$omp と記述し、指示文名等を続けて記述します。
!$omp parallel

以下のように !$omp の前に空白を含む事が許されていますので、どの列から書き始めても構いません。

    !$omp parallel

OpenMPの指示文では大文字小文字が区別されませんので、下記は全て正しい記述で同じ意味を持ちます。

!$omp parallel
!$OMP PARALLEL
!$OmP PaRallel

指示文を継続する場合には行末に&を付けます。

以下の一行と

  !$omp parallel private(k)
以下の二行は同じ意味を持ちます。
  !$omp parallel &
  !$omp private(k)

OpenMPの指示文以降に現れた 以降はすべてコメントとして扱われます。 以下に例を示します。

!$omp parallel   ! This is comment

2.5.2 固定形式の場合の指示文の記述方法

固定形式の場合は行の先頭に !$ompc$omp*$omp のいずれかを記述し、指示文名等を続けて記述します。 この際自由形式の場合と異なり必ず一列目から記述する必要があります。
!$omp parallel
上記は正しい例ですが、下記は一列目から記述されていないので誤りです。
  !$omp parallel

自由形式の場合と同様、OpenMPの指示文に大文字小文字の区別はありません。

指示文を継続する場合には固定形式のFortranの継続行と同様に、継続する行の6列目をゼロと空白以外の文字にします。

以下の一行と

!$omp parallel private(k)
以下の二行は同じ意味を持ちます。
!$omp parallel
!$omp+private(k)
大文字小文字及びコメントの記述については自由形式とほぼ同じ規則が適用されます。

2.6 条件付きコンパイル

条件付きコンパイルはOpenMPが有効な場合とそうでない場合で異なる記述を行いたい場合に利用可能です。

この機能はOpenMPを利用して並列化されたプログラムと並列化されていない逐次プログラムを同じソースコードで管理したい場合に特に有効です。

条件付きコンパイルの記述は自由形式と固定形式で若干異なります。

自由形式の場合は !$ で始まる行が条件付きコンパイルの対象となります。 この際に !$ の前に空白を含む事が許されています。

固定形式の場合は !$*$c$ のいずれかで始まる行が条件付きコンパイルの対象となります。 この際に必ず一列目から記述を行う必要があります。( !$*$c$ の前に空白を含む事は許されていません)

条件付きコンパイルの記述を行った場合、OpenMPが有効な場合にはコンパイル対象となり、そうでない場合には無視されます。

例)
!$ iam = omp_get_thread_num()
!$ print *, "I am thread:", iam
上記2行はOpenMPが有効な場合のみコンパイル対象となり、そうでない場合には無視されます。

2.7 良く利用される実行時ライブラリルーチン

OpenMPでは実行環境の問い合わせや、制御、時間計測等を行うためのOpenMP実行時ライブラリルーチンが利用可能です。 これらのルーチンを利用する場合にはuse文を用いて正しい呼び出しが行われるようにします。
  use omp_lib
この記述によりOpenMP実行時ライブラリルーチンの引用仕様が含まれる omp_lib モジュールが参照され、 OpenMP実行時ライブラリルーチンを正しく呼び出す事ができるようになります。

またOpenMPが有効な場合のみ上記モジュールを利用したい場合には、 条件付きコンパイルの書式を用いて下記のように記述することも可能です。

!$ use omp_lib

以下に良く利用される実行時ライブラリルーチンを示します。

integer function omp_get_num_threads()
スレッド数を返します。並列領域外では1を返します。
integer function omp_get_thread_num()
自らのスレッド番号を返します。 スレッド番号は0〜スレッド数-1の数字となり、このうち0はマスタースレッドを示します。
※マスタースレッドとは並列領域より前から存在し、並列領域内では複数のスレッドのうちの一つとして機能し、 並列領域より後ろでも引き続き存在するスレッドを指します。

2.8 良く利用される環境変数

OpenMPにおいて最も良く利用される環境変数はOMP_NUM_THREADSです。 この環境変数により並列領域においてのスレッド数が決定されます。(OpenMPの指示文の中で明示的にスレッド数を指定した場合はこの限りではありません)

以下にコマンドウィンドウからスレッド数を4に設定してプログラム(hello.exe)を実行する際の例を示します。

UNIX系のcsh等を利用している場合の例)
  setenv OMP_NUM_THREADS 4
  ./hello.exe

Windowsのコマンドプロンプトから利用する場合の例)
  set OMP_NUM_THREADS=4
  hello.exe



ナビゲーション:前へ   上へ   次へ

Results matter. Trust NAG.
Privacy Policy | Trademarks