uni

University stuff
git clone git://git.margiolis.net/uni.git
Log | Files | Refs | README | LICENSE

commit 328337343bb5137b66dcec935617bceaaaf990a7
parent 3143d9955c248ea40b5a676e09ac453136e1cbde
Author: Christos Margiolis <christos@margiolis.net>
Date:   Thu, 12 Jan 2023 16:25:20 +0200

ex2a done

Diffstat:
Mc_parallel_systems/ex2/Makefile | 3+--
Mc_parallel_systems/ex2/ex2a.c | 121+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
2 files changed, 85 insertions(+), 39 deletions(-)

diff --git a/c_parallel_systems/ex2/Makefile b/c_parallel_systems/ex2/Makefile @@ -1,6 +1,5 @@ all: cc ex2a.c -fopenmp -lomp -o ex2a - cc ex2b.c -fopenmp -lomp -o ex2b clean: - rm -f ex2a ex2b *.core + rm -f ex2a *.core diff --git a/c_parallel_systems/ex2/ex2a.c b/c_parallel_systems/ex2/ex2a.c @@ -1,38 +1,14 @@ #include <err.h> -#include <stdarg.h> #include <stdio.h> #include <stdlib.h> +#include <time.h> #include <omp.h> -static int safe_input(const char *, ...); static void pretty_print(int *, int, const char *); - -static int -safe_input(const char *fmt, ...) -{ - va_list args; - char buf[48]; - int n, rc; - - /* Collect the arguments into a buffer. */ - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - - /* - * The following loop keeps asking for input as long as the current - * input wasn't correct. In this case "incorrect" input means anything - * other than digits. - */ - do { - printf("\r%s", buf); - rc = scanf("%d", &n); - (void)getchar(); - } while (rc != 1); - - return (n); -} +static int cmpfunc(const void *, const void *); +static void merge(int *, int *, int *, int *, int *); +static void multisort(int *, int *, int); /* * Print the contents of a 2D array like: @@ -50,33 +26,104 @@ pretty_print(int *arr, int n, const char *name) printf("]\n"); } +/* + * Passed to qsort(3). + */ +static int +cmpfunc(const void *a, const void *b) +{ + return (*(int *)a - *(int *)b); +} + +static void +merge(int *a, int *enda, int *b, int *endb, int *res) +{ + while (a <= enda && b <= endb) { + if (*a < *b) + *res++ = *a++; + else + *res++ = *b++; + } + while (a <= enda) + *res++ = *a++; + while (b <= endb) + *res++ = *b++; +} + +static void +multisort(int *arr, int *space, int n) +{ + int quarter, *sta, *spa, *stb, *spb, *stc, *spc, *std, *spd; + + if ((quarter = n / 4) < 4) + qsort(arr, n, sizeof(int), cmpfunc); + else { + /* Split the array into 4 quarters. */ + sta = arr; + spa = space; + stb = sta + quarter; + spb = spa + quarter; + stc = stb + quarter; + spc = spb + quarter; + std = stc + quarter; + spd = spc + quarter; +#pragma omp task + multisort(sta, spa, quarter); +#pragma omp task + multisort(stb, spb, quarter); +#pragma omp task + multisort(stc, spc, quarter); +#pragma omp task + multisort(std, spd, n - 3 * quarter); + /* Wait for the tasks above to finish. */ +#pragma omp taskwait +#pragma omp task + /* Merge A and B into SpaceA */ + merge(sta, sta + quarter - 1, stb, stb + quarter - 1, spa); +#pragma omp task + /* Merge C and D into SpaceC */ + merge(stc, stc + quarter - 1, std, arr + n - 1, spc); +#pragma omp taskwait + /* Merge the two resulting couples (SpaceA and SpaceC). */ + merge(spa, spc - 1, spc, space + n - 1, arr); + } +} + int main(int argc, char *argv[]) { - int *a, i, n, ntd; + int *a, *space, i, n, ntd; double start, end; - ntd = safe_input("threads: ", 0); + if (argc < 3) { + fprintf(stderr, "usage: %s nthreads n\n", getprogname()); + return (1); + } + if ((ntd = atoi(argv[1])) < 1) + err(1, "can't use nthreads n < 1"); + if ((n = atoi(argv[2])) < 1) + err(1, "can't use n < 1"); + + srand(time(NULL)); omp_set_num_threads(ntd); - n = safe_input("n: ", 0); if ((a = malloc(n * sizeof(int))) == NULL) err(1, "malloc"); + if ((space = malloc(n * sizeof(int))) == NULL) + err(1, "malloc"); for (i = 0; i < n; i++) - a[i] = safe_input("a[%d]: ", i); + a[i] = rand() % 100; start = omp_get_wtime(); - /* TODO */ - <++> + pretty_print(a, n, "A_unsorted"); + multisort(a, space, n); + pretty_print(a, n, "A_multisort"); end = omp_get_wtime(); printf("Total time: %f seconds\n", end - start); - pretty_print(a, n, "A_unsorted"); - pretty_print(a, n, "A_multisort"); - free(a); return (0);