JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
Oracle Solaris Studio 12.3: OpenMP API ユーザーガイド     Oracle Solaris Studio 12.3 Information Library (日本語)
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.  指令での節の記述

索引

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 を 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

4.2.3 OMP_MAX_ACTIVE_LEVELS

環境変数 OMP_MAX_ACTIVE_LEVELS は、アクティブな並列領域をいくつまで入れ子にすることができるかを制御します。並列領域がアクティブであると見なされるのは、複数のスレッドで構成されているチームによって実行される場合です。入れ子になったアクティブな並列領域の最大数のデフォルトは 4 です。

この環境変数を設定するだけでは、入れ子並列処理は有効になりません。この環境変数は、入れ子になったアクティブな並列領域の最大数を制御するだけで、入れ子並列処理を有効にはしません。入れ子並列を有効にするには、OMP_NESTEDTRUE に設定するか、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 がどのようにスレッドをスケジューリングしているかによって異なります。