Oracle Solaris Studio 12.2:OpenMP API 用户指南

5.4 任务处理示例

以下 C/C++ 程序说明为什么 OpenMP 任务和 taskwait 指令可用于递归计算斐波纳契数。

在该示例中,parallel 指令指示一个将由四个线程执行的并行区域。在并行构造中,single 指令用于指示只有其中一个线程将执行调用 fib(n)print 语句。

fib(n) 的调用会生成两个任务(由 task 指令指示)。其中一个任务计算 fib(n-1),另一个任务计算 fib(n-2),将返回值加在一起即可产生由 fib(n) 返回的值。对 fib(n-1)fib(n-2) 的每个调用反过来又会生成两个任务。将会以递归方式生成任务,直到传递到 fib() 的参数小于 2。

taskwait 指令可确保在调用 fib() 的过程中生成的两个任务(即计算 ij 的任务)在对 fib() 的调用返回之前已完成。

请注意,虽然只有一个线程执行 single 指令(因而也只有一个线程对 fib(n) 进行调用),但是所有四个线程都将参与执行生成的任务。

该示例是使用 Solaris Studio 12.2 C++ 编译器编译的。


示例 5–1 任务处理示例:计算斐波纳契数


#include <stdio.h>
#include <omp.h>
int fib(int n)
{
  int i, j;
  if (n<2)
    return n;
  else
    {
       #pragma omp task shared(i) firstprivate(n)
       i=fib(n-1);

       #pragma omp task shared(j) firstprivate(n)
       j=fib(n-2);

       #pragma omp taskwait
       return i+j;
    }
}

int main()
{
  int n = 10;

  omp_set_dynamic(0);
  omp_set_num_threads(4);

  #pragma omp parallel shared(n)
  {
    #pragma omp single
    printf ("fib(%d) = %d\n", n, fib(n));
  }
}


% CC -xopenmp -xO3 task_example.cc
% a.out
fib(10) = 55