おいも貴婦人ブログ

生物系博士課程満期退学をしたAIエンジニアのブログ。

はじめてのOpenMP(4)

OpenMPの構文は以下のようになります。

#pragma omp 指示文名 [指示句[]...]

指示文

parallel 構文
  • 並列実行の開始を指示し、複数のスレッドを生成する。
for 構文
  • forループの繰り返しがスレッドに並列処理されることを指定する。
#pragma omp for [指示句[]...]
for(...)
  • 使える指示句:private,firstprivate,lastprivate,reduction,schedule,collapse,ordered,no wait.
  • 並列化できない例:ループ回数がわからない。ループインデックスが一定でない。breakする。
sections 構文
  • 並列実行するブロックをそれぞれ定義する。
#pragma omp sections [指示句[]...]
{
    [#pragma omp section]
        処理ブロック
    [#pragma omp section]
        処理ブロック
    ...
}
  • 使える指示句:private,firstprivate,lastprivate,reduction,nowait.
  • section構文の最後にバリアがあるものとして処理される。
single 構文
  • 関連づけられた構造化ブロックを1つのスレッドだけで実行する。
#pragma imp single [指示句[]...]
    処理ブロック
  • 使える指示句:private,firstprivate,lastprivate,nowait.
  • どのスレッドが実行するかは不明。
parallel for 構文
  • 1つのループ構文だけで構成されるparallel構文を指定する
#pragma omp parallel for [指示句[]...]
    処理ブロック
  • 使える指示句:nowait以外。
  • parallel指示文とfor指示文を連続して使用しただけ。
parallel sections 構文
  • 1つのsections構文だけから形成されるparallel構文を指定する。
#pragma omp parallel sections [指示句[]...]
{
    [#pragma omp section]
        処理ブロック
    [#pragma omp section]
        処理ブロック
    ...
}
  • 使える指示句:nowait以外。
  • parallel指示文とsections指示文を連続して使用しただけ。
master 構文
  • マスタースレッドによて実行される構造化ブロックを指定する。
#pragma omp master
処理ブロック
critical 構文
  • 一度に1つのスレッドだけが関連したブロックを実行するように制限する。
#pragma omp critical [(名前)]
    処理ブロック
  • 他にcritical文がある場合、そのcritical文が実行されるまで待つ。
barrier 構文
  • この構文が現れた位置に明示的なバリアを指定する。
#pragma omp barrier
  • 並列リージョンを実行しているすべてのスレッドの動機をとる。
atomic 構文
  • 特定の記憶域が、複数のスレッドによって同時に書き込まれないようにする。
#pragma omp atomic
  • 指定できる構文:x binop = expr,x++,++x,x--,--x
flush 構文
  • 指定された変数をすべてのスレッドで同じメモりビューを持つようにする。
#pragma omp flush[(リスト)]
  • ポインタをフラッシュすると、ポインタ自体がフラッシュされるので注意。
ordered 構文
  • 並列処理されるforループ内のコードを順次実行する。
#pragma omp oerderd
    処理ブロック
threadprivate 構文
  • リストに指定した項目が並列リージョンのスレッドに対してプライベート変数として扱われることを指定する。
#pragma omp threadprivate (リスト) 
  • リストで指定する変数は、グローバル変数または静的変数でなければならない。

指示句

default 指示句
  • 並列リージョン内で参照される変数のデータ共有属性を指定する。
#default(shared | none)
shared 指示句
  • 並列リージョンで使用される変数を共有変数にすることを宣言する。
shared(リスト)
private 指示句
  • 並列リージョンで使用される変数をプライベートへすうとすることを宣言する。
private(リスト)
  • すべてのスレッドへ別々の記憶域が割り当てられ、変数の値は引き継がれない。
firstprivate 指示句
  • 並列リージョンで使用される変数をプライベート宣言し、並列リージョンへ入る前の値で初期化する。
fisrtprivate(リスト)
lastprivate 指示句
  • 並列リージョンで使用される変数をプライベート宣言し、最後の値をオリジナルへコピーする。
lastprivate(リスト)
reduction 指示句
  • 1つの演算子とリストを指定する。
reduction(operator:リスト)
  • 使える演算子、+,*,-,&,|,^,&&,||
  • 初期値、0,1,0,~0,0,0,1,0
copyin 指示句
  • マスタースレッドのthread privateに指定した変数の値を、並列リージョンへ入る前にプライベート変数にコピーする。
copyin(リスト)
copyprivate 指示句
  • あるスレッドが取得した値を、他の全てのスレッドのプライベート変数に設定する。
copyprivate(リスト)
if 指示句
  • ループを並列実行するか逐次実行するかを指定する。
if (式)
nowait 指示句
  • 並列リージョンにある暗黙のバリアを無効にする。
nowait
num_threads 指示句
  • 対応する並列ブロックのスレッド数を指定する。
num_threads(整数)
schedule 指示句
  • ループをどのように分散するか指定する。
schedule(type[,size])
  • typeで使用できる宣言:static,dynamic,guided,runtime
  • size:割り当てたスレッドが連続で処理する反復回数を整数で指定する。

実行時ライブラリ

omp_get_num_procs
  • 関数の呼び出し時点で使用できるプロセッサ数を返します。
int omp_get_num_procs(void);
omp_set_dynamic
  • 後続の並列リージョンで使用できるスレッド数を、実行時に調整できるようにする。
void omp_set_dynamic(int dynamic_threads);
omp_get_dynamic
  • 後続の並列リージョンで使用できるスレッド数を、実行時に調整できるか示す値を返す。
int omp_get_dynamic(void);
  • スレッドの自動調整が有効である場合は、true、そう出なければ、falseを返します。
omp_set_num_threads
  • 指定した値をOpenMP内部制御変数に設定し、num_threads指示句の指定されていないparallel指示文が生成するスレッド数に影響を与える。
void omp_set_num_threads(int num_threads);
omp_get_num_threads
  • 並列リージョン内のスレッド数を返す。
int omp_get_num_threads(void);
omp_get_max_threads
  • num_threads指示句のない並列リージョンで使用できるスレッド数の上限値を返す。
int omp_get_max_threads(void);
omp_get_thread_num
  • この関数を呼び出したスレッドの、スレッド番号を返す。
int omp_get_thread_num(void);
omp_in_parallel
  • 並列処理リージョン内から呼ばれた場合にtrue(0以外)を返す。それ以外はfalse(0)を返す。
int omp_in_parallel(void);

環境変数

OMP_SCHEDULE
  • ランタイムスケジュールタイプとチャンクサイズを指定する。
OMP_NUM_THREADS
  • 使用できるスレッド数を設定する。
OMP_DYNAMIC
  • スレッド数の自動調整を有効または無効にする。

詳しい説明は以下の本を参照してください。

OpenMP入門―マルチコアCPU時代の並列プログラミング

OpenMP入門―マルチコアCPU時代の並列プログラミング