Κατανεμημένος και Παράλληλος Προγραμματισμός Ηλίας Κ. Σάββας Καθηγητής Τμήμα Μηχανικών Πληροφορικής ΤΕ, ΤΕΙ Θεσσαλίας Email: savvas@teilar.gr Παράλληλος προγραμματισμός - OpenMP Παράλληλες αρχιτεκτονικές βασισμένες στην μνήμη Εισαγωγή στην Open Multi Processing Παραδείγματα Οδηγίες OpenMP OMP και MPI ΟMP vs MPI 2 Παράλληλες αρχιτεκτονικές βασισμένες στην μνήμη Κοινής μνήμης shared memory: Συμμετρικό σύστημα πολλών επεξεργαστών (Symmetric MultiProcessor system SMP) Κατανεμημένης μνήμης distributed memory: Κατανεμημένο σύστημα πολλών επεξεργαστών (Distributed MoultiProcessor system DMP) Υβριδικής μνήμης hybrid memory. 3 1
Αρχιτεκτονική κοινής μνήμης (SMP) Οι παράλληλοι υπολογιστές κοινής μνήμης αν και διαφέρουν μεταξύ τους γενικά έχουν την δυνατότητα όλοι οι επεξεργαστές να έχουν προσπέλαση στην ίδια μνήμη. Αν και ο κάθε επεξεργαστής μπορεί να λειτουργεί αυτόνομα διαμοιράζεται όμως την ίδια μνήμη με όλους τους υπόλοιπους. Η όποια αλλαγή στην μνήμη επέλθει από κάποιον επεξεργαστή είναι ορατή και από όλους τους άλλους. 4 Πλεονεκτήματα και μειονεκτήματα αρχιτεκτονικής κοινής μνήμης +Η καθολικά κοινή μνήμη παρέχει ένα αρκετά φιλικό προς τον χρήστη προγραμματιστικό περιβάλλον. +Η κοινή μνήμη μεταξύ των παράλληλων τμημάτων ενός προγράμματος είναι ταχύτατη λόγω της εγγύτητας της μνήμης προς τους επεξεργαστές. -Πρόβλημα κλιμάκωσης μεταξύ μνήμης και επεξεργαστών. Αύξηση του πλήθους των επεξεργαστών αυξάνει την κίνηση μεταξύ CPUs και μνήμης. -Ο συγχρονισμός γίνεται με ευθύνη του προγραμματιστή ώστε να είναι σίγουρη η ορθή χρήση της κοινής μνήμης. -Είναι εξαιρετικά δύσκολη και ακριβή η σχεδίαση και παραγωγή τέτοιου τύπου συστημάτων με τον ολοένα αυξανόμενο αριθμό επεξεργαστών. 5 Αρχιτεκτονική κατανεμημένης μνήμης (DMP) Κάθε επεξεργαστής διαθέτει την δική του αποκλειστική μνήμη. Κάθε επεξεργαστής λειτουργεί αυτόνομα. Όταν κάποιος επεξεργαστής χρειαστεί να προσπελάσει μνήμη άλλου επεξεργαστή είναι ευθύνη του προγραμματιστή για το πώς και πότε (συγχρονισμός, επικοινωνία). Απαιτείται κάποιο δίκτυο για να είναι εφικτή η επικοινωνία (μπορεί να είναι για παράδειγμα το ethernet) 6 2
Πλεονεκτήματα και μειονεκτήματα αρχιτεκτονικής κατανεμημένης μνήμης +Η μνήμη κλιμακώνεται ανάλογα με τον αριθμό των επεξεργαστών. Αύξηση του αριθμού των επεξεργαστών συνεπάγεται αύξηση και της συνολικής μνήμης. +Ο κάθε επεξεργαστής έχει ταχύτατη προσπέλαση στην δική του μνήμη. +Αποτελεί φθηνή λύση καθώς ο κάθε επεξεργαστής μπορεί να είναι ένας απλός και φθηνός υπολογιστής του εμπορίου. -Ο προγραμματιστής είναι ο υπεύθυνος για πολλές λεπτομέρειες που συσχετίζονται με την μεταφορά δεδομένων μεταξύ των υπολογιστικών κόμβων. -Μη ομοιόμορφος χρόνος προσπέλαση μνήμης καθώς εξαρτάται από το δίκτυο και την φυσική θέση της μνήμης που πρέπει να προσπελασθεί (Non-Uniform Memory Access time NUMA). 7 Αρχιτεκτονική υβριδικής (κοινής και κατανεμημένης) μνήμης Το τμήμα τη κοινής μνήμης αποτελεί μία SMP μηχανή. Όλοι οι επεξεργαστές μίας SMP μηχανής έχουν προσπέλαση στην ίδια μνήμη. Πολλαπλές SMP μηχανές οι οποίες επικοινωνούν μεταξύ τους μέσω κάποιου δικτύου αποτελούν το τμήμα του συστήματος με την κατανεμημένη μνήμη. Οι ταχύτεροι και μεγαλύτεροι υπολογιστές σήμερα χρησιμοποιούν αυτό το μοντέλο. +/-: ότι είναι κοινό και στις δύο αρχιτεκτονικές. 8 OpenMP Open Multi-Processing: Αποτελεί ένα application programming interface (API) το οποίο υποστηρίζει multi-platform shared memory multiprocessing Γλώσσες που υποστηρίζει: C, C++, και Fortran Λειτουργικά Συστήματα: Solaris, AIX, HP-UX, Linux, OS X, και Windows. Διαθέτει ένα σύνολο οδηγιών προς τους compilers 9 3
Πρώτο πρόγραμμα hello1.c #include <omp.h> #include <stdio.h> int main(int *argc, char **argv) # pragma omp parallel printf("arithmos Thread: %d\n", omp_get_thread_num()); return 0; gcc hello1.c o hello1 -fopenmp ubuntu@ubuntu:~/omp$./hello1 Arithmos Thread: 3 Arithmos Thread: 0 Arithmos Thread: 1 Arithmos Thread: 2 ubuntu@ubuntu:~/omp 10 Σχόλια hello1.c #include <omp.h> #include <stdio.h> int main(int *argc, char **argv) # pragma omp parallel printf("arithmos Thread: %d\n", omp_get_thread_n um()); return 0; omp.h η βιβλιοθήκη για την OMP. Δεν χρειάζεται να κάνουμε κάτι. Εμπεριέχεται στην gcc #pragma οδηγίες της OMP για παραλληλία τμήματος προγράμματος (γενικά οδηγίες στον compiler της C για διαδικασίες που εξαρτώνται από το λειτουργικό, υλικό, κλπ). Εάν είναι απαραίτητο: κώδικας omp_get_thread_num() αριθμός διεργασίας (myid). Πόσες διεργασίες: εάν δεν το προσδιορίσουμε τόσες όσοι και οι διαθέσιμοι πυρήνες 11 Βελτίωση: hello2.c #include <omp.h> ----- int P; // synolo diergasiwn # pragma omp parallel if (omp_get_thread_num() == 0 ) P = omp_get_num_threads(); printf("\nsynolo DIERASIWN: %d\n\n", P); #pragma omp parallel printf("geia sas apo tin %d diergasia epi synolou %d\n", omp_get_thread_num(), P); if (omp_get_thread_num() == 2 ) printf("\talla egw, i %d diergasia, sas xaireto gia alli mia fora...!\n", omp_get_thread_num()); return 0; 12 4
hello2.c: εκτέλεση ubuntu@ubuntu:~/omp$ gcc hello2.c -o hello2 -fopenmp ubuntu@ubuntu:~/omp$./hello2 SYNOLO DIERASIWN: 4 Geia sas apo tin 1 diergasia epi synolou 4 Geia sas apo tin 3 diergasia epi synolou 4 Geia sas apo tin 2 diergasia epi synolou 4 Alla egw, i 2 diergasia, sas xaireto gia alli mia fora...! Geia sas apo tin 0 diergasia epi synolou 4 13 Σχόλια hello2.c omp_get_num_threads(): σύνολο διεργασιών (αν δεν διαφοροποιηθεί, όσοι και οι πυρήνες) if (omp_get_thread_num() == 2 ): σε περίπτωση που μόνο κάποια διεργασία πρέπει να κάνει κάτι (συνήθως η master διεργασία = 0) # pragma κώδικας 1 # pragma κώδικας 2): για να εκτελεσθεί ο κώδικας 2 θα πρέπει όλες οι διεργασίες του κώδικα 1 να έχουν τερματίσει (barrier) 14 Επιπλέον βελτίωση: hello3.c int P; // synolo diergasiwn int myid; // i dirgasiaasia mou # pragma omp parallel private(myid) myid = omp_get_thread_num(); printf("hello World apo tin diergasia %d\n", myid); if (myid == 0) // Mono i vasiki diergasia (master) ektelei auto P = omp_get_num_threads(); printf("synolo DIERGASIWN= %d\n", P); 15 5
hello3.c: εκτέλεση ubuntu@ubuntu:~/omp$ gcc hello3.c -o hello3 fopenmp ubuntu@ubuntu:~/omp$./hello3 Hello World apo tin diergasia 0 SYNOLO DIERGASIWN = 4 Hello World apo tin diergasia 3 Hello World apo tin diergasia 2 Hello World apo tin diergasia 1 ubuntu@ubuntu:~/omp$ 16 Σχόλια hello3.c # pragma omp parallel private(myid): εμβέλεια μεταβλητής ιδιωτική (private) για κάθε διεργασία # pragma omp parallel shared(x): κοινή για όλες τις διεργασίες, αλλά και συνδυασμός: # pragma omp parallel private(i) shared(n, A, B, C): για C[N] = A[N] + B[N], i ο δείκτης του for 17 Οδηγία omp.h Γρήγορος οδηγός αναφοράς omp_get_num_thr eads() omp_get_thread_ num() #pragma omp parallel private(λίστα μεταβλητών) shared(λίστα μεταβλητών) Αποτέλεσμα Βιβλιοθήκη της OpenMP Εύρεση πλήθους διεργασιών (όσοι και οι πυρήνες αν δεν διαφοροποιηθεί) Εύρεση ποια διεργασία είμαι εγώ Αρχή παράλληλου κώδικα Εμβέλεια μεταβλητών: τοπικές σε κάθε διεργασία Εμβέλεια μεταβλητών: καθολικές (σε όλες τις διεργασίες) 18 6
MPI με OMP Μπορούμε να συνδυάσουμε MPI με OMP? (αυτό θα ήταν η πεμπτουσία του συνδυασμού κατανεμημένου και παράλληλου προγραμματισμού) ΝΑΙ! Επειδή η MPI λειτουργεί με κόμβους οι οποίοι θα μπορούσε να είναι αυτόνομες υπολογιστικές μονάδες (και ετερογενείς) και σε κάθε κόμβο να εκμεταλλευόμαστε τους (φυσικούς) πυρήνες του Προφανώς αποτελεί ένα πανίσχυρο εργαλείο! 19 Παράδειγμα: omp_mpi.c (1 από 3) #include <stdio.h> #include "mpi.h" #include <omp.h> int main(int *argc, char **argv) int P, myid; //MPI: P=σύνολο κόμβων, myid ποιος είμαι int ego, diergasies; //OMP: ego=ποια διεργασία (πυρήνας // είμαι), diergasies=σύνολο πυρήνων 20 Παράδειγμα: omp_mpi.c (2 από 3) MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &P); MPI_Comm_rank(MPI_COMM_WORLD, &myid); 21 7
Παράδειγμα: omp_mpi.c (3 από 3) #pragma omp parallel default(shared) private(ego, diergasies) diergasies = omp_get_num_threads(); ego = omp_get_thread_num(); printf("xaietismata apo tin diergasia %d se synolo %d kai apo ton komvo %d se synolo %d\n", ego, diergasies, myid, P); MPI_Finalize(); 22 Μεταγλώττιση και εκτέλεση (1 από 3) ilias@ilias-optiplex-9010:~/omp_programs$ mpicc mpi_omp.c -o mpi_omp fopenmp ilias@ilias-optiplex-9010:~/omp_programs$ mpirun -np 4./mpi_omp Δηλαδή: το τρέχουμε σε 4 κόμβους όπου ο κάθε κόμβος θα αξιοποιήσει τους πυρήνες του Αποτέλεσμα (ο κάθε κόμβος διαθέτει 8 πυρήνες): 23 Μεταγλώττιση και εκτέλεση (2 από 3) ilias@ilias-optiplex-9010:~/omp_programs$ mpicc mpi_omp.c -o mpi_omp -fopenmp ilias@ilias-optiplex-9010:~/omp_programs$ mpirun -np 4./mpi_omp Xairetismata apo tin diergasia 4 se synolo 8 kai apo ton komvo 2 se synolo 4 Xairetismata apo tin diergasia 1 se synolo 8 kai apo ton komvo 2 se synolo 4 Xairetismata apo tin diergasia 5 se synolo 8 kai apo ton komvo 2 se synolo 4 Xairetismata apo tin diergasia 2 se synolo 8 kai apo ton komvo 0 se synolo 4 Xairetismata apo tin diergasia 6 se synolo 8 kai apo ton komvo 0 se synolo 4 Xairetismata apo tin diergasia 4 se synolo 8 kai apo ton komvo 0 se synolo 4 Xairetismata apo tin diergasia 0 se synolo 8 kai apo ton komvo 0 se synolo 4 Xairetismata apo tin diergasia 6 se synolo 8 kai apo ton komvo 2 se synolo 4 Xairetismata apo tin diergasia 3 se synolo 8 kai apo ton komvo 2 se synolo 4 Xairetismata apo tin diergasia 3 se synolo 8 kai apo ton komvo 0 se synolo 4 24 8
Μεταγλώττιση και εκτέλεση (3 από 3) Xairetismata apo tin diergasia 1 se synolo 8 kai apo ton komvo 0 se synolo 4 Xairetismata apo tin diergasia 2 se synolo 8 kai apo ton komvo 2 se synolo 4 Xairetismata apo tin diergasia 7 se synolo 8 kai apo ton komvo 2 se synolo 4 Xairetismata apo tin diergasia 5 se synolo 8 kai apo ton komvo 3 se synolo 4 Xairetismata apo tin diergasia 7 se synolo 8 kai apo ton komvo 3 se synolo 4 Xairetismata apo tin diergasia 1 se synolo 8 kai apo ton komvo 3 se synolo 4 Xairetismata apo tin diergasia 3 se synolo 8 kai apo ton komvo 3 se synolo 4 Xairetismata apo tin diergasia 7 se synolo 8 kai apo ton komvo 0 se synolo 4 Xairetismata apo tin diergasia 5 se synolo 8 kai apo ton komvo 0 se synolo 4 Xairetismata apo tin diergasia 0 se synolo 8 kai apo ton komvo 2 se synolo 4 Xairetismata apo tin diergasia 6 se synolo 8 kai apo ton komvo 1 se synolo 4 ------ 25 OMP vs MPI Να γραφεί πρόγραμμα με α) χρήση της MPI και β) χρήση της ΟΜP το οποίο θα εκτελεί το εσωτερικό γινόμενο δύο διανυσμάτων. Έστω Α[Ν] και Β[Ν] δύο διανύσματα μεγέθους Ν. To εσωτερικό γινόμενο c=axb δίνεται από τον τύπο: N c 1 a b i 0 i i 26 OMP: egd_omp.c (1 από 3) // Esoteriko ginomeno dianysmatwn #include <stdio.h> #include <stdlib.h> #include <omp.h> int main(int *argc, char **argv) int myid, P; // my id kai arithmos diergasiwn int *A, *B; // ta dianysmata int N; // megethos dianysmatwn int i; // deiktis int sum=0; // edo tha sysoreythei to esoteriko ginomeno printf("\nn="); scanf("%d", &N); 27 9
OMP: egd_omp.c (2 από 3) // Dimiourgia dianysmatwn A = malloc(n * sizeof( int )); B = malloc(n * sizeof( int )); for (i=0; i<n; i++) A[i] = rand() % 10; for (i=0; i<n; i++) B[i] = rand() % 10; 28 OMP: egd_omp.c (3 από 3) // Esoteriko ginomeno sum = A x B # pragma omp parallel for private (i) shared(n, A, B) reduction(+:sum) for (i=0; i<n; i++) sum += A[i] * B[i]; printf("\n\nesoteriko ginomeno = %d\n\n", sum); return 0; 29 MPI: egd_mpi.c Διαφοροποιήσεις: Πρέπει το Ν να εισαχθεί στον 0 κόμβο και να γίνει στην συνέχεια broadcast Πρέπει να διαμοιραστεί το for: for (i=myid; i<n; i+=p) // P αριθμός κόμβων Πρέπει ο κάθε κόμβος να χρησιμοποιεί μία τοπική μεταβλητή για το άθροισμα που του αντιστοιχεί: int sum_local=0; Πρέπει να γίνει reduce στον κόμβο 0 και στην μεταβλητή sum H εκτύπωση του sum να γίνει μόνο από τον κόμβο 0 30 10
Ποιο είναι πιο εύκολο? OpenMP: γιατί «κρύβει» και διαχειρίζεται μόνη της πολλές διαδικασίες από τον προγραμματιστή, για παράδειγμα: Παραλληλοποίηση for (και στην MPI δεν είδαμε και την περίπτωση να είναι N % P!= 0) O master κόμβος πρέπει να υποδηλώνεται στην MPI και να διαχειρίζεται διαφορετικά. Και αυτό μέλημα του προγραμματιστή! Οι συμμετέχουσες διεργασίες ενεργοποιούνται αυτόματα στο βέλτιστο από την OMP (όσοι και οι πυρήνες) 31 Ποια είναι πιο χρήσιμη? Η MPI γιατί: Μπορεί να κλιμακώνει ανάλογα με τους συμμετέχοντες κόμβους Χρησιμοποιεί περισσότερους και εάν υπάρχει ανάγκη απομακρυσμένους και γεωγραφικά κατανεμημένους υπολογιστικούς πόρους ΒΕΛΤΙΣΤΟ: ο συνδυασμός τους!!! 32 Ερωτήσεις; Τέλος της # 06 ενότητας Χρησιμοποιείστε το email για όποιες επιπλέον απορίες / ερωτήσεις: savvas@teilar.gr Σημειώσεις μαθήματος (και όχι μόνο): https://e-class.teilar.gr/courses/cs386/ 33 11