From dbfa26936719275598235921d50456f9b8eb8387 Mon Sep 17 00:00:00 2001 From: Bruce Cowan <bruce@bcowan.me.uk> Date: Mon, 24 Sep 2018 10:46:03 +0100 Subject: [PATCH] Add OpenMP and licence Must have forgotten in the last commit, I'm stupid --- COPYING | 0 meson.build | 4 ++- openmp/meson.build | 7 +++++ openmp/pi.c | 48 +++++++++++++++++++++++++++++++++ openmp/simd.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++ openmp/taylor.c | 65 +++++++++++++++++++++++++++++++++++++++++++++ openmp/threads.c | 20 ++++++++++++++ 7 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 COPYING create mode 100644 openmp/meson.build create mode 100644 openmp/pi.c create mode 100644 openmp/simd.c create mode 100644 openmp/taylor.c create mode 100644 openmp/threads.c diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..e69de29 diff --git a/meson.build b/meson.build index a994b3a..27dd1dc 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 0000000..f154584 --- /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 0000000..6d2384f --- /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 0000000..ae48262 --- /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 0000000..28df1dd --- /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 0000000..7963ce7 --- /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); + } + } +} -- GitLab