The following C/C++ program illustrates how the OpenMP task and taskwait directives can be used to compute Fibonacci numbers recursively.
In the example, the parallel directive denotes a parallel region which will be executed by four threads. In the parallel construct, the single directive is used to indicate that only one of the threads will execute the print statement that calls fib(n).
The call to fib(n) generates two tasks, indicated by the task directive. One of the tasks computes fib(n-1) and the other computes fib(n-2), and the return values are added together to produce the value returned by fib(n). Each of the calls to fib(n-1) and fib(n-2) will in turn generate two tasks. Tasks will be recursively generated until the argument passed to fib() is less than 2.
The taskwait directive ensures that the two tasks generated in an invocation of fib() are completed (that is. the tasks compute i and j) before that invocation of fib() returns.
Note that although only one thread executes the single directive and hence the call to fib(n), all four threads will participate in executing the tasks generated.
The example is compiled using the Sun Studio 12 Update 1 C++ compiler.
#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 |