diff --git a/COPYING b/COPYING new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/meson.build b/meson.build index a994b3aab6a74e0781e602b656823133ca7fbe18..27dd1dc4fb96a822b1d36d6dcb7c05cebc4a2e4a 100644 --- a/meson.build +++ b/meson.build @@ -6,6 +6,7 @@ libm = cc.find_library('m') utils = library('utils', 'utils.c') glib_dep = dependency('glib-2.0', version: '>= 2.16') +openmp_dep = dependency('openmp') executable('add', 'add.c') executable('add2', 'add2.c', link_with: utils) @@ -30,4 +31,5 @@ executable('write', 'write.c') subdir('array') subdir('hashtable') subdir('list') -subdir('winter') \ No newline at end of file +subdir('openmp') +subdir('winter') diff --git a/openmp/meson.build b/openmp/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..f154584eee6fb06503ca62cd1cc3de39d8b38404 --- /dev/null +++ b/openmp/meson.build @@ -0,0 +1,7 @@ +cc = meson.get_compiler('c') +libm = cc.find_library('m') + +executable('pi', 'pi.c', dependencies: [openmp_dep, libm]) +executable('simd', 'simd.c', dependencies: openmp_dep) +executable('taylor', 'taylor.c', dependencies: openmp_dep) +executable('threads', 'threads.c', dependencies: openmp_dep) diff --git a/openmp/pi.c b/openmp/pi.c new file mode 100644 index 0000000000000000000000000000000000000000..6d2384f848724a5d7790b35dc26cec0435d64d3b --- /dev/null +++ b/openmp/pi.c @@ -0,0 +1,48 @@ +#include <stdio.h> +#include <stdlib.h> +#include <tgmath.h> +#include <time.h> + +#include <omp.h> + +#define NUM_STEPS (10 * 1000 * 1000) + +static double +random_coord (void) +{ + return 2 * ((double) rand () / RAND_MAX) - 1; +} + +static double +pi_func (size_t n) +{ + size_t inside = 0; + + printf ("Started\n"); + + srand (time (NULL)); + + #pragma omp parallel for reduction(+:inside) + for (size_t i = 0; i < n; i++) + { + double x = random_coord (); + double y = random_coord (); + double r2 = pow (x, 2) + pow (y, 2); + if (r2 <= 1.0) + inside++; + } + + return (4 * ((double) inside / n)); +} + +int +main (void) +{ + double start = omp_get_wtime (); + double pi = pi_func (NUM_STEPS); + double stop = omp_get_wtime (); + + printf ("pi = %lf, took %.3f seconds\n", pi, stop-start); + + return 0; +} diff --git a/openmp/simd.c b/openmp/simd.c new file mode 100644 index 0000000000000000000000000000000000000000..ae48262712b1df82823da2b4f9ee198b070a3354 --- /dev/null +++ b/openmp/simd.c @@ -0,0 +1,66 @@ +#include <stdio.h> + +static const int N = 32; + +#pragma omp declare simd uniform(fact) +double +add1 (double a, + double b, + double fact) +{ + return a + b + fact; +} + +#pragma omp declare simd uniform(a,b,fact) linear(i:1) +double +add2 (double *a, + double *b, + int i, + double fact) +{ + return a[i] + b[i] + fact; +} + +#pragma omp declare simd uniform(fact) linear(a,b:1) +double +add3 (double *a, + double *b, + double fact) +{ + return *a + *b + fact; +} + +void +work (double *a, + double *b, + int n) +{ + double tmp; + + #pragma omp simd private(tmp) + for (int i = 0; i < n; i++) + { + tmp = add1 (a[i], b[i], 1.0); + a[i] = add2 (a, b, i, 1.0 + tmp); + a[i] = add3 (&a[i], &b[i], 1.0); + } +} + +int +main (void) +{ + double a[N], b[N]; + + for (int i = 0; i < N; i++) + { + a[i] = i; + b[i] = N - i; + } + + work (a, b, N); + + for (int i = 0; i < N; i++) + printf ("%d %f\n", i, a[i]); + + return 0; +} diff --git a/openmp/taylor.c b/openmp/taylor.c new file mode 100644 index 0000000000000000000000000000000000000000..28df1ddd083c1c2f3f7a68c455449a1391b2c18b --- /dev/null +++ b/openmp/taylor.c @@ -0,0 +1,65 @@ +#include <stdio.h> + +#include <omp.h> + +static const size_t NUM_STEPS = 1e9; + +static double +e_func (size_t n) +{ + double e = 1; + double factorial = 1; + + printf ("e started\n"); + + #pragma omp parallel for shared(factorial) reduction(+:e) + for (size_t i = 1; i < n; i++) + { + factorial *= i; + e += 1.0 / factorial; + } + + return e; +} + +static double +pi_func (size_t n) +{ + double pi = 0; + + printf ("pi started\n"); + + for (size_t i = 0; i < n; i++) + { + pi += 1.0 / (i * 4.0 + 1.0); + pi -= 1.0 / (i * 4.0 + 3.0); + } + + pi *= 4.0; + + return pi; +} + +int +main (void) +{ + #pragma omp parallel sections + { + #pragma omp section + { + double start = omp_get_wtime (); + double e = e_func (NUM_STEPS); + double stop = omp_get_wtime (); + printf ("e = %lf, took %.3f seconds\n", e, stop-start); + } + #pragma omp section + { + double start = omp_get_wtime (); + double pi = pi_func (NUM_STEPS); + double stop = omp_get_wtime (); + printf ("pi = %lf, took %.3f seconds\n", pi, stop-start); + } + } + + return 0; +} diff --git a/openmp/threads.c b/openmp/threads.c new file mode 100644 index 0000000000000000000000000000000000000000..7963ce78be6209626d6e36119aadc164c1145913 --- /dev/null +++ b/openmp/threads.c @@ -0,0 +1,20 @@ +#include <stdio.h> + +#include <omp.h> + +int +main (void) +{ + #pragma omp parallel + { + int tid = omp_get_thread_num (); + printf ("Hello world from thread %d\n", tid); + + #pragma omp master + { + int nthreads = omp_get_max_threads (); + int procs = omp_get_num_procs (); + printf ("%d threads and %d processors\n", nthreads, procs); + } + } +}