Skip to content

Commit fdc568f

Browse files
committed
Tasking: example optimization
1 parent 369f8ec commit fdc568f

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

docs/tasks.rst

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2044,6 +2044,92 @@ The list contains variables, which may include array sections.
20442044
return 0;
20452045
}
20462046
2047+
.. challenge::
2048+
2049+
In the previous implementation of the Fibonacci generator code, we noticed that the values of
2050+
Fibonacci numbers are computed several times during recursion. This situation can be avoided by using
2051+
task dependencies, as in the following graph which shows the dependencies that we can create explicitl
2052+
for the Fibonacci number 6:
2053+
2054+
2055+
.. code-block:: text
2056+
2057+
fib[6]
2058+
depends on fib[5] and fib[4]
2059+
|
2060+
v
2061+
fib[5]
2062+
depends on fib[4] and fib[3]
2063+
|
2064+
v
2065+
fib[4]
2066+
depends on fib[3] and fib[2]
2067+
/ \
2068+
v v
2069+
fib[3] fib[2]
2070+
depends on fib[2] and fib[1] depends on fib[1] and fib[0]
2071+
| \ | \
2072+
v v v v
2073+
fib[2] fib[1] fib[1] fib[0]
2074+
depends on fib[1] and fib[0]
2075+
| \
2076+
v v
2077+
fib[1] fib[0]
2078+
2079+
2080+
Base values:
2081+
fib[1] = 1
2082+
fib[0] = 0
2083+
2084+
Write a code for the Fibonacci numbers generator but now using task dependencies.
2085+
2086+
.. solution::
2087+
2088+
.. code-block:: c
2089+
:linenos:
2090+
2091+
// On cluster Kebnekaise
2092+
// ml foss
2093+
// export OMP_NUM_THREADS=4
2094+
// gcc -O3 -march=native -fopenmp -o test.x fibonacci_task_dependencies.c -lm
2095+
#include <stdio.h>
2096+
#include <stdlib.h>
2097+
#include <omp.h>
2098+
2099+
int main(int argc, char* argv[]) {
2100+
int n = (argc > 1) ? atoi(argv[1]) : 40;
2101+
unsigned long long *fib = malloc((n+1) * sizeof(unsigned long long));
2102+
2103+
#pragma omp parallel
2104+
{
2105+
#pragma omp single
2106+
{
2107+
// Base cases
2108+
#pragma omp task depend(out: fib[0])
2109+
{ fib[0] = 0; }
2110+
2111+
#pragma omp task depend(out: fib[1])
2112+
{ fib[1] = 1; }
2113+
2114+
// Create tasks for F(2) .. F(n)
2115+
for (int i = 2; i <= n; i++) {
2116+
#pragma omp task depend(in: fib[i-1], fib[i-2]) depend(out: fib[i])
2117+
{
2118+
fib[i] = fib[i-1] + fib[i-2];
2119+
}
2120+
}
2121+
2122+
// Wait until fib[n] is available
2123+
#pragma omp taskwait
2124+
printf("fib(%d) = %llu\n", n, fib[n]);
2125+
}
2126+
}
2127+
2128+
free(fib);
2129+
return 0;
2130+
}
2131+
2132+
20472133
20482134
20492135
taskloop Construct (OpenMP 4.5)

0 commit comments

Comments
 (0)