Κατανεμημένα και Παράλληλα Συστήματα (εργαστήριο) Παραδείγματα με openmp

Σχετικά έγγραφα
Τμήμα Μηχανικών Πληροφορικής Τ.Ε. Σχολή Τεχνολογικών Εφαρμογών Ακαδημαϊκό έτος

Εκφωνήσεις ασκήσεων εργαστηρίου 2 (pthreads)

Εκφωνήσεις ασκήσεων εργαστηρίου 1

Συστήματα Παράλληλης και Κατανεμημένης Επεξεργασίας

Κατανεμημένος και Παράλληλος Προγραμματισμός

Κατανεμημένος και Παράλληλος Προγραμματισμός

Παράλληλη Επεξεργασία

Προγραμματισμός με το OpenMP Β. Δημακόπουλος

ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΠΑΡΑΛΛΗΛΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ ΜΕ OpenMP

Μέρος IΙ: OpenMP Κεφάλαιο 4 (νέο βιβλίο)

Συστήματα Παράλληλης και Κατανεμημένης Επεξεργασίας

Παράλληλη Επεξεργασία

Ερώτημα Α 1. Να γράψετε τις εντολές που πραγματοποιούν τα ακόλουθα:

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ. Διεργασίες και Νήματα Εργαστηριακές Ασκήσεις

Ε-85: Ειδικά Θέµατα Λογισµικού

2/4/2012 Προγραμματισμός συστημάτων κοινόχρηστης μνήμης (ΙΙ) OpenMP Β. Δημακόπουλος

Συστήματα Παράλληλης και Κατανεμημένης Επεξεργασίας

OpenMP. Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων

ΤΕΜ-101 Εισαγωγή στους Η/Υ Εξεταστική Ιανουαρίου 2011 Θέματα Β

Επιστημονικοί Υπολογισμοί - Μέρος ΙΙΙ: Παράλληλοι Υπολογισμοί

OpenMP. Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων

Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών. OpenMP. Συστήματα Παράλληλης Επεξεργασίας 9 ο Εξάμηνο

Α. unsigned int Β. double. Γ. int. unsigned char x = 1; x = x + x ; x = x * x ; x = x ^ x ; printf("%u\n", x); Β. unsigned char

Συστήµατα Παράλληλης Επεξεργασίας. OpenMP

Κεφάλαιο , 3.2: Συναρτήσεις II. (Διάλεξη 12)

EM 361: Παράλληλοι Υπολογισμοί

Μεθόδων Επίλυσης Προβλημάτων

Προγραμματισμός Ι (ΗΥ120)

Προγραµµατισµός Νηµάτων. Αρχικοποίηση µιας Φοράς pthread_once_t once_block = PTHREAD_ONCE_INIT; pthread_mutex_t mutex;

ΑΣΚΗΣΕΙΣ ΓΙΑ ΤΟ ΕΡΓΑΣΤΗΡΙΟ 2

Κατανεμημένος και Παράλληλος Προγραμματισμός

Κατανεμημένος και. Ηλίας Κ. Σάββας Αναπληρωτής Καθηγητής Τμήμα Μηχανικών Πληροφορικής ΤΕ, ΤΕΙ Θεσσαλίας

Κεφάλαιο , 3.2: Συναρτήσεις II. ( ιάλεξη 12) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Προγραμματισμός ΙI (E)

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

Ορολογία. Παράδειγµα 3. Εξισορρόπηση Εργασίας. Ε-85: Ειδικά Θέµατα Λογισµικού. E-85: Ε.Θ.Λ: Προγραµµατισµός Συστηµάτων Υψηλών Επιδόσεων 6

Προγραμματισμός I (Θ)

OpenMP. Προγραµµατισµός Αρχιτεκτονικών Μοιραζόµενης Μνήµης. Συστήµατα Παράλληλης Επεξεργασίας Εργαστήριο Υπολογιστικών Συστηµάτων ΕΜΠ. OpenMP p.

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Ε-85: Ειδικά Θέµατα Λογισµικού

ΕΡΓΑΣΤΗΡΙΟ 1 - ΣΗΜΕΙΩΣΕΙΣ

Δομές Δεδομένων και Αλγόριθμοι

Ε-85: Ειδικά Θέµατα Λογισµικού

Εργαστήριο 2: Πίνακες

Ενότητα 4: «Εισαγωγή στον Προγραμματισμό. Τα πρώτα προγράμματα σε γλώσσα C»

Προγραμματισμός Η/Υ (ΤΛ2007 )

Α Β Γ static; printf("%c\n", putchar( A +1)+2); B DB BD. int i = 0; while (++i); printf("*");

Η γλώσσα προγραμματισμού C

Συστήματα Παράλληλης και Κατανεμημένης Επεξεργασίας

Η γλώσσα προγραμματισμού C

Προγραμματισμός I (Θ)

Σημειώσεις όγδοης εβδομάδας

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ. Ασκήσεις Επανάληψης

ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ Ενδεικτικές Απαντήσεις Εξετάσεων Β' Περιόδου Θέµα 1. (α')

ax 2 + bx + c = 0, αλλίως θα αποκρίνεται ανάλογα.

Η γλώσσα προγραμματισμού C Οι συναρτήσεις στη C (2)

Υπολογισμός - Εντολές Επανάληψης

Διάλεξη 15η: Αναδρομή, μέρος 1ο

Πίνακες: μια σύντομη εισαγωγή. Πίνακες χαρακτήρων: τα "Αλφαριθμητικά"

Η γλώσσα προγραμματισμού C Οι συναρτήσεις στη C (2)

ύο μηχανισμοί απαιτούνται: 1. Μία μέθοδος για τη δημιουργία διεργασιών

Αρχές Προγραμματισμού

Προγραμματισμός Ι (HY120)

Οι συναρτήσεις στη γλώσσα C

Προγραμματισμός Η/Υ (ΤΛ2007 )

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Συστήματα Παράλληλης & Κατανεμημένης Επεξεργασίας

Πίνακες. 1 Πίνακες. 30 Μαρτίου 2014

#include <stdlib.h> Α. [-128,127] Β. [-127,128] Γ. [-128,128]

OpenMP. Συστήµατα Παράλληλης Επεξεργασίας Εργαστήριο Υπολογιστικών Συστηµάτων. Αθήνα, Νοέµβριος /11/2004 Εισαγωγή στο OpenMP 1

ΕΡΓΑΣΤΗΡΙΟ 9: Συμβολοσειρές και Ορίσματα Γραμμής Εντολής

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

Δείκτες (Pointers) Ένας δείκτης είναι μια μεταβλητή με τιμή μια διεύθυνση μνήμης. 9.8

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Προγραμματισμός Συστημάτων

Εργαστήριο 5 fork(), exec(), signals

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ II. Υφαντόπουλος Νικόλαος Υποψήφιος Διδάκτορας Contact:

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

double sum(double a, double b) { return(a+b); } double my_avg(double a, double b) { return(sum(a, b)/2.0); }

Η γλώσσα προγραμματισμού C

Κατανεμημένος και Παράλληλος Προγραμματισμός. Εισαγωγή στο MPI. Εγκατάσταση MPICH σε ένα ΗΥ 10/3/2017

ΠΡΟΓΡΜΜΑΤΑ ΣΕ C. Γράψτε σε γλώσσα προγραμματισμού C τη συνάρτηση:

Προγραμματισμός Ι. Προχωρημένα Θέματα. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Επανάληψη για τις Τελικές εξετάσεις. (Διάλεξη 24) ΕΠΛ 032: ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΜΕΘΟΔΩΝ ΕΠΙΛΥΣΗΣ ΠΡΟΒΛΗΜΑΤΩΝ

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

NIKOΛΑΟΣ ΝΤΙΡΛΗΣ 5ο ΦΡΟΝΤΙΣΤΗΡΙΟ ΑΙΘΟΥΣΑ Β4

Προγραμματισμός Ι (ΗΥ120)

Διάλεξη 5η: Εντολές Επανάληψης

ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ Ενδεικτικές Απαντήσεις Εξετάσεων Α' Περιόδου Θέµα 1. (α') 2 - ii 3 - iii 4 - iv

12. Συναρτήσεις (Μέρος ΙI)

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

Αλγόριθμοι Ταξινόμησης Μέρος 1

Προγραμματισμός Ι. Δείκτες. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Δημιουργία & Τερματισμός Διεργασιών. Προγραμματισμός II 1

Εργαστήριο ΔΙΕΡΓΑΣΙΕΣ - ΔΙΑΧΕΙΡΙΣΗ

Δομημένος Προγραμματισμός

Εισαγωγή στον Προγραμματισμό

Εργαστήριο 2ο. Περίγραμμα Εργαστηριακής Άσκησης

Προεπεξεργαστής της C. C Preprocessor. Προγραμματισμός II 1

Transcript:

Τμήμα Μηχανικών Πληροφορικής Τ.Ε. Σχολή Τεχνολογικών Εφαρμογών Ακαδημαϊκό έτος 2016-2017 ΤΕΙ Ηπείρου - Άρτα Κατανεμημένα και Παράλληλα Συστήματα (εργαστήριο) Παραδείγματα με openmp Γκόγκος Χρήστος Παράδειγμα 1 Δημιουργία ενός αριθμού νημάτων (ο αριθμός καθορίζεται από όρισμα της γραμμής εντολών) και εμφάνιση μηνύματος που περιέχει τον αριθμό νήματος για κάθε νήμα. #include <stdlib.h> int main(int argc, char *argv[]) { if (argc!= 2) { printf("usage: %s <number_of_threads>\n", argv[0]); exit(-1); int thread_count = strtol(argv[1], NULL, 10); #pragma omp parallel num_threads(thread_count) { int my_rank = omp_get_thread_num(); int thread_count = omp_get_num_threads(); printf("hello from thread %d of %d\n", my_rank, thread_count); openmp_example01a.c gcc openmp_example01a.c -o openmp_example01a -fopenmp./openmp_example01a 4 Hello from thread 1 of 4 Hello from thread 2 of 4 Hello from thread 0 of 4 Hello from thread 3 of 4 ή εναλλακτικά #include <stdlib.h> void hello(void); int main(int argc, char *argv[]) { if (argc!= 2) { printf("usage: %s <number_of_threads>\n", argv[0]); exit(-1); int thread_count = strtol(argv[1], NULL, 10); #pragma omp parallel num_threads(thread_count) [1]

hello(); void hello(void) { int my_rank = omp_get_thread_num(); int thread_count = omp_get_num_threads(); printf("hello from thread %d of %d\n", my_rank, thread_count); openmp_example01b.c Παράδειγμα 2 Παραδείγματα με μεταβλητές private, firstprivate και shared. #include <stdlib.h> int main(int argc, char *argv[]) { int a = 0, b = 0; #pragma omp parallel num_threads(4) shared(a) firstprivate(b) { b++; int my_rank = omp_get_thread_num(); #pragma omp critical a++; printf("%d a=%d b=%d\n", my_rank, a, b); printf("a=%d b=%d\n", a, b); pthreads_example02a.c gcc openmp_example02a.c -o openmp_example02a -fopenmp./openmp_example02a 0 a=1 b=1 3 a=2 b=1 1 a=4 b=1 2 a=3 b=1 a=4 b=0 int main() { int a = 1, b = 1, c = 1, d = 1; printf("1. a=%d, b=%d, c=%d, d=%d\n", a, b, c, d); #pragma omp parallel shared(b), private(c), firstprivate(d) num_threads(4) [2]

{ c++; d++; #pragma omp critical { a++; b++; printf("2. [%d] a=%d, b=%d, c=%d, d=%d\n", omp_get_thread_num(), a, b, c, d); printf("3. a=%d, b=%d, c=%d, d=%d\n", a, b, c, d); pthreads_example02b.c gcc openmp_example02b.c -o openmp_example02b -fopenmp./openmp_example02b 1. a=1, b=1, c=1, d=1 2. [1] a=2, b=2, c=2292609, d=2 2. [0] a=3, b=3, c=1, d=2 2. [3] a=5, b=5, c=5288825, d=2 2. [2] a=4, b=4, c=5269073, d=2 3. a=5, b=5, c=1, d=1 Παράδειγμα 3 Υπολογισμός ορισμένου ολοκληρώματος συνάρτησης (σειριακός και παράλληλος κώδικας). #include <stdlib.h> // example f(x)=x^2 double f(double x) { return x * x; double trapezio_serial(double a, double b, int n) { double x_i, approx; int i; double h = (b - a) / n; approx = (f(a) + f(b)) / 2.0; for (i = 1; i <= n - 1; i++) { x_i = a + i * h; approx += f(x_i); approx *= h; return approx; void trapezio_parallel(double a, double b, int n, double *global_result) { double h, x, my_result, local_a, local_b; int i, local_n; [3]

int my_rank = omp_get_thread_num(); int thread_count = omp_get_num_threads(); h = (b - a) / n; local_n = n / thread_count; local_a = a + my_rank * local_n * h; local_b = local_a + local_n * h; my_result = (f(local_a) + f(local_b)) / 2.0; for (i = 1; i <= local_n - 1; i++) { x = local_a + i * h; my_result += f(x); my_result *= h; #pragma omp_critical *global_result += my_result; int main(int argc, char **argv) { int thread_count = 5; double global_result = 0.0; int n = 1000000000; double approx; double a = 0.0, b = 10.0; approx = trapezio_serial(a, b, n); printf("result from the serial code: %.5f\n", approx); #pragma omp parallel num_threads(thread_count) trapezio_parallel(a, b, n, &global_result); printf("result from the parallel code: %.5f\n", global_result); openmp_example03a.c gcc openmp_example03a.c -o openmp_example03a fopenmp./openmp_example03a result from the serial code: 333.33333 result from the parallel code: 333.33333 #include <stdlib.h> // example f(x)=x^2 double f(double x) { return x * x; double trapezio_parallel(double a, double b, int n) { double h, x, my_result, local_a, local_b; [4]

int i, local_n; int my_rank = omp_get_thread_num(); int thread_count = omp_get_num_threads(); h = (b - a) / n; local_n = n / thread_count; local_a = a + my_rank * local_n * h; local_b = local_a + local_n * h; my_result = (f(local_a) + f(local_b)) / 2.0; for (i = 1; i <= local_n - 1; i++) { x = local_a + i * h; my_result += f(x); my_result *= h; return my_result; int main(int argc, char **argv) { double global_result = 0.0; int n = 1000000000; double a = 0.0, b = 10.0; #pragma omp parallel num_threads(5) { double my_result = trapezio_parallel(a, b, n); #pragma omp_critical global_result += my_result; printf("result from the parallel code: %.5f\n", global_result); openmp_example03b.c gcc openmp_example03b.c -o openmp_example03b fopenmp./openmp_example03b result from the parallel code: 333.33333 Υπολογισμός ορισμένου ολοκληρώματος συνάρτησης με χρήση reduction. #include <stdlib.h> // example f(x)=x^2 double f(double x) { return x * x; double trapezio_parallel(double a, double b, int n) { double h, x, my_result, local_a, local_b; int i, local_n; int my_rank = omp_get_thread_num(); int thread_count = omp_get_num_threads(); h = (b - a) / n; [5]

local_n = n / thread_count; local_a = a + my_rank * local_n * h; local_b = local_a + local_n * h; my_result = (f(local_a) + f(local_b)) / 2.0; for (i = 1; i <= local_n - 1; i++) { x = local_a + i * h; my_result += f(x); my_result *= h; return my_result; int main(int argc, char **argv) { double global_result = 0.0; int n = 1000000000; double a = 0.0, b = 10.0; #pragma omp parallel num_threads(5) reduction(+ : global_result) global_result = trapezio_parallel(a, b, n); printf("result from the parallel code using reduction : %.5f\n", global_result); openmp_example03c.c gcc openmp_example03c.c -o openmp_example03c fopenmp./openmp_example03c result from the parallel code using reduction : 333.33333 Παράδειγμα 4 Δομές διαμοιρασμού εργασίας (single, sections, for) // Δομές διαμοιρασμού εργασίας (single, sections, for) int main() { int i; #pragma omp parallel num_threads(5) { // ο ακόλουθος κώδικας θα εκτελεστεί από όλα τα νήματα printf("hi from thread %d\n", omp_get_thread_num()); // ο ακόλουθος κώδικας θα εκτελεστεί από ένα μόνο τυχαίο νήμα #pragma omp single printf("the thread chosen for single execution is %d\n", omp_get_thread_num()); [6]

// δύο τυχαία νήματα θα εκτελέσουν από ένα από τα ακόλουθα sections #pragma omp sections { #pragma omp section { printf("section A was executed by %d\n", omp_get_thread_num()); #pragma omp section { printf("section B was executed by %d\n", omp_get_thread_num()); // οι 10 επαναλήψεις της for θα μοιραστούν από 2 σε κάθε ένα από τα 5 νήματα #pragma omp for for (i = 0; i < 10; i++) printf("iteration %d is given to thread %d\n", i, omp_get_thread_num()); openmp_example04a.c gcc openmp_example04a.c -o openmp_example04a fopenmp./openmp_example04a Hi from thread 3 The thread chosen for single execution is 3 Hi from thread 0 Hi from thread 2 Hi from thread 4 Hi from thread 1 Section A was executed by 4 Section B was executed by 3 Iteration 4 is given to thread 2 Iteration 5 is given to thread 2 Iteration 2 is given to thread 1 Iteration 3 is given to thread 1 Iteration 6 is given to thread 3 Iteration 7 is given to thread 3 Iteration 8 is given to thread 4 Iteration 9 is given to thread 4 Iteration 0 is given to thread 0 Iteration 1 is given to thread 0 Παράδειγμα 5 Υπολογισμός του αριθμού π με βάση τον τύπο: 1 4 1 + x 2 dx = π 0 #define n 1000000000 [7]

double compute_pi_serial() { int i = 0; double pi = 0.0, w = 1.0 / n; for (i = 0; i < n; i++) pi += 4 * w / (1 + (i + 0.5) * (i + 0.5) * w * w); return pi; void compute_pi_parallel() { int i; double pi = 0.0, mysum = 0.0, w = 1.0 / n; #pragma omp parallel firstprivate(mysum) num_threads(1000) { #pragma omp for for (i = 0; i < n; i++) mysum += 4 * w / (1 + (i + 0.5) * (i + 0.5) * w * w); #pragma omp critical pi += mysum; printf("pi computed in parallel using 10^9 terms: %.14f\n", pi); void compute_pi_parallel_using_reduction() { int i; double pi = 0.0, w = 1.0 / n; #pragma omp parallel for reduction(+ : pi) for (i = 0; i < n; i++) pi += 4 * w / (1 + (i + 0.5) * (i + 0.5) * w * w); printf("pi computed in parallel(reduction) using 10^9 terms: %.14f\n", pi); int main() { double start, finish; printf("pi computed serially using 10^9 terms : %.14f\n", compute_pi_serial()); printf("time elapsed: %.2f\n", finish - start); compute_pi_parallel(); printf("time elapsed: %.2f\n", finish - start); compute_pi_parallel_using_reduction(); printf("time elapsed: %.2f\n", finish - start); [8]

openmp_example05a.c gcc openmp_example05a.c -o openmp_example05a fopenmp./openmp_example05a Pi computed serially using 10^9 terms : 3.14159265358938 Time elapsed: 7.20 Pi computed in parallel using 10^9 terms: 3.14159265358979 Time elapsed: 1.95 Pi computed in parallel(reduction) using 10^9 terms: 3.14159265358978 Time elapsed: 1.95 Υπολογισμός του π με βάση τον τύπο: #define n 1000000000 double compute_pi_serial() { int k; double factor = 1.0; double sum = 0.0; for (k = 0; k < n; k++) { sum += factor / (2 * k + 1); factor = -factor; return 4.0 * sum; π = 4 [1 1 3 + 1 5 1 7 + ] = 4 ( 1)k 2k + 1 void compute_pi_parallel() { int k; double sum = 0.0, factor; #pragma omp parallel for reduction(+ : sum) private(factor) for (k = 0; k < n; k++) { if (k % 2 == 0) factor = 1.0; else factor = -1.0; sum += factor / (2 * k + 1); printf("pi computed in parallel using 10^9 terms: %.14f\n", 4.0 * sum); k=0 int main() { double start, finish; [9]

printf("pi computed serially using 10^9 terms : %.14f\n", compute_pi_serial()); printf("time elapsed: %.2f\n", finish - start); compute_pi_parallel(); printf("time elapsed: %.2f\n", finish - start); openmp_example05b.c gcc openmp_example05b.c -o openmp_example05b fopenmp./openmp_example05b Pi computed serially using 10^9 terms : 3.14159265258805 Time elapsed: 7.30 Pi computed in parallel using 10^9 terms: 3.14159265258932 Time elapsed: 1.93 Παράδειγμα 6 Χρονοπρογραμματισμός βρόχων. Επιλογή χρονοδιαγραμμάτων. #include <math.h> // n=30000 // serial execution: 11.02 seconds // parallel for : 5.83 seconds // parallel for schedule(static, 1): 4.61 seconds double f(int i) { int j, start = i * (i + 1) / 2, finish = start + i; double return_val = 0; for (j = start; j < finish; j++) return_val += sin(j); return return_val; int main() { double sum; int i, n = 30000; double start, finish; sum = 0; [10]

for (i = 0; i <= n; i++) sum += f(i); printf("the sum is %.2f\n", sum); printf("time elapsed: %.2f (serial)\n", finish - start); sum = 0; // χρονοδιάγραμμα τύπου μπλοκ #pragma omp parallel for num_threads(4) reduction(+ : sum) for (i = 0; i <= n; i++) sum += f(i); printf("the sum is %.2f\n", sum); printf("time elapsed: %.2f (default schedule)\n", finish - start); sum = 0; // κυκλικό χρονοδιάγραμμα #pragma omp parallel for num_threads(4) reduction(+ : sum) schedule(static, 1) for (i = 0; i <= n; i++) sum += f(i); printf("the sum is %.2f\n", sum); printf("time elapsed: %.2f (cyclic schedule)\n", finish - start); openmp_example06.c gcc openmp_example06.c -o openmp_example06 fopenmp./openmp_example06 The sum is 6.49 Time elapsed: 20.83 (serial) The sum is 6.49 Time elapsed: 9.58 (default schedule) The sum is 6.49 Time elapsed: 5.85 (cyclic schedule) Παράδειγμα 7 Ταξινόμηση #include <stdlib.h> void bubble_sort_serial(int *a, int n) { int i, list_length, tmp; for (list_length = n; list_length >= 2; list_length--) for (i = 0; i < list_length - 1; i++) if (a[i] > a[i + 1]) { [11]

tmp = a[i]; a[i] = a[i + 1]; a[i + 1] = tmp; void odd_even_sort_serial(int *a, int n) { int i, phase, tmp; for (phase = 0; phase < n; phase++) if (phase % 2 == 0) { for (i = 1; i < n; i += 2) if (a[i - 1] > a[i]) { tmp = a[i]; a[i] = a[i - 1]; a[i - 1] = tmp; else { for (i = 1; i < n - 1; i += 2) if (a[i] > a[i + 1]) { tmp = a[i]; a[i] = a[i + 1]; a[i + 1] = tmp; void odd_even_sort_parallel1(int *a, int n, int thread_count) { int i, phase, tmp; for (phase = 0; phase < n; phase++) if (phase % 2 == 0) { #pragma omp parallel for num_threads(thread_count) default(none) \ shared(a, n) private(i, tmp) for (i = 1; i < n; i += 2) if (a[i - 1] > a[i]) { tmp = a[i]; a[i] = a[i - 1]; a[i - 1] = tmp; else { #pragma omp parallel for num_threads(thread_count) default(none) \ shared(a, n) private(i, tmp) for (i = 1; i < n - 1; i += 2) if (a[i] > a[i + 1]) { tmp = a[i]; a[i] = a[i + 1]; a[i + 1] = tmp; void odd_even_sort_parallel2(int *a, int n, int thread_count) { int i, phase, tmp; [12]

#pragma omp parallel num_threads(thread_count) default(none) \ shared(a, n) private(i, tmp, phase) for (phase = 0; phase < n; phase++) if (phase % 2 == 0) { #pragma omp for for (i = 1; i < n; i += 2) if (a[i - 1] > a[i]) { tmp = a[i]; a[i] = a[i - 1]; a[i - 1] = tmp; else { #pragma omp for for (i = 1; i < n - 1; i += 2) if (a[i] > a[i + 1]) { tmp = a[i]; a[i] = a[i + 1]; a[i + 1] = tmp; int main() { int i, n = 40000; int a[n], c[n]; double start, finish; srand(12345l); for (i = 0; i < n; i++) c[i] = a[i] = rand() % 1000000; bubble_sort_serial(a, n); printf("time elapsed bubble sort serial %.2f seconds\n", finish - start); for (i = 0; i < n; i++) a[i] = c[i]; odd_even_sort_serial(a, n); printf("time elapsed odd even sort serial %.2f seconds\n", finish - start); for (i = 0; i < n; i++) a[i] = c[i]; odd_even_sort_parallel1(a, n, 4); printf("time elapsed odd even sort parallel1 %.2f seconds\n", finish - start); for (i = 0; i < n; i++) a[i] = c[i]; [13]

odd_even_sort_parallel2(a, n, 4); printf("time elapsed odd even sort parallel2 %.2f seconds\n", finish - start); openmp_example07.c gcc openmp_example07.c -o openmp_example07 fopenmp./openmp_example07 Time elapsed bubble sort serial 8.18 seconds Time elapsed odd even sort serial 6.62 seconds Time elapsed odd even sort parallel1 3.73 seconds Time elapsed odd even sort parallel2 2.73 seconds [14]