以下 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() 的过程中生成的两个任务(即计算 i 和 j 的任务)在对 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