Oracle® Solaris Studio 12.4: OpenMP API ユーザーズガイド

印刷ビューの終了

更新: 2014 年 12 月
 
 

4.5 タスクの依存関係

OpenMP 4.0 仕様では、task ディレクティブの depend 節を紹介しています。これは、タスクのスケジューリングに対する追加の制約を強制するものです。これらの制約では、兄弟タスク間の依存関係のみを確立します。兄弟タスクとは、同じタスク領域の子タスクである OpenMP タスクです。

in 依存関係タイプを depend 節で指定すると、生成されたタスクは、out または inout 依存関係タイプリスト内の少なくともいずれか 1 つのリスト項目を参照する、以前に生成されたすべての兄弟タスクの従属タスクとなります。out または inout 依存関係タイプを depend 節で指定すると、生成されたタスクは、inout、または inout 依存関係タイプリスト内の少なくともいずれか 1 つのリスト項目を参照する、以前に生成されたすべての兄弟タスクの従属タスクとなります。

次の例はタスクの依存関係を示しています。

使用例 4-3  兄弟タスクのみを同期化する depend 節の例
% cat -n task_depend_01.c
     1  #include <omp.h>
     2  #include <stdio.h>
     3  #include <unistd.h>
     4
     5  int main()
     6  {
     7      int a,b,c;
     8
     9      #pragma omp parallel
    10      {
    11          #pragma omp master
    12          {
    13              #pragma omp task depend(out:a)
    14              {
    15                  #pragma omp critical
    16                  printf ("Task 1\n");
    17              }
    18
    19              #pragma omp task depend(out:b)
    20              {
    21                  #pragma omp critical
    22                  printf ("Task 2\n");
    23              }
    24
    25              #pragma omp task depend(in:a,b) depend(out:c)
    26              {
    27                  printf ("Task 3\n");
    28              }
    29
    30              #pragma omp task depend(in:c)
    31              {
    32                  printf ("Task 4\n");
    33              }
    34          }
    35          if (omp_get_thread_num () == 1)
    36            sleep(1);
    37      }
    38      return 0;
    39  }

% cc -xopenmp -O3 task_depend_01.c
% a.out
Task 2
Task 1
Task 3
Task 4

% a.out
Task 1
Task 2
Task 3
Task 4

この例では、Task 1、2、3、および 4 はすべて同じ暗黙的タスク領域の子タスクであるため、それらは兄弟タスクです。a 引数への依存関係が depend 節に指定されているため、Task 3 は Task 1 と 2 の従属タスクです。したがって、Task 1 と 2 の両方が完了するまで、Task 3 をスケジュールすることはできません。同様に、Task 4 は Task 3 の従属タスクであるため、Task 3 が完了するまで Task 4 をスケジュールすることはできません。

depend 節は兄弟タスクのみを同期化することに注意してください。次の例 (Example 4–4) は、depend 節が兄弟以外のタスクに影響を及ぼさないケースを示しています。

使用例 4-4  兄弟以外のタスクに影響を及ぼさない depend 節の例
% cat -n task_depend_02.c
     1  #include <omp.h>
     2  #include <stdio.h>
     3  #include <unistd.h>
     4
     5  int main()
     6  {
     7      int a,b,c;
     8
     9      #pragma omp parallel
    10      {
    11          #pragma omp master
    12          {
    13              #pragma omp task depend(out:a)
    14              {
    15                  #pragma omp critical
    16                  printf ("Task 1\n");
    17              }
    18
    19              #pragma omp task depend(out:b)
    20              {
    21                  #pragma omp critical
    22                  printf ("Task 2\n");
    23
    24                  #pragma omp task depend(out:a,b,c)
    25                  {
    26                    sleep(1);
    27                    #pragma omp critical
    28                    printf ("Task 5\n");
    29                  }
    30              }
    31
    32              #pragma omp task depend(in:a,b) depend(out:c)
    33              {
    34                  printf ("Task 3\n");
    35              }
    36
    37              #pragma omp task depend(in:c)
    38              {
    39                  printf ("Task 4\n");
    40              }
    41          }
    42          if (omp_get_thread_num () == 1)
    43            sleep(1);
    44      }
    45      return 0;
    46  }

% cc -xopenmp -O3 task_depend_02.c
% a.out
Task 1
Task 2
Task 3
Task 4
Task 5

上記の例では、Task 5 は Task 2 の子タスクであり、Task 1、2、3、または 4 の兄弟ではありません。このため、depend 節が同じ変数 (abc) を参照しているにもかかわらず、Task 5 と Task 1、2、3、または 4 の間に依存関係はありません。