以下 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