JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
Oracle Solaris Studio 12.2: OpenMP API ユーザーガイド
search filter icon
search icon

ドキュメントの情報

はじめに

1.  OpenMP API について

2.  OpenMP プログラムのコンパイルと実行

3.  実装によって定義される動作

4.  入れ子並列処理

4.1 実行モデル

4.2 入れ子並列処理の制御

4.2.1 OMP_NESTED

4.2.2 OMP_THREAD_LIMIT

4.2.3 OMP_MAX_ACTIVE_LEVELS

4.3 入れ子並列領域での OpenMP ライブラリルーチンの使用

4.4 入れ子並列処理を使う際のヒント

5.  タスク化

6.  変数の自動スコープ宣言

7.  スコープチェック

8.  パフォーマンス上の検討事項

A.  指令での節の記述

B.  OpenMP への変換

索引

4.2 入れ子並列処理の制御

入れ子並列処理は、プログラムの実行前にさまざまな環境変数を設定することでその実行を制御できます。

4.2.1 OMP_NESTED

入れ子並列処理は、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

4.2.2 OMP_THREAD_LIMIT

OpenMP 実行時ライブラリにはスレッドがプールされていて、並列領域内でのスレーブスレッドとして使用されます。OMP_THREAD_LIMIT 環境変数の設定は、プール内のスレッド数を制御します。デフォルトでは、プール内のスレッド数は最大で 1023 個です。

プールにあるのは、実行時ライブラリが作成した非ユーザースレッドだけです。最初のスレッドやユーザーのプログラムが明示的に作成したスレッドは含まれません。

OMP_THREAD_LIMIT が 1 に設定されている場合 (または SUNW_MP_MAX_POOL_THREADS がゼロに設定されている場合)、スレッドプールは空になり、すべての並列領域は 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

4.2.3 OMP_MAX_ACTIVE_LEVELS

環境変数 OMP_MAX_ACTIVE_LEVELS は、スレッドを複数必要とする有効な並列領域を何層まで入れ子にすることができるかを制御します。

この環境変数で指定した数を超える有効な入れ子を持つ有効な並列領域は、1 つのスレッドによって実行されます。並列領域が有効であると見なされるのは、if 節がない場合と、if 節の評価が true となるときです。有効な入れ子レベルのデフォルトの最大数は 4 です。

次に、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 がどのようにスレッドをスケジューリングしているかによって異なります。