ここでは、入れ子並列領域内で次の OpenMP ルーチンを呼び出す実行について説明します。
- omp_set_num_threads() - omp_get_max_threads() - omp_set_dynamic() - omp_get_dynamic() - omp_set_nested() - omp_get_nested()
「set」呼び出しは、呼び出しスレッドが検出した並列領域と同じレベルまたはその内側で入れ子になっている、呼び出し以降の並列領域に対してのみ有効です。ほかのスレッドが検出した並列領域には無効です。
「get」呼び出しは、呼び出しスレッドが設定した値を返します。スレッドが並列領域の実行時にチームのマスターになる場合は、チームのほかのすべてのメンバーはマスタースレッドが持つ値を継承します。マスタースレッドが入れ子並列領域を終了し、その領域を取り囲む並列領域の実行を続ける場合、そのスレッドの値は、入れ子並列領域を実行する直前に、取り囲んでいる並列領域内での値に戻ります。
#include <stdio.h> #include <omp.h> int main() { omp_set_nested(1); omp_set_dynamic(0); #pragma omp parallel num_threads(2) { if (omp_get_thread_num() == 0) omp_set_num_threads(4); /* A 行*/ else omp_set_num_threads(6); /* B 行*/ /* 次のように出力される。 * * 0: 2 4 * 1: 2 6 * * omp_get_num_threads() は、チームのスレッド数を * 返します。そのためチーム内で 2 スレッドである * という同じ結果が返されます。 */ printf("%d: %d %d\n", omp_get_thread_num(), omp_get_num_threads(), omp_get_max_threads()); /* 2 つの内部並列領域は、一つは 4 スレッドのチー * ムとして、他は 6 スレッドのチームとして生成さ * れます。 */ #pragma omp parallel { #pragma omp master { /* 次のように出力されます。 * * Inner: 4 * Inner: 6 */ printf("Inner: %d\n", omp_get_num_threads()); } omp_set_num_threads(7); /* C 行*/ } |
/* 繰り返しになりますが、2 つの内部並列領域は、一つは * 4 スレッドのチームとして、他は 6 スレッドのチームと * して生成されます。 * * C 行での omp_set_num_threads(7) 呼び出しは、同じ並列 * 領域か、内部の入れ子並列領域にのみ影響を及ぼすため、 * この部分には影響を与えません。 */ #pragma omp parallel { printf("count me.\n"); } } return(0); } |
このプログラムをコンパイル、実行すると次のような結果が出力されます。
% a.out 0: 2 4 Inner: 4 1: 2 6 Inner: 6 count me. count me. count me. count me. count me. count me. count me. count me. count me. count me. |