Oracle® Developer Studio 12.5:OpenMP API 用户指南

退出打印视图

更新时间: 2016 年 7 月
 
 

4.6 使用 taskwaittaskgroup 同步任务

您可以使用 taskwaittaskgroup 指令同步任务。

当线程遇到 taskwait 构造时,当前任务会暂停,直到它在 taskwait 区域前生成的所有子任务均已完成执行为止。

当线程遇到 taskgroup 构造时,它将开始执行 taskgroup 区域。在 taskgroup 区域末尾,当前任务暂停,直到它在 taskgroup 区域中生成的所有子任务及其所有子孙任务均已完成执行为止。

请注意 taskwaittaskgroup 之间的不同。使用 taskwait,当前任务仅等待其子任务。使用 taskgroup,当前任务不仅等待在 taskgroup 中生成的子任务,还等待这些子任务的所有子孙任务。下面两个示例介绍了二者之间的差异。

示例 7  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  }
示例 8  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 行有包含任务 1 和任务 2 的 taskgroup 构造。在这两个程序中,taskwaittaskgroup 指令同步任务 1 和任务 3 的执行;不同之处在于它们是否同步任务 2 和任务 3 的执行。

在使用 taskwait.c 的情况下,任务 2 不是 taskwait 区域绑定到的并行区域所生成的隐式任务的子任务。因此,任务 2 不必在 taskwait 区域末尾完成。可以在完成任务 2 之前调度任务 3。

对于 taskgroup.c,任务 2 是任务 1 的子任务,该任务是在 taskgroup 区域中生成的。因此,任务 2 必须在 taskgroup 区域末尾完成,然后才能遇到和调度任务 3。