commit 7106df9383f21ad2db00d5e2f403cab0485771b5 Author: Alessandro Capotondi Date: Tue Apr 13 23:27:30 2021 +0200 HPC OpenMP Lab 1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c6127b3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,52 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..167a1cf --- /dev/null +++ b/LICENSE @@ -0,0 +1,25 @@ +BSD 2-Clause License + +Copyright (c) 2020, Alessandro Capotondi +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..2f85e86 --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# High Performance Computing Class + +This repo contains the exercises and the tutorials used for Unimore's HPC class [https://dolly.fim.unimore.it/2020/course/view.php?id=145](https://dolly.fim.unimore.it/2020/course/view.php?id=145). + +## Contacts +- **Alessandro Capotondi** <[alessandro.capotondi@unimore.it](mailto:alessandro.capotondi@unimore.it)> +- **Prof. Andrea Marongiu** <[andrea.marongiu@unimore.it](mailto:andrea.marongiu@unimore.it)> + +## Contents + +### OpenMP Exercises +The exercises related to OpenMP programming model can be found in the folder `openmp`. Here the list of currectly available classes: +- `openmp\lab1`: OpenMP basics: *parallel*, *for-loop*, *sections*, and *tasking*. +- `openmp\lab2`: OpenMP advance (accelerator model): *target*, *teams*. +- `openmp\lab3`: OpenMP advance-2 (accelerator model): memory model. + diff --git a/openmp/lab1/.solutions/exercise1.c b/openmp/lab1/.solutions/exercise1.c new file mode 100644 index 0000000..e5ca8b5 --- /dev/null +++ b/openmp/lab1/.solutions/exercise1.c @@ -0,0 +1,56 @@ +/* + * BSD 2-Clause License + * + * Copyright (c) 2020, Alessandro Capotondi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file exercise1.c + * @author Alessandro Capotondi + * @date 27 Mar 2020 + * @brief Exercise 1 + * + * @see https://dolly.fim.unimore.it/2019/course/view.php?id=152 + */ + +#include +#include + +#include "utils.h" + +/** + * @brief EX 1 - Spawn a parallel region from the "print" code + * + * a) Detect number of threads and thread ID (hint: omp_get_num_threads(), omp_get_thread_num()) + * b) Do it for 2, 4, 8, 16 threads + * + * @return void + */ +void exercise() +{ + int tid = 0, nthreads = 0; +#pragma omp parallel num_threads(NTHREADS) + printf("Hello World! I am thread number %d out of %d!\n", omp_get_thread_num(), omp_get_num_threads()); +} diff --git a/openmp/lab1/.solutions/exercise2.c b/openmp/lab1/.solutions/exercise2.c new file mode 100644 index 0000000..506d9a2 --- /dev/null +++ b/openmp/lab1/.solutions/exercise2.c @@ -0,0 +1,89 @@ +/* + * BSD 2-Clause License + * + * Copyright (c) 2020, Alessandro Capotondi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file exercise2.c + * @author Alessandro Capotondi + * @date 27 Mar 2020 + * @brief Exercise 2 + * + * @see https://dolly.fim.unimore.it/2019/course/view.php?id=152 + */ + +#include +#include + +#include "utils.h" + +/** + * @brief EX 2 - Data parallelism: parallel loop ** 1 to 16 THREADS ** + * + * a) Parallelize loop w/static scheduling + * b) Parallelize loop w/dynamic scheduling for chunks = NITER/NTHR (same as static) and 1 (finest granularity) + * c) Same as 2a + 2b, with 1<<20 loop iterations and work(10) + * + * @return void + */ +void exercise() +{ + +#if 0 //2a +#pragma omp parallel for schedule(static) num_threads(NTHREADS) + for(int i=0; i< 1<<10; i++) + { + DEBUG_PRINT("%hu: I am executing iteration %hu!\n", omp_get_thread_num(), i); + work(1<<10); + DEBUG_PRINT("%hu: Done with iteration %hu!\n", omp_get_thread_num(), i); + } +#endif + +#if 0 //2b + int M = (1<<10) / NTHREADS; + //#pragma omp parallel for schedule(dynamic,M) num_threads(NTHREADS) +#pragma omp parallel for schedule(dynamic, 1) num_threads(NTHREADS) + for(int i=0; i< 1<<10; i++) + { + DEBUG_PRINT("%hu: I am executing iteration %hu!\n", omp_get_thread_num(), i); + work(1<<10); + DEBUG_PRINT("%hu: Done with iteration %hu!\n", omp_get_thread_num(), i); + } +#endif + +#if 1 //2c + int M = (1 << 20) / NTHREADS; +//#pragma omp parallel for schedule(static) num_threads(NTHREADS) +//#pragma omp parallel for schedule(dynamic,M) num_threads(NTHREADS) +#pragma omp parallel for schedule(dynamic, 1) num_threads(NTHREADS) + for (int i = 0; i < 1 << 20; i++) + { + DEBUG_PRINT("%hu: I am executing iteration %hu!\n", omp_get_thread_num(), i); + work(10); + DEBUG_PRINT("%hu: Done with iteration %hu!\n", omp_get_thread_num(), i); + } +#endif +} diff --git a/openmp/lab1/.solutions/exercise3.c b/openmp/lab1/.solutions/exercise3.c new file mode 100644 index 0000000..12184b2 --- /dev/null +++ b/openmp/lab1/.solutions/exercise3.c @@ -0,0 +1,60 @@ +/* + * BSD 2-Clause License + * + * Copyright (c) 2020, Alessandro Capotondi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file exercise3.c + * @author Alessandro Capotondi + * @date 27 Mar 2020 + * @brief Exercise 3 + * + * @see https://dolly.fim.unimore.it/2019/course/view.php?id=152 + */ + +#include +#include + +#include "utils.h" + +/** + * @brief EX 3 - Data parallelism: unbalanced parallel loop ** 4 THREADS ** + * + * a) Parallelize loop w/static scheduling + * b) Parallelize loop w/dynamic scheduling, for chunks of 32, 16, 8, 4 ,1 (128 iter) + * + * @return void + */ +void exercise() +{ +//#pragma omp parallel for num_threads(4) schedule(static) +#pragma omp parallel for num_threads(4) schedule(dynamic, M) + for (int i = 0; i < 128; i++) + { + DEBUG_PRINT("%hu: I am executing iteration %hu!\n", omp_get_thread_num(), i); + work((i >> 2) * 1 << 20); + } +} diff --git a/openmp/lab1/.solutions/exercise4.c b/openmp/lab1/.solutions/exercise4.c new file mode 100644 index 0000000..5368c20 --- /dev/null +++ b/openmp/lab1/.solutions/exercise4.c @@ -0,0 +1,64 @@ +/* + * BSD 2-Clause License + * + * Copyright (c) 2020, Alessandro Capotondi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file exercise4.c + * @author Alessandro Capotondi + * @date 27 Mar 2020 + * @brief Exercise 4 + * + * @see https://dolly.fim.unimore.it/2019/course/view.php?id=152 + */ + +#include +#include + +#include "utils.h" + +#if !defined(W) +#define W (1) //1, 10, 100, 1000 +#endif + +/** + * @brief EX 4 - Data parallelism: balanced small parallel loop ** 4 THREADS ** + * + * Parallelize loop with static and dynamic scheduling, for chunks of 32, 16, 8, 4, 1 + * and for W 1, 10, 100, 1000 + * + * @return void + */ +void exercise() +{ +//#pragma omp parallel for num_threads(4) schedule(static) +#pragma omp parallel for num_threads(4) schedule(dynamic, M) + for (int i = 0; i < 1024 * 256; i++) + { + DEBUG_PRINT("%hu: I am executing iteration %hu!\n", omp_get_thread_num(), i); + work(W); + } +} diff --git a/openmp/lab1/.solutions/exercise5.c b/openmp/lab1/.solutions/exercise5.c new file mode 100644 index 0000000..526130d --- /dev/null +++ b/openmp/lab1/.solutions/exercise5.c @@ -0,0 +1,122 @@ +/* + * BSD 2-Clause License + * + * Copyright (c) 2020, Alessandro Capotondi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file exercise5.c + * @author Alessandro Capotondi + * @date 27 Mar 2020 + * @brief Exercise 5 + * + * @see https://dolly.fim.unimore.it/2019/course/view.php?id=152 + */ + +#include +#include + +#include "utils.h" + +#if !defined(W) +#define W (1 << 15) +#endif + +/* Dummy Tasks */ +void task1(); +void task2(); +void task3(); +void task4(); + +/** + * @brief EX 5 - Task Parallelism w/sections + * + * a) Create a parallel region with 4 threads. Use thread IDs to execute + * different WORK functions on different threads. + * b) Create a parallel region with 4 threads. Achieve the same work partitioning + * as a) using SECTIONS. + * + * @return void + */ +void exercise() +{ +#if 0 //5a +#pragma omp parallel num_threads(4) +{ + if(omp_get_thread_num()==0) + task1(); + + if(omp_get_thread_num()==1) + task2(); + + if(omp_get_thread_num()==2) + task3(); + + if(omp_get_thread_num()==3) + task4(); +} +#endif + +#if 1 //5b +#pragma omp parallel sections + { +#pragma omp section + task1(); + +#pragma omp section + task2(); + +#pragma omp section + task3(); + +#pragma omp section + task4(); + } +#endif +} + +void task1() +{ + DEBUG_PRINT("%hu: exec task1!\n", omp_get_thread_num()); + work((1 * W)); +} + +void task2() +{ + DEBUG_PRINT("%hu: exec task2!\n", omp_get_thread_num()); + work((2 * W)); +} + +void task3() +{ + DEBUG_PRINT("%hu: exec task3!\n", omp_get_thread_num()); + work((3 * W)); +} + +void task4() +{ + DEBUG_PRINT("%hu: exec task4!\n", omp_get_thread_num()); + work((4 * W)); +} diff --git a/openmp/lab1/.solutions/exercise6.c b/openmp/lab1/.solutions/exercise6.c new file mode 100644 index 0000000..f2e9d06 --- /dev/null +++ b/openmp/lab1/.solutions/exercise6.c @@ -0,0 +1,106 @@ +/* + * BSD 2-Clause License + * + * Copyright (c) 2020, Alessandro Capotondi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file exercise6.c + * @author Alessandro Capotondi + * @date 27 Mar 2020 + * @brief Exercise 6 + * + * @see https://dolly.fim.unimore.it/2019/course/view.php?id=152 + */ + +#include +#include + +#include "utils.h" + +#if !defined(W) +#define W (1 << 15) +#endif + +/** + * @brief EX 6 - Task Parallelism w/tasks + * + * a) Create a parallel region with 4 threads. Use SINGLE directive to allow only one thread to execute the loop. Use TASK directive to outline tasks. + * b) Change number of iterations to 1024 and W to 1000000. Parallelize with TASK directive. + * c) Same setup as b): parallelize with SINGLE instead of TASK. Comment on ease of coding and performance of the various parallelization schemes. + * + * @return void + */ +void exercise() +{ + unsigned int i; + +#if 0 //Wrong! +#pragma omp parallel num_threads(4) + for(i=0; i<4; i++) + { +#pragma omp single nowait + { + DEBUG_PRINT("%hu: I am executing iteration %hu!\n", omp_get_thread_num(), i); + work((i+1)*W); + } + } + +/* + *./exercise6.exe + * + * + *============================ + *Test - Iteration 0... + *============================ + *0: I am executing iteration 0! + *3: I am executing iteration 3! + *2: I am executing iteration 2! + *1: I am executing iteration 1! + * + * + *============================ + *Test - Iteration 1... + *============================ + *0: I am executing iteration 2! + *3: I am executing iteration 2! + *2: I am executing iteration 3! + *1: I am executing iteration 3! + */ +#endif + +#if 1 +#pragma omp parallel num_threads(4) +#pragma omp single nowait + for (i = 0; i < 4; i++) + { +#pragma omp task + { + DEBUG_PRINT("%hu: I am executing iteration %hu!\n", omp_get_thread_num(), i); + work((i + 1) * W); + } + } +#endif +} diff --git a/openmp/lab1/.solutions/exercise7.c b/openmp/lab1/.solutions/exercise7.c new file mode 100644 index 0000000..9912c3e --- /dev/null +++ b/openmp/lab1/.solutions/exercise7.c @@ -0,0 +1,96 @@ +/* + * BSD 2-Clause License + * + * Copyright (c) 2020, Alessandro Capotondi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file exercise7.c + * @author Alessandro Capotondi + * @date 27 Mar 2020 + * @brief Exercise 7 + * + * @see https://dolly.fim.unimore.it/2019/course/view.php?id=152 + */ + +#include +#include + +#include "utils.h" + +#if !defined(W) +#define W (1000) +#endif + +#if !defined(T) +#define T (20) +#endif + +/** + * @brief EX 7 - Task Parallelism w/tasks + * + * a) Parallelize with TASK directive. + * b) Parallelize with SINGLE NOWAIT directive. + * c) Compare Results with a for loop. + * @return void + */ +void exercise() +{ + unsigned int i; + +#if 1 +#pragma omp parallel +#pragma omp single nowait + for (i = 0; i < 16384; i++) + { +#pragma omp task + { + DEBUG_PRINT("%hu: I am executing iteration %hu!\n", omp_get_thread_num(), i); + work(W); + } + } +#endif + +#if 0 +#pragma omp parallel + for (i = 0; i < 16384; i++) + { +#pragma omp single nowait + { + DEBUG_PRINT("%hu: I am executing iteration %hu!\n", omp_get_thread_num(), i); + work(W); + } + } +#endif + +#if 0 +#pragma omp parallel for + for (i = 0; i < 16384; i++) + { + DEBUG_PRINT("%hu: I am executing iteration %hu!\n", omp_get_thread_num(), i); + work(W); + } +#endif +} diff --git a/openmp/lab1/Makefile b/openmp/lab1/Makefile new file mode 100644 index 0000000..48a61b2 --- /dev/null +++ b/openmp/lab1/Makefile @@ -0,0 +1,28 @@ +ifndef EXERCISE +EXERCISE=exercise1.c +endif + +CC=gcc +LD=ld +OBJDUMP=objdump + +OPT=-O2 -g -fopenmp +CFLAGS=$(OPT) -I. $(EXT_CFLAGS) +LDFLAGS=-lm $(EXT_LDFLAGS) + +SRCS=main.c utils.c +OBJS=$(SRCS:.c=.o) $(EXERCISE:.c=.o) +EXE=$(EXERCISE:.c=.exe) + +$(EXE): $(OBJS) + $(CC) $(CFLAGS) $(OBJS) -o $@ $(LDFLAGS) + +all: $(EXE) + +.PHONY: run clean +run: $(EXE) + ./$(EXE) + +clean: + rm -f $(OBJS) *.o *.exe *.out *~ + diff --git a/openmp/lab1/exercise1.c b/openmp/lab1/exercise1.c new file mode 100644 index 0000000..e127163 --- /dev/null +++ b/openmp/lab1/exercise1.c @@ -0,0 +1,53 @@ +/* + * BSD 2-Clause License + * + * Copyright (c) 2020, Alessandro Capotondi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file exercise1.c + * @author Alessandro Capotondi + * @brief Exercise 1 + * + */ + +#include +#include + +#include "utils.h" + +/** + * @brief EX 1 - Spawn a parallel region from the "print" code + * + * a) Detect number of threads and thread ID (hint: omp_get_num_threads(), omp_get_thread_num()) + * b) Do it for 2, 4, 8, 16 threads + * + * @return void + */ +void exercise() +{ + int tid = 0, nthreads = 0; + printf("Hello World! I am thread number %d out of %d!\n", tid, nthreads); +} diff --git a/openmp/lab1/exercise2.c b/openmp/lab1/exercise2.c new file mode 100644 index 0000000..807f7b6 --- /dev/null +++ b/openmp/lab1/exercise2.c @@ -0,0 +1,58 @@ +/* + * BSD 2-Clause License + * + * Copyright (c) 2020, Alessandro Capotondi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file exercise2.c + * @author Alessandro Capotondi + * @brief Exercise 2 + * + */ + +#include +#include + +#include "utils.h" + +/** + * @brief EX 2 - Data parallelism: parallel loop ** 1 to 16 THREADS ** + * + * a) Parallelize loop w/static scheduling + * b) Parallelize loop w/dynamic scheduling for chunks = NITER/NTHR (same as static) and 1 (finest granularity) + * c) Same as 2a + 2b, with 1<<20 loop iterations and work(10) + * + * @return void + */ +void exercise() +{ + for (int i = 0; i < 1 << 10; i++) + { + DEBUG_PRINT("%hu: I am executing iteration %hu!\n", omp_get_thread_num(), i); + work(1 << 10); + DEBUG_PRINT("%hu: Done with iteration %hu!\n", omp_get_thread_num(), i); + } +} diff --git a/openmp/lab1/exercise3.c b/openmp/lab1/exercise3.c new file mode 100644 index 0000000..16367d3 --- /dev/null +++ b/openmp/lab1/exercise3.c @@ -0,0 +1,56 @@ +/* + * BSD 2-Clause License + * + * Copyright (c) 2020, Alessandro Capotondi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file exercise3.c + * @author Alessandro Capotondi + * @brief Exercise 3 + * + */ + +#include +#include + +#include "utils.h" + +/** + * @brief EX 3 - Data parallelism: unbalanced parallel loop ** 4 THREADS ** + * + * a) Parallelize loop w/static scheduling + * b) Parallelize loop w/dynamic scheduling, for chunks of 32, 16, 8, 4 ,1 (128 iter) + * + * @return void + */ +void exercise() +{ + for (int i = 0; i < 128; i++) + { + DEBUG_PRINT("%hu: I am executing iteration %hu!\n", omp_get_thread_num(), i); + work((i >> 2) * 1 << 20); + } +} diff --git a/openmp/lab1/exercise4.c b/openmp/lab1/exercise4.c new file mode 100644 index 0000000..889d05f --- /dev/null +++ b/openmp/lab1/exercise4.c @@ -0,0 +1,60 @@ +/* + * BSD 2-Clause License + * + * Copyright (c) 2020, Alessandro Capotondi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file exercise4.c + * @author Alessandro Capotondi + * @brief Exercise 4 + * + */ + +#include +#include + +#include "utils.h" + +#if !defined(W) +#define W (1) //1, 10, 100, 1000 +#endif + +/** + * @brief EX 4 - Data parallelism: balanced small parallel loop ** 4 THREADS ** + * + * Parallelize loop with static and dynamic scheduling, for chunks of 32, 16, 8, 4, 1 + * and for W 1, 10, 100, 1000 + * + * @return void + */ +void exercise() +{ + for (int i = 0; i < 1024 * 256; i++) + { + DEBUG_PRINT("%hu: I am executing iteration %hu!\n", omp_get_thread_num(), i); + work(W); + } +} diff --git a/openmp/lab1/exercise5.c b/openmp/lab1/exercise5.c new file mode 100644 index 0000000..ec8ab1f --- /dev/null +++ b/openmp/lab1/exercise5.c @@ -0,0 +1,94 @@ +/* + * BSD 2-Clause License + * + * Copyright (c) 2020, Alessandro Capotondi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file exercise5.c + * @author Alessandro Capotondi + * @brief Exercise 5 + * + */ + +#include +#include + +#include "utils.h" + +#if !defined(W) +#define W (1 << 15) +#endif + +/* Dummy Tasks */ +void task1(); +void task2(); +void task3(); +void task4(); + +/** + * @brief EX 5 - Task Parallelism w/sections + * + * a) Create a parallel region with 4 threads. Use thread IDs to execute + * different WORK functions on different threads. + * b) Create a parallel region with 4 threads. Achieve the same work partitioning + * as a) using SECTIONS. + * + * @return void + */ +void exercise() +{ + task1(); + + task2(); + + task3(); + + task4(); +} + +void task1() +{ + DEBUG_PRINT("%hu: exec task1!\n", omp_get_thread_num()); + work((1 * W)); +} + +void task2() +{ + DEBUG_PRINT("%hu: exec task2!\n", omp_get_thread_num()); + work((2 * W)); +} + +void task3() +{ + DEBUG_PRINT("%hu: exec task3!\n", omp_get_thread_num()); + work((3 * W)); +} + +void task4() +{ + DEBUG_PRINT("%hu: exec task4!\n", omp_get_thread_num()); + work((4 * W)); +} diff --git a/openmp/lab1/exercise6.c b/openmp/lab1/exercise6.c new file mode 100644 index 0000000..6b714f3 --- /dev/null +++ b/openmp/lab1/exercise6.c @@ -0,0 +1,64 @@ +/* + * BSD 2-Clause License + * + * Copyright (c) 2020, Alessandro Capotondi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file exercise6.c + * @author Alessandro Capotondi + * @brief Exercise 6 + * + */ + +#include +#include + +#include "utils.h" + +#if !defined(W) +#define W (1 << 15) +#endif + +/** + * @brief EX 6 - Task Parallelism w/tasks + * + * Distribute workload among 4 threads using task directive + * Same program as EX 5, but we had to manually unroll the loop to use sections + * + * a) Create a parallel region with 4 threads. Use SINGLE directive to allow + * only one thread to execute the loop. Use TASK directive to outline tasks. + * b) Parallelize using SECTION + * + * @return void + */ +void exercise() +{ + for (int i = 0; i < 4; i++) + { + DEBUG_PRINT("%hu: I am executing iteration %hu!\n", omp_get_thread_num(), i); + work((i + 1) * W); + } +} diff --git a/openmp/lab1/exercise7.c b/openmp/lab1/exercise7.c new file mode 100644 index 0000000..4870c6d --- /dev/null +++ b/openmp/lab1/exercise7.c @@ -0,0 +1,66 @@ +/* + * BSD 2-Clause License + * + * Copyright (c) 2020, Alessandro Capotondi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file exercise7.c + * @author Alessandro Capotondi + * @brief Exercise 7 + * + */ + +#include +#include + +#include "utils.h" + +#if !defined(W) +#define W (1000) +#endif + +#if !defined(T) +#define T (20) +#endif + +/** + * @brief EX 7 - Task Parallelism w/tasks + * + * a) Parallelize with TASK directive. + * b) Parallelize the loop with for directive + * + * @return void + */ +void exercise() +{ + unsigned int i; + + for (i = 0; i < 16384; i++) + { + DEBUG_PRINT("%hu: I am executing iteration %hu!\n", omp_get_thread_num(), i); + work(W); + } +} diff --git a/openmp/lab1/main.c b/openmp/lab1/main.c new file mode 100644 index 0000000..958173e --- /dev/null +++ b/openmp/lab1/main.c @@ -0,0 +1,64 @@ +/* + * BSD 2-Clause License + * + * Copyright (c) 2020, Alessandro Capotondi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file main.c + * @author Alessandro Capotondi + * @brief Main program of OpenMP Lab #1 + */ + +#include +#include "utils.h" + +#if !defined(ITERS) +#define ITERS (4) +#endif + +/* Hook to the exercise function */ +extern void exercise(); + +int +main(int argc, char** argv) +{ + for(int i=0; i +#include +#include +#include +#include + +#include "utils.h" + +#define MAX_ITERATIONS 100 +static struct timespec timestampA, timestampB; +static unsigned long long statistics[MAX_ITERATIONS]; +static int iterations = 0; + +static unsigned long long __diff_ns(struct timespec start, struct timespec end) +{ + struct timespec temp; + if ((end.tv_nsec - start.tv_nsec) < 0) + { + temp.tv_sec = end.tv_sec - start.tv_sec - 1; + temp.tv_nsec = 1000000000ULL + end.tv_nsec - start.tv_nsec; + } + else + { + temp.tv_sec = end.tv_sec - start.tv_sec; + temp.tv_nsec = end.tv_nsec - start.tv_nsec; + } + + return temp.tv_nsec + temp.tv_sec * 1000000000ULL; +} + +void start_timer() +{ + asm volatile("" :: + : "memory"); + clock_gettime(CLOCK_MONOTONIC_RAW, ×tampA); + asm volatile("" :: + : "memory"); +} + +void stop_timer() +{ + unsigned long long elapsed = 0ULL; + asm volatile("" :: + : "memory"); + clock_gettime(CLOCK_MONOTONIC_RAW, ×tampB); + asm volatile("" :: + : "memory"); +} + +unsigned long long elapsed_ns() +{ + return __diff_ns(timestampA, timestampB); +} + +void start_stats() +{ + start_timer(); +} + +void collect_stats() +{ + assert(iterations < MAX_ITERATIONS); + stop_timer(); + statistics[iterations++] = elapsed_ns(timestampA, timestampB); +} + +void print_stats() +{ + unsigned long long min = ULLONG_MAX; + unsigned long long max = 0LL; + double average = 0.0; + double std_deviation = 0.0; + double sum = 0.0; + + /* Compute the sum of all elements */ + for (int i = 0; i < iterations; i++) + { + if (statistics[i] > max) + max = statistics[i]; + if (statistics[i] < min) + min = statistics[i]; + sum = sum + statistics[i] / 1E6; + } + average = sum / (double)iterations; + + /* Compute variance and standard deviation */ + for (int i = 0; i < iterations; i++) + { + sum = sum + pow((statistics[i] / 1E6 - average), 2); + } + std_deviation = sqrt(sum / (double)iterations); + + printf("AvgTime\tMinTime\tMaxTime\tStdDev\n"); + printf("%.4f ms\t%.4f ms\t%.4f ms\t%.4f\n", (double)average, (double)min / 1E6, (double)max / 1E6, (double)std_deviation); +} + +#if defined(__GNUC__) +#pragma GCC push_options +#pragma GCC optimize("O0") +void work(unsigned long num) +#else +void work __attribute__((optnone)) (unsigned long num) +#endif +{ + volatile int cnt = 0; + for (int i = 0; i < num; i++) + cnt += i; +} +#if defined(__GNUC__) +#pragma GCC pop_options +#endif diff --git a/openmp/lab1/utils.h b/openmp/lab1/utils.h new file mode 100644 index 0000000..ac236fe --- /dev/null +++ b/openmp/lab1/utils.h @@ -0,0 +1,156 @@ +/* + * BSD 2-Clause License + * + * Copyright (c) 2020, Alessandro Capotondi + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file utils.h + * @author Alessandro Capotondi + * @brief File containing utilities functions for HPC Unimore Class + * + * The header define time functions and dummy workload used on the example tests. + */ + +#ifndef __UTILS_H__ +#define __UTILS_H__ + +#include + +#if defined(VERBOSE) +#define DEBUG_PRINT(x, ...) printf((x), ##__VA_ARGS__) +#else +#define DEBUG_PRINT(x, ...) +#endif + +#if !defined(NTHREADS) +#define NTHREADS (4) +#endif + +/** + * @brief The function set the timestampA + * + * The function is used to measure elapsed time between two execution points. + * The function start_timer() sets the starting point timestamp, while the function + * stop_timer() sets the termination timestamp. The elapsed time, expressed in nanoseconds, + * between the two points can be retrieved using the function elapsed_ns(). + * + * Example usage: + * @code + * start_timer(); // Point A + * //SOME CODE HERE + * stop_timer(); // Point B + * printf("Elapsed time = %llu ns\n", elapsed_ns())); //Elapsed time between A and B + * //SOME OTHER CODE HERE + * stop_timer(); // Point C + * printf("Elapsed time = %llu ns\n", elapsed_ns())); //Elapsed time between A and C + * @endcode + * + * @return void + * @see start_timer() + * @see stop_timer() + * @see elapsed_ns() + */ +void start_timer(); + +/** + * @brief The function set the second timestamps + * + * The function is used to measure elapsed time between two execution points. + * The function start_timer() sets the starting point timestamp, while the function + * stop_timer() returns the elapsed time, expressed in nanoseconds between the last call + * of start_timer() and the current execution point. + * + * Example usage: + * @code + * start_timer(); // Point A + * //SOME CODE HERE + * stop_timer(); // Point B + * printf("Elapsed time = %llu ns\n", elapsed_ns())); //Elapsed time between A and B + * //SOME OTHER CODE HERE + * stop_timer(); // Point C + * printf("Elapsed time = %llu ns\n", elapsed_ns())); //Elapsed time between A and C + * @endcode + * + * @return void + * @see start_timer() + * @see stop_timer() + * @see elapsed_ns() + */ +void stop_timer(); + +/** + * @brief Elapsed nano seconds between start_timer() and stop_timer(). + * + * @return Elapsed nano seconds + * @see start_timer() + * @see stop_timer() + */ +unsigned long long elapsed_ns(); + +/** + * @brief The function init the starting point of stat measurement. + * + * The function is similar to start_timer(). + * + * @return void + * @see start_timer + */ +void start_stats(); + +/** + * @brief The function collects the elapsed time between the current exeuction point and the + * last call of start_stats(). + * + * @return void + */ +void collect_stats(); + +/** + * @brief The function display the collected statistics. + * @return void + */ +void print_stats(); + +/** + * @brief The dummy work function + * + * The function is used to emulate some usefull workload. + * + * @param @num work duration in terms of loop iterations. + * @return void + */ +#if defined(__GNUC__) +#pragma GCC push_options +#pragma GCC optimize("O0") +void work(unsigned long num); +#else +void work __attribute__((optnone)) (unsigned long num); +#endif +#if defined(__GNUC__) +#pragma GCC pop_options +#endif + +#endif /*__UTILS_H__*/