ナビゲーションリンクをスキップ | |
印刷ビューの終了 | |
Oracle Solaris Studio 12.3: OpenMP API ユーザーガイド Oracle Solaris Studio 12.3 Information Library (日本語) |
入れ子並列処理は、プログラムの実行前にさまざまな環境変数を設定することでその実行を制御できます。
入れ子並列処理は、OMP_NESTED 環境変数を設定するか omp_set_nested() を呼び出すことで有効または無効に設定できます。
3 つのレベルを持つ、入れ子並列構文の例を次に示します。
例 4-1 入れ子並列処理の例
#include <omp.h> #include <stdio.h> void report_num_threads(int level) { #pragma omp single { printf("Level %d: number of threads in the team - %d\n", level, omp_get_num_threads()); } } int main() { omp_set_dynamic(0); #pragma omp parallel num_threads(2) { report_num_threads(1); #pragma omp parallel num_threads(2) { report_num_threads(2); #pragma omp parallel num_threads(2) { report_num_threads(3); } } } return(0); }
入れ子並列処理を有効にして、このプログラムをコンパイルおよび実行すると、次のようなソート済みの結果が出力されます。
% setenv OMP_NESTED TRUE % a.out Level 1: number of threads in the team - 2 Level 2: number of threads in the team - 2 Level 2: number of threads in the team - 2 Level 3: number of threads in the team - 2 Level 3: number of threads in the team - 2 Level 3: number of threads in the team - 2 Level 3: number of threads in the team - 2
次の例では、入れ子並列処理を無効にして同じプログラムを実行します。
% setenv OMP_NESTED FALSE % a.out Level 1: number of threads in the team - 2 Level 2: number of threads in the team - 1 Level 3: number of threads in the team - 1 Level 2: number of threads in the team - 1 Level 3: number of threads in the team - 1
OpenMP 実行時ライブラリにはスレッドがプールされていて、並列領域内でのスレーブスレッドとして使用されます。OMP_THREAD_LIMIT 環境変数の設定は、プール内のスレッド数を制御します。デフォルトでは、プール内のスレッド数は最大で 1023 個です。
プールにあるのは、実行時ライブラリが作成した非ユーザースレッドだけです。プールには、最初のスレッドやユーザーのプログラムが明示的に作成したスレッドは含まれません。
OMP_THREAD_LIMIT を 1 に設定 (または SUNW_MP_MAX_POOL_THREADS を 0 に設定) すると、スレッドのプールは空になり、すべての並列領域は 1 つのスレッドによって実行されます。
次の例では、プール内のスレッド数が不十分な場合、並列領域で取得されるスレッド数も少なくなることを示しています。コードは 例 4-1 と同じです。アクティブ化されるすべての並列領域に必要な同時スレッドの数は、8 個です。つまり、プールには少なくとも 7 個のスレッドが含まれている必要があります。OMP_THREAD_LIMIT を 6 に設定した場合 (または SUNW_MP_MAX_POOL_THREADS を 5 に設定した場合)、プールには最大で 5 個のスレーブスレッドが含まれます。これは、もっとも内側にある 4 つの並列領域のうち 2 つが、必要な数のスレーブスレッドを取得できないことを示します。次の例は、可能性のある 1 つの結果を示しています。
% setenv OMP_NESTED TRUE % OMP_THREAD_LIMIT 6 % a.out Level 1: number of threads in the team - 2 Level 2: number of threads in the team - 2 Level 2: number of threads in the team - 2 Level 3: number of threads in the team - 2 Level 3: number of threads in the team - 2 Level 3: number of threads in the team - 1 Level 3: number of threads in the team - 1
環境変数 OMP_MAX_ACTIVE_LEVELS は、アクティブな並列領域をいくつまで入れ子にすることができるかを制御します。並列領域がアクティブであると見なされるのは、複数のスレッドで構成されているチームによって実行される場合です。入れ子になったアクティブな並列領域の最大数のデフォルトは 4 です。
この環境変数を設定するだけでは、入れ子並列処理は有効になりません。この環境変数は、入れ子になったアクティブな並列領域の最大数を制御するだけで、入れ子並列処理を有効にはしません。入れ子並列を有効にするには、OMP_NESTED を TRUE に設定するか、true と評価される引数を指定して omp_set_nested() を呼び出す必要があります。
次に、4 重の入れ子になった並列領域のコードの例を示します。OMP_MAX_ACTIVE_LEVELS が 2 に設定されると、3 番目と 4 番目の深さにある入れ子並列領域は 1 つのスレッドによって実行されます。
#include <omp.h> #include <stdio.h> #define DEPTH 5 void report_num_threads(int level) { #pragma omp single { printf("Level %d: number of threads in the team - %d\n", level, omp_get_num_threads()); } } void nested(int depth) { if (depth == DEPTH) return; #pragma omp parallel num_threads(2) { report_num_threads(depth); nested(depth+1); } } int main() { omp_set_dynamic(0); omp_set_nested(1); nested(1); return(0); }
次の例は、入れ子の深さの最大数を 4 に設定してこのプログラムをコンパイルし実行した場合の、可能性のある結果を示しています。実際の結果は、OS がどのようにスレッドをスケジューリングしているかによって異なります。
% setenv OMP_MAX_ACTIVE_LEVELS 4 % a.out |sort Level 1: number of threads in the team - 2 Level 2: number of threads in the team - 2 Level 2: number of threads in the team - 2 Level 3: number of threads in the team - 2 Level 3: number of threads in the team - 2 Level 3: number of threads in the team - 2 Level 3: number of threads in the team - 2 Level 4: number of threads in the team - 2 Level 4: number of threads in the team - 2 Level 4: number of threads in the team - 2 Level 4: number of threads in the team - 2 Level 4: number of threads in the team - 2 Level 4: number of threads in the team - 2 Level 4: number of threads in the team - 2 Level 4: number of threads in the team - 2
次の例は、入れ子の深さを 2 に設定して実行した場合の、可能性のある結果を示しています。
% setenv OMP_MAX_ACTIVE_LEVELS 2 % a.out |sort Level 1: number of threads in the team - 2 Level 2: number of threads in the team - 2 Level 2: number of threads in the team - 2 Level 3: number of threads in the team - 1 Level 3: number of threads in the team - 1 Level 3: number of threads in the team - 1 Level 3: number of threads in the team - 1 Level 4: number of threads in the team - 1 Level 4: number of threads in the team - 1 Level 4: number of threads in the team - 1 Level 4: number of threads in the team - 1
この例は、可能性のある結果の一部のみを示しています。実際の結果は、OS がどのようにスレッドをスケジューリングしているかによって異なります。