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

印刷ビューの終了

更新: 2014 年 12 月
 
 

4.6 taskwait および taskgroup を使用したタスクの同期化

taskwait または taskgroup ディレクティブを使用してタスクを同期化できます。

スレッドが taskwait 構文を検出すると、現在のタスクは、それが taskwait 領域の前に生成したすべての子タスクの実行が完了するまで中断されます。

スレッドが taskgroup 構文を検出すると、taskgroup 領域の実行が開始されます。taskgroup 領域の終わりで、現在のタスクは、taskgroup 領域でそのタスクが生成したすべての子タスクとそのすべての子孫タスクの実行が完了するまで中断されます。

taskwaittaskgroup の違いに注意してください。taskwait を使用すると、現在のタスクはその子タスクのみを待機します。taskgroup を使用すると、現在のタスクは、taskgroup 領域で生成された子タスクだけでなく、その子タスクのすべての子孫も待機します。次の 2 つの例は、その違いを示しています。

使用例 4-5  taskwait の例
% cat -n taskwait.c
     1  #include <omp.h>
     2  #include <stdio.h>
     3  #include <unistd.h>
     4
     5  int main()
     6  {
     7    #pragma omp parallel
     8    #pragma omp single
     9    {
    10      #pragma omp task
    11      {
    12        #pragma omp critical
    13        printf ("Task 1\n");
    14
    15        #pragma omp task
    16        {
    17          sleep(1);
    18          #pragma omp critical
    19          printf ("Task 2\n");
    20        }
    21      }
    22
    23      #pragma omp taskwait
    24
    25      #pragma omp task
    26      {
    27        #pragma omp critical
    28        printf ("Task 3\n");
    29      }
    30    }
    31
    32    return 0;
    33  }
使用例 4-6  taskgroup の例
% cat -n taskgroup.c
     1  #include <omp.h>
     2  #include <stdio.h>
     3  #include <unistd.h>
     4
     5  int main()
     6  {
     7    #pragma omp parallel
     8    #pragma omp single
     9    {
    10      #pragma omp taskgroup
    11      {
    12        #pragma omp task
    13        {
    14          #pragma omp critical
    15          printf ("Task 1\n");
    16
    17          #pragma omp task
    18          {
    19            sleep(1);
    20            #pragma omp critical
    21            printf ("Task 2\n");
    22          }
    23        }
    24      } /* end taskgroup */
    25
    26      #pragma omp task
    27      {
    28        #pragma omp critical
    29        printf ("Task 3\n");
    30      }
    31    }
    32
    33    return 0;
    34  }

taskwait.ctaskgroup.c のソースコードはほとんど同じですが、taskwait.c の 23 行目に taskwait ディレクティブがあるのに対し、taskgroup.c の 10 行目には Task 1 と Task 2 を含む taskgroup 構文があります。どちらのプログラムでも、taskwait および taskgroup ディレクティブは Task 1 と Task 3 の実行を同期化しています。両者の違いは、それらが Task 2 と Task 3 の実行を同期化しているかどうかにあります。

taskwait.c の場合、Task 2 は、taskwait 領域がバインドされている並列領域によって生成される暗黙的タスクの子タスクではありません。そのため、taskwait 領域の終わりまでに Task 2 を終了させる必要はありません。Task 3 は Task 2 の完了前にスケジュールできます。

taskgroup.c の場合、Task 2 は、taskgroup 領域で生成される Task 1 の子タスクです。そのため、taskgroup 領域の終わりまでに Task 2 を終了させてから、Task 3 の検出およびスケジュールを行う必要があります。