Εισαγωγή στον Προγραµµατισµό Πολυεπεξεργαστικών Συστηµάτων Κοινής Μνήµης µε...

Σχετικά έγγραφα
Ε-85: Ειδικά Θέµατα Λογισµικού

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Περίληψη. Υπερυπολογιστές. Υπολογιστικά προβλήµατα. TOP 500 (Ιούνιος 2007) TOP 500 (Ιούνιος 2009) Ε-85: Ειδικά Θέµατα Λογισµικού

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

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

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

ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΠΑΡΑΛΛΗΛΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ ΜΕ OpenMP (2 ο Μέρος)

ΥΛΟΠΟΙΗΣΗ ΣΥΝΤΑΚΤΙΚΟΥ ΑΝΑΛΥΤΗ ΓΙΑ ΤΟΝ ΠΑΡΑΛΛΗΛΟΠΟΙΗΤΙΚΟ ΜΕΤΑΦΡΑΣΤΗ OMPI Η ΜΕΤΑΠΤΥΧΙΑΚΗ ΕΡΓΑΣΙΑ ΕΞΕΙ ΙΚΕΥΣΗΣ. Υποβάλλεται στην

Υ07 Παράλληλα Συστήματα /3/2018 Προγραμματισμός συστημάτων κοινόχρηστης μνήμης (IΙ)

Υλοποίηση cancellation στον παραλληλοποιητικό μεταφραστή OMPi. Εμμανουήλ Φελουτζή. με Α.Μ: 1579 ΔΙΠΛΩΜΑΤΟΣ

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

Αποδοτική εκτέλεση προγραμμάτων OpenMP σε συστάδες Η/Υ

Λ10 Παράλληλος & Κατανεμημένος Προγραμματισμός 2009

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

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

ΕΙΣΑΓΩΓΗ ΣΤΟN ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΑΤΡΩΝ ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΜΗΧΑΝΙΚΩΝ Η/Υ ΚΑΙ ΠΛΗΡΟΦΟΡΙΚΗΣ

FORTRAN & Αντικειμενοστραφής Προγραμματισμός ΣΝΜΜ 2016

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

QuakeTM: Parallelizing a Complex Sequential Application Using Transactional Memory (Gajinov et al., 2009)

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

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

Διπλωματική Εργασία του φοιτητή του Τμήματος Ηλεκτρολόγων Μηχανικών και Τεχνολογίας Υπολογιστών της Πολυτεχνικής Σχολής του Πανεπιστημίου Πατρών

FORTRAN & Αντικειμενοστραφής Προγραμματισμός ΣΝΜΜ 2017

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

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

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Ανάπτυξη Μεγάλων Εφαρµογών στη Γλώσσα C (Programming in the large)

ΗΥ-150. Προγραµµατισµός. Εντολές Ελέγχου Ροής

ΤΕΧΝΟΛΟΓΙΑ ΚΑΙ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΑΤΡΩΝ ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΜΗΧΑΝΙΚΩΝ Η/Υ ΚΑΙ ΠΛΗΡΟΦΟΡΙΚΗΣ

ΤΕΙ ΙΟΝΙΩΝ ΝΗΣΩΝ ΣΧΟΛΗ ΔΙΟΙΚΗΣΗΣ ΚΑΙ ΟΙΚΟΝΟΜΙΑΣ ΤΜΗΜΑ ΔΙΟΙΚΗΣΗΣ ΕΠΙΧΕΙΡΗΣΕΩΝ - ΕΙΣ

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

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

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

Προγραμματισμό για ΗΜΥ

Προγραμματισμός Υπολογιστών & Υπολογιστική Φυσική

Προγραμματισμός Η/Υ 1 (Εργαστήριο)

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

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

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

Εισαγωγή στην C. Μορφή Προγράµµατος σε γλώσσα C

ΕΡΓΑΣΤΗΡΙΟ 1 ΕΙΣΑΓΩΓΗ ΣΤΗ C. Τµήµα Πληροφορικής και Τηλεπικοινωνιών

Παρακάτω δίνεται o σκελετός προγράμματος σε γλώσσα C. Σχολιάστε κάθε γραμμή του κώδικα.

Αντικειµενοστρεφής Προγραµµατισµός

Επανάληψη για τις Τελικές εξετάσεις

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

Οδηγός OpenMp. Εργαστήριο Ψηφιακών Συστημάτων και Αρχιτεκτονικής Υπολογιστών

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

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

Γλώσσα Προγραμματισμού C++ Εισαγωγή - Μια πρώτη ματιά

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

Ανάπτυξη και Σχεδίαση Λογισμικού

Διάλεξη 6: Δείκτες και Πίνακες

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

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Εισαγωγή στη Java II

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Εισαγωγή στη Java

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

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

FORTRAN και Αντικειμενοστραφής Προγραμματισμός

int array[10]; double arr[5]; char pin[20]; Προγραµµατισµός Ι

Κατηγορίες Νηµάτων. Νήµατα Επιπέδου Πυρήνα. Νήµατα Επιπέδου Χρήστη. «Νήµατα Επιπέδου Χρήστη» Ε-85: Ειδικά Θέµατα Λογισµικού

Προγραμματισμός και Χρήση Ηλεκτρονικών Υπολογιστών - Βασικά Εργαλεία Λογισμικού

8 FORTRAN 77/90/95/2003

FORTRAN και Αντικειμενοστραφής Προγραμματισμός

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

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

ΕισαγωγήστουςΗ/Υ. PHP Hypertext Preprocessor

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

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

Κεφάλαιο Πίνακες Ι. ( ιάλεξη 15) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Ανάπτυξη Μεγάλων Εφαρµογών στη Γλώσσα C (2)

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

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

C Programming EPL032 Maria Stavrinou Ioannou Εισαγωγή στη Γλώσσα C

Ανάλυση ροής δεδομένων και autoscoping στον παραλληλοποιητικό μεταφραστή OMPi

Η Γλώσσα Προγραµµατισµού C++ (The C++ Programming Language) Ιστοσελίδα του µαθήµατος. Περιεχόµενα. ηµήτριος Κατσαρός, Ph.D. Κλάσεις.

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

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

είκτες και Πίνακες (2)

Άρα, Τ ser = (A 0 +B 0 +B 0 +A 0 ) επίπεδο 0 + (A 1 +B 1 +A 1 ) επίπεδο 1 + +(B 5 ) επίπεδο 5 = 25[χρονικές µονάδες]

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Εισαγωγή στη Java II

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Κεφάλαιο 8.7. Πίνακες & Συναρτήσεις ( ιάλεξη 17) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Transcript:

Εισαγωγή στον Προγραµµατισµό Πολυεπεξεργαστικών Συστηµάτων Κοινής Μνήµης µε... Λογισµικό & Προγραµµατισµός Συστηµάτων Υψηλής Επίδοσης Εργαστήριο Πληροφοριακών Συστηµάτων Υψηλών Επιδόσεων Τοµέας Λογικού Τµηµα Μηχ. Η/Υ & Πληροφορικής

Παράλληλος Υπολογισµός: Στο Hardware Πάµε Καλά Time 1998 2000 2002 Cluster SMP 100Mb 16 Boxes 32 Boxes 256+ Boxes VIA > 1Gb, Infiniband Περιορίζεται από τις ανάγκες της αγοράς και όχι την τεχνολογία 1-4 CPUs 1-8 CPUs 1-16 CPUs Processor Pentium II Xeon TM PIII, IA-64 64 Merced P4, IA-64 64 McKinley

Παράλληλος υπολογισµός: όµως τι γίνεται µε το software; Οι περισσότεροι συγγραφείς εφαρµογών αγνοούν τον παραλληλισµό (εκτός ίσως από αδρά καταµερισµένο (βαρύ) πολυνηµατισµό γιαgui s και λογισµικό συστήµατος) Γιατί; Οι δυσκολίες συγγραφής παράλληλου software υπερνικούν τα πλεονεκτήµατα Τα πλεονεκτήµατα είναι ξεκάθαρα. Για να αυξηθεί ο όγκος του παράλληλου software πρέπει να ελαχιστοποιηθούν οι δυσκολίες.

Παράδειγµα: Πρόγραµµα π. Η Ακολουθιακή Έκδοση static long num_steps = 100000; double step; void main () { int i; double x, pi, sum = 0.0; step = 1.0/(double) num_steps; for (i=1;i<= num_steps; i++){ x = (i-0.5)*step; sum = sum + 4.0/(1.0+x*x); pi = step * sum;

Πρόγραµµα π: Win32 API #include <windows.h> #define NUM_THREADS 2 HANDLE thread_handles[num_threads]; CRITICAL_SECTION hupdatemutex; static long num_steps = 100000; double step; double global_sum = 0.0; void Pi (void *arg) { int i, start; double x, sum = 0.0; start = *(int *) arg; step = 1.0/(double) num_steps; for (i=start;i<= num_steps; i=i+num_threads){ x = (i-0.5)*step; sum = sum + 4.0/(1.0+x*x); EnterCriticalSection(&hUpdateMutex); global_sum += sum; LeaveCriticalSection(&hUpdateMutex); void main () { double pi; int i; DWORD threadid; int threadarg[num_threads]; for(i=0; i<num_threads; i++) threadarg[i] = i+1; InitializeCriticalSection(&hUpdateMutex); for (i=0; i<num_threads; i++){ thread_handles[i] = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) Pi, &threadarg[i], 0, &threadid); WaitForMultipleObjects(NUM_THREADS, thread_handles, TRUE,INFINITE); pi = global_sum * step; printf(" pi is %f \n",pi); ιπλασιάζεται το µέγεθος του κώδικα!

Πρόγραµµα π: H λύση του OpenMP #include <omp.h> static long num_steps = 100000; double step; #define NUM_THREADS 2 void main () { int i; double x, pi, sum = 0.0; step = 1.0/(double) num_steps; omp_set_num_threads(num_threads) #pragma omp parallel for reduction(+:sum) private(x) for (i=1;i<= num_steps; i++){ x = (i-0.5)*step; sum = sum + 4.0/(1.0+x*x); pi = step * sum;

OpenMP: Εισαγωγή C$OMP parallel do shared(a, b, c) C$OMP FLUSH #pragma omp critical OpenMP: API για τη συγγραφή πολυνηµατικών εφαρµογών C$OMP THREADPRIVATE(/ABC/) #pragma omp parallel for private(a, B) CALL OMP_SET_NUM_THREADS(10) call omp_test_lock(jlok) Σύνολο οδηγιών προς τον µεταγλωττιστή και call OMP_INIT_LOCK (ilok) C$OMP MASTER συναρτήσεων βιβλιοθήκης, C$OMP διαθέσιµο ATOMIC στον C$OMP SINGLE προγραµµατιστή PRIVATE(X) παράλληλων setenv OMP_SCHEDULE συστηµάτων dynamic ιευκολύνει τη συγγραφή πολυνηµατικών προγραµµάτων σε Fortran, C and C++ C$OMP PARALLEL DO ORDERED PRIVATE (A, B, C) C$OMP PARALLEL REDUCTION (+: A, B) Πρότυπο που συγκεντρώνει την C$OMP εµπειρία SECTIONS 18 ετών σε προγραµµατισµό πολυεπεξεργαστικών συστηµάτων κοινής µνήµης C$OMP PARALLEL COPYIN(/blk/) C$OMP ORDERED!$OMP BARRIER C$OMP DO lastprivate(xx) Nthrds = OMP_GET_NUM_PROCS() omp_set_lock(lck)

OpenMP: Υποστηρικτές Εταιρείες παραγωγής υλικού Intel, HP, SGI, IBM, SUN, Compaq Εταιρείες παραγωγής λογισµικού KAI (Intel), PGI, PSR, APR, Absoft Εταιρείες παραγωγής εφαρµογών ANSYS, Fluent, Oxford Molecular, NAG, DOE ASCI, Dash, Livermore Software κλπ.

OpenMP: Προγραµµατιστικό Μοντέλο Παραλληλισµός τύπου Fork-Join : To νήµα αρχηγός δηµιουργεί οµάδα νηµάτων σύµφωνα µε τις ανάγκες. Ο παραλληλισµός προστίθεται βαθµιαία: δηλ. το ακολουθιακό πρόγραµµα εξελίσσεται σε παράλληλο πρόγραµµα. Νήµα Αρχηγός Παράλληλα Τµήµατα

OpenMP: Ποια Είναι η Τυπική του Χρήση; Το OpenMP συνήθως χρησιµοποιείται για την παραλληλοποίηση loops: Βρες τα πιο χρονοβόρα loops. Μοίρασε τις επαναλήψεις µεταξύ νηµάτων. ιαίρεσε αυτό το loop µεταξύ πολλαπλών νηµάτων void main() { double Res[1000]; for(int i=0;i<1000;i++) { do_huge_comp(res[i]); Ακολουθιακό πρόγραµµα void main() { double Res[1000]; #pragma omp parallel for for(int i=0;i<1000;i++) { do_huge_comp(res[i]); Παράλληλο πρόγραµµα

OpenMP: Πώς Αλληλεπιδρούν τα Νήµατα; Πλεονέκτηµα : Απόκρυψη «λεπτοµερειών» από τον προγραµµατιστή Μειονέκτηµα : Απόκρυψη πολλών «λεπτοµερειών» από τον προγραµµατιστή µπορεί να βλάψει την επίδοση To OpenMP είναι µοντέλο κοινής µνήµης. Τα νήµατα επικοινωνούν µέσω διαµοιραζόµενων µεταβλητών. Ακούσια διαµοίραση δεδοµένων µπορεί να προκαλέσει races : race : Το αποτέλεσµα του προγράµµατος αλλάζει µε τυχαίο τρόπο αν τα νήµατα εκτελεστούν µε διαφορετική σειρά. Εξάλειψη races : Χρήση συγχρονισµού στα σηµεία που χρειάζεται. Ο συγχρονισµός είναι «ακριβός», άρα : Αλλαγή της δοµής του προγράµµατος και της οργάνωσης των δεδοµένων ώστε να µειωθούν οι απαιτήσεις συγχρονισµού

OpenMP: Μερικές Λεπτοµέρειες Σύνταξης (για Αρχή) Οι περισσότερες «εντολές» OpenMP είναι directives προς τον compiler ή pragmas. Για την C και C++, τα pragmas έχουν τη µορφή: #pragma omp construct [clause [clause] ] Για τη Fortran, τα directives έχουν µία από τις ακόλουθες µορφές: C$OMP construct [clause [clause] ]!$OMP construct [clause [clause] ] *$OMP construct [clause [clause] ] Αφού οι «εντολές» είναι directives και pragmas, ένα πρόγραµµα OpenMP µπορεί να µεταγλωττιστεί από compilers που δεν υποστηρίζουν OpenMP (οι τελευταίοι απλά αγνοούν τα directives / pragmas).

OpenMP: οµηµένα Τµήµατα (Βlocks) Οι περισσότερες «εντολές» OpenMPεφαρµόζονται σε δοµηµένα τµήµατα (blocks) κώδικα. οµηµένο τµήµα: ένα τµήµα κώδικα µε ένα σηµείο εισόδου στην κορυφή και ένα σηµείο εξόδου στο τέλος. Οι µόνες επιτρεπτές διακλαδώσεις είναι εντολές STOP της Fortran και exit() της C/C++. C$OMP PARALLEL 10 wrk(id) = garbage(id) res(id) = wrk(id)**2 if(conv(res(id)) goto 10 C$OMP END PARALLEL print *,id Ένα δοµηµένο τµήµα C$OMP PARALLEL 10 wrk(id) = garbage(id) 30 res(id)=wrk(id)**2 if(conv(res(id))goto 20 go to 10 C$OMP END PARALLEL if(not_done) goto 30 20 print *, id Ένα µη δοµηµένο τµήµα

OpenMP: Παράλληλα Τµήµατα Νήµατα δηµιουργούνται στο OpenMP (στη C/C++) µε το pragma omp parallel. Για παράδειγµα, για να δηµιουργηθεί ένα παράλληλο τµήµα µε 4 νήµατα: Κάθε νήµα εκτελεί για λογαριασµό του τον κώδικα µέσα στο δοµηµένο block του παράλληλου τµήµατος double A[1000]; omp_set_num_threads(4); #pragma omp parallel { int ID = omp_thread_num(); pooh(id,a); Κάθε νήµα καλεί την pooh(id) για ID = 0 έως 3

OpenMP: Παράλληλα Τµήµατα Κάθε νήµα εκτελεί για λογαριασµό του τον ίδιο κώδικα. double A[1000]; omp_set_num_threads(4) double A[1000]; omp_set_num_threads(4); #pragma omp parallel { int ID = omp_thread_num(); pooh(id, A); printf( all done\n ); Ένα µοναδικό αντίγραφο του Α µοιράζεται µεταξύ των νηµάτων. pooh(0,a) printf( all done\n ); pooh(1,a) pooh(2,a) pooh(3,a) Τα νήµατα προχωρούν µόνο όταν έχουν τελειώσει όλα (δηλ. barrier)

Άσκηση 1: Ένα πολυνηµατικό πρόγραµµα Hello world Γράψτε ένα πολυνηµατικό πρόγραµµα στο οποίο κάθε νήµα τυπώνει ένα απλό νήµατα (π.χ. hello world ). Χρησιµοποιήστε 2 ξεχωριστές εντολές printf και το thread ID: int ID = omp_get_thread_num(); printf( hello(%d), ID); printf( world(%d), ID); Τι γίνεται όταν εκτελείται ταυτόχρονα I/O από πολλαπλά νήµατα;

OpenMP: Μερικές Πρώτες Λεπτοµέρειες Dynamic mode (default): Ο αριθµός των νηµάτων που χρησιµοποιούνται για την εκτέλεση παράλληλων τµηµάτων µπορεί να διαφέρει µεταξύ διαφορετικών τµηµάτων. Ο ορισµός του αριθµού των νηµάτων αφορά τον µέγιστο αριθµό νηµάτων ενδεχοµένως η εκτέλεση να γίνει µε λιγότερα νήµατα. Static mode: Ο αριθµός των νηµάτων είναι σταθερός και µάλιστα ακριβώς αυτός που καθορίζεται από τον προγραµµατιστή. Το OpenMP υποστηρίζει εµφωλευµένα παράλληλα τµήµατα, όµως Ένας compiler ενδεχοµένως να επιλέξει να εκτελέσει σειριακά όλα τα επίπεδα µετά το 1ο.

OpenMP: οµές ιαµοίρασης Έργου Το omp for κατανέµει τις επαναλήψεις ενός loop µεταξύ των νηµάτων µιας οµάδας #pragma omp parallel #pragma omp for for (I=0;I<N;I++){ NEAT_STUFF(I); Εξ ορισµού υπονοείται barrier στο τέλος του omp for. Για να αφαιρεθεί το barrier χρησιµοποιούµε την παράµετρο nowait

οµές ιαµοίρασης Έργου: Γιατί Είναι Χρήσιµες; (Παράδειγµα) Ακολουθιακός Κώδικας Παράλληλο Τµήµα OpenMP Παράλληλο τµήµα OpenMP µε omp for για διαµοίραση έργου for(i=0;i<n;i++) { a[i] = a[i] + b[i]; #pragma omp parallel { int id, i, Nthrds, istart, iend; id = omp_get_thread_num(); Nthrds = omp_get_num_threads(); istart = id * N / Nthrds; iend = (id+1) * N / Nthrds; for(i=istart;i<iend;i++) { a[i] = a[i] + b[i]; #pragma omp parallel #pragma omp for schedule(static) for(i=0;i<n;i++) { a[i] = a[i] + b[i];

Εντολή omp for: Η Παράµετρος schedule Η παράµετρος schedule επηρεάζει την κατανοµή των επαναλήψεων στα νήµατα schedule(static [,chunk]) Μοίρασε «κοµµάτια» επαναλήψεων µεγέθους chunk κυκλικά στα νήµατα schedule(dynamic[,chunk]) Κάθε νήµα παίρνει chunk iterations από µια ουρά µέχρι να εξαντληθούν οι επαναλήψεις schedule(guided[,chunk]) Τα νήµατα παίρνουν δυναµικά «κοµµάτια» επαναλήψεων. Το µέγεθος των κοµµατιών είναι αρχικά µεγάλο και µειώνεται σταδιακά σε µέγεθος chunk schedule(runtime) Ο τρόπος scheduling και η παράµετρος chunk λαµβάνονται δυναµικά, κατά το χρόνο εκτέλεσης από τις κατάλληλες µεταβλητές περιβάλλοντος.

OpenMP: οµές ιαµοίρασης Έργου Ηδοµή διαµοίρασης έργου sections αναθέτει ένα διαφορετικό δοµηµένο block σε κάθε νήµα #pragma omp parallel #pragma omp sections { X_calculation(); #pragma omp section y_calculation(); #pragma omp section z_calculation(); Εξ ορισµού υπονοείται barrier στο τέλος του omp sections. Για να αφαιρεθεί το barrier χρησιµοποιούµε την παράµετρο nowait

OpenMP: Συνδυασµός της Εντολής parallel µε οµές ιαµοίρασης Έργου #pragma omp parallel for for (I=0;I<N;I++){ NEAT_STUFF(I); Υπάρχει και parallel sections

Άσκηση 2: Πολυνηµατικό Πρόγραµµα Υπολογισµού του π Στην επόµενη διαφάνεια θα δείτε ένα πρόγραµµα που χρησιµοποιεί αριθµητική ολοκλήρωση για τον υπολογισµό προσέγγισης του π. Παραλληλοποιήστε το πρόγραµµα χρησιµοποιώντας OpenMP. Υπάρχουν εναλλακτικές επιλογές Σαν πρόγραµµα SPMD µε χρήση παράλληλου τµήµατος µόνο. Με χρήση δοµής διαµοίρασης έργου. Πρέπει να διασφαλίσετε ότι το ένα νήµα δεν θα γράφει πάνω στις µεταβλητές του άλλου.

Πρόγραµµα π: H Ακολουθιακή Έκδοση static long num_steps = 100000; double step; void main () { int i; double x, pi, sum = 0.0; step = 1.0/(double) num_steps; for (i=1;i<= num_steps; i++){ x = (i-0.5)*step; sum = sum + 4.0/(1.0+x*x); pi = step * sum;

Πρόγραµµα π: H Έκδοση µε Παράλληλο Τµήµα (SPMD) #include <omp.h> static long num_steps = 100000; double step; #define NUM_THREADS 2 void main () { int i; double x, pi, sum[num_threads]; step = 1.0/(double) num_steps; omp_set_num_threads(num_threads) #pragma omp parallel { double x; int id; id = omp_get_thread_num(); Προγράµ- µατα SPMD Κάθε νήµα εκτελεί τον ίδιο κώδικα. Το ID του νήµατος χρησιµοποιείται για τη διαφοροποίηση της συµπεριφοράς. for (i=id, sum[id]=0.0;i< num_steps; i=i+num_threads){ x = (i+0.5)*step; sum[id] += 4.0/(1.0+x*x); for(i=0, pi=0.0;i<num_threads;i++)pi += sum[i] * step;

Πρόγραµµα π: Η Έκδοση µε οµή ιαµοίρασης Έργου #include <omp.h> static long num_steps = 100000; double step; #define NUM_THREADS 2 void main () { int i; double x, pi, sum[num_threads]; step = 1.0/(double) num_steps; omp_set_num_threads(num_threads) #pragma omp parallel { double x; int id; id = omp_get_thread_num(); sum[id] = 0; #pragma omp for for (i=id;i< num_steps; i++){ x = (i+0.5)*step; sum[id] += 4.0/(1.0+x*x); for(i=0, pi=0.0;i<num_threads;i++)pi += sum[i] * step;

OpenMP: Περισσότερες Λεπτοµέρειες: Scope των Εντολών OpenMP Εντολές OpenMP µπορεί να επεκτείνονται σε πολλά αρχεία. C$OMP PARALLEL call whoami C$OMP END PARALLEL Static ή lexical extent του παράλληλου τµήµατος poo.f Dynamic extent του παράλληλου τµήµατος: περιλαµβάνει το static extent + bar.f subroutine whoami external omp_get_thread_num integer iam, omp_get_thread_num iam = omp_get_thread_num() C$OMP CRITICAL print*, Hello from, iam C$OMP END CRITICAL Orphan directives return εµφανίζονται εκτός end παράλληλου τµήµατος

Περιβάλλον εδοµένων: Default Χαρακτηριστικά Αποθήκευσης εδοµένων Προγραµµατιστικό µοντέλο κοινής µνήµης: Οι περισσότερες µεταβλητές είναι by default κοινές Οι global µεταβλητές είναι κοινές µεταξύ των νηµάτων Fortran: COMMON blocks, SAVE variables, MODULE variables C: File scope variables, static Όµως δεν είναι τα πάντα κοινά... Οι stack variables σε υπο-προγράµµατα που καλούνται από παράλληλα τµήµατα είναι ιδιωτικές Οι automatic variables µέσα σε ένα δοµηµένο block εντολών είναι ιδιωτικές.

Περιβάλλον εδοµένων: Παραδείγµατα Χαρακτηριστικών Αποθήκευσης εδοµένων program sort common /input/ A(10) integer index(10) call input C$OMP PARALLEL call work(index) C$OMP END PARALLEL print*, index(1) Τα A, index και count είναι κοινά µεταξύ των νηµάτων. Το temp είναι ιδιωτικό σε κάθε νήµα A, index, count subroutine work common /input/ A(10) real temp(10) integer count save count temp temp temp A, index, count

Περιβάλλον εδοµένων: Αλλαγή των Χαρακτηριστικών Αποθήκευσης Ο προγραµµατιστής µπορεί να αλλάξει τα χαρακτηριστικά αποθήκευσης των µεταβλητών χρησιµοποιώντας ένα από τα ακόλουθα SHARED PRIVATE FIRSTPRIVATE THREADPRIVATE Η τιµή µιας ιδιωτικής µεταβλητής εντός ενός παράλληλου loop µπορεί να «µεταδοθεί» σαν καθολική τιµή εκτός του loop µε τη: LASTPRIVATE H default συµπεριφορά µπορεί να µεταβληθεί µε τη: DEFAULT (PRIVATE SHARED NONE) Όλες οι εντολές αυτής της διαφάνειας έχουν ισχύ στο lexical extent της εντολής OpenMP. Όλες οι εντολές δεδοµένων εφαρµόζονται σε παράλληλα τµήµατα και δοµές διαµοίρασης έργου εκτός της shared η οποία εφαρµόζεται µόνο σε παράλληλα τµήµατα.

Εντολή private Η private(var) δηµιουργεί ιδιωτικό αντίγραφο της var για κάθε νήµα Η τιµή δεν είναι αρχικοποιηµένη Το ιδιωτικό αντίγραφο δεν συσχετίζεται (όσον αφορά τον χώρο αποθήκευσης) µε το αυθεντικό Παρά την αρχικοποίηση, το IS έχει ακαθόριστη τιµή σε αυτό το σηµείο program wrong IS = 0 C$OMP PARALLEL DO PRIVATE(IS) DO J=1,1000 IS = IS + J 1000 CONTINUE print *, IS Το IS δεν έχει αρχικοποιηθεί

Εντολή firstprivate Firstprivate : ειδική περίπτωση του private. To ιδιωτικό αντίγραφο κάθε νήµατος αρχικοποιείται µε την αντίστοιχη τιµή του νήµατος αρχηγού. program almost_right IS = 0 C$OMP PARALLEL DO FIRSTPRIVATE(IS) DO J=1,1000 IS = IS + J 1000 CONTINUE print *, IS Κάθε νήµα έχει ιδιωτικό αντίγραφο του IS µε αρχική τιµή 0 Παρά την αρχικοποίηση, το IS έχει ακαθόριστη τιµή σε αυτό το σηµείο

Εντολή lastprivate Περνά την τιµή της ιδιωτικής µεταβλητής από την τελευταία επανάληψη που εκτελέστηκε στην καθολική µεταβλητή program closer IS = 0 C$OMP PARALLEL DO FIRSTPRIVATE(IS) C$OMP+ LASTPRIVATE(IS) DO J=1,1000 IS = IS + J 1000 CONTINUE print *, IS Κάθε νήµα έχει ιδιωτικό αντίγραφο του IS µε αρχική τιµή 0 Το IS έχει την τιµή που είχε στην τελευταία επανάληψη (δηλ. για J=1000)

OpenMP: Άλλο ένα Παράδειγµα Σχετικά µε το Περιβάλλον εδοµένων Παράδειγµα µε χρήση των PRIVATE και FIRSTPRIVATE αρχικά οι µεταβλητές A,B, και C = 1 C$OMP PARALLEL PRIVATE(B) C$OMP& FIRSTPRIVATE(C) Μέσα στο παράλληλο τµήµα : Το A είναι κοινό µεταξύ των νηµάτων και ίσο µε 1 Τα B και C είναι ιδιωτικά σε κάθε νήµα. Το B έχει ακαθόριστη αρχική τιµή Το C έχει αρχική τιµή 1 Μετά το παράλληλο τµήµα : Οι τιµές των Β και C είναι ακαθόριστες

OpenMP: Eντολή Default Ηεξ ορισµού τιµή είναι DEFAULT(SHARED) (οπότε αν αυτή είναι η επιθυµητή συµπεριφορά δεν χρειάζεται να κάνουµε τίποτε) Για να αλλάξουµε την εξ ορισµού σηµπεριφορά: DEFAULT(PRIVATE) κάθε µεταβλητή στο static extent του παράλληλου τµήµατος γίνεται ιδιωτική (σαν να είχε καθοριστεί αυτό ρητά µε εντολή private) DEFAULT(NONE): καµία εξ ορισµού συµπεριφορά για τις µεταβλητές στο static extent. Πρέπει να καθοριστεί ρητά η συµπεριφορά για όλες τις µεταβλητές Μόνο το Fortran API υποστηρίζει default(private). Η C/C++ υποστηρίζει µόνο default(shared) ή default(none).

OpenMP: Παράδειγµα Εντολής Default itotal = 1000 C$OMP PARALLEL PRIVATE(np, each) np = omp_get_num_threads() each = itotal/np C$OMP END PARALLEL itotal = 1000 C$OMP PARALLEL DEFAULT(PRIVATE) SHARED(itotal) np = omp_get_num_threads() each = itotal/np C$OMP END PARALLEL Οι δύο κώδικες είναι ισοδύναµοι

Threadprivate Κάνει global δεδοµένα ιδιωτικά σε κάθε νήµα Fortran: COMMON blocks C: File scope και static variables ιαφορετική συµπεριφορά από το PRIVATE Με το PRIVATE οι global µεταβλητές αποκρύπτονται. Το THREADPRIVATE διατηρεί το global scope σε κάθε νήµα Οι µεταβλητές threadprivate µπορούν να αρχικοποιηθούν χρησιµοποιώντας εντολές COPYIN ή DATA.

Παράδειγµα threadprivate Θεωρήστε 2 διαφορετικές συναρτήσεις που καλούνται εντός του ίδιου παράλληλου τµήµατος. subroutine poo parameter (N=1000) common/buf/a(n),b(n) C$OMP THREADPRIVATE(/buf/) do i=1, N B(i)= const* A(i) end do return end subroutine bar parameter (N=1000) common/buf/a(n),b(n) C$OMP THREADPRIVATE(/buf/) do i=1, N A(i) = sqrt(b(i)) end do return end Εξαιτίας της εντολής threadprivate, κάθε νήµα που εκτελεί αυτές τις συναρτήσεις έχει δικό του αντίγραφο του common block /buf/.

OpenMP: Reduction Επηρεάζει στην ουσία τον τρόπο «διαµοίρασης» των µεταβλητών: reduction (op : list) Οι µεταβλητές στο list πρέπει να είναι shared στο παράλληλο τµήµα στου οποίου το scope βρισκόµαστε. Εντός µια δοµής parallel ή διαµοίρασης εργασίας: ηµιουργείται τοπικό αντίγραφο κάθε µεταβλητής της λίστας και αρχικοποιείται (ανάλογα µε την πράξη op π.χ. 0 για + ) Τα τοπικά αντίγραφα συνδυάζονται ώστε να εκφυλιστούν σε ένα µοναδικό global αντίγραφο στο τέλος της δοµής

OpenMP: Παράδειγµα reduction #include <omp.h> #define NUM_THREADS 2 void main () { int i; double ZZ, func(), res=0.0; omp_set_num_threads(num_threads) #pragma omp parallel for reduction(+:res) private(zz) for (i=0; i< 1000; i++){ ZZ = func(i); res = res + ZZ;

Άσκηση 3: Πολυνηµατικό Πρόγραµµα π Επιστρέψτε στο πρόγραµµα υπολογισµού προσέγγισης του πκαι αυτή τη φορά, χρησιµοποιήστε private, reduction και µια δοµή διαµοίρασης έργου για την παραλληλοποίησή του. Πόσο µοιάζει στο αρχικό, ακολουθιακό πρόγραµµα;

OpenMP Πρόγραµµα π : Parallel for µε reduction #include <omp.h> static long num_steps = 100000; double step; #define NUM_THREADS 2 void main () { int i; double x, pi, sum = 0.0; step = 1.0/(double) num_steps; omp_set_num_threads(num_threads) #pragma omp parallel for reduction(+:sum) private(x) for (i=1;i<= num_steps; i++){ x = (i-0.5)*step; sum = sum + 4.0/(1.0+x*x); pi = step * sum; To OpenMP προσθέτει 2-4 γραµµές κώδικα

OpenMP: Συγχρονισµός To OpenMPορίζει τις ακόλουθες εντολές για την υποστήριξη συγχρονισµού: atomic critical section barrier flush ordered single master Στην πραγµατικότητα είναι δοµή διαµοίρασης έργου που περιλαµβάνει συγχρονισµό. Στην ουσία δεν είναι εντολή συγχρονισµού.

OpenMP: Συγχρονισµός Μόνο ένα νήµα µπορεί κάθε στιγµή να µπει στο critical section. C$OMP PARALLEL DO PRIVATE(B) C$OMP& SHARED(RES) DO 100 I=1,NITERS B = DOIT(I) C$OMP CRITICAL CALL CONSUME (B, RES) C$OMP END CRITICAL 100 CONTINUE

OpenMP: Συγχρονισµός To atomicείναι ειδική περίπτωση του critical section που µπορεί να χρησιµοποιηθεί για ορισµένες απλές εντολές. Εφαρµόζεται µόνο για την ανανέωση µιας θέσης µνήµης (την ανανέωση του X στο ακόλουθο παράδειγµα) C$OMP PARALLEL PRIVATE(B) B = DOIT(I) C$OMP ATOMIC X = X + B C$OMP END PARALLEL

OpenMP: Συγχρονισµός Barrier: Κάθε νήµα περιµένει να φτάσουν όλα τα υπόλοιπα νήµατα πριν προχωρήσει. #pragma omp parallel shared (A, B, C) private(id) { id=omp_get_thread_num(); A[id] = big_calc1(id); #pragma omp barrier #pragma omp for for(i=0;i<n;i++){c[i]=big_calc3(i,a); #pragma omp for nowait for(i=0;i<n;i++){ B[i]=big_calc2(C, i); A[id] = big_calc3(id); Υπονοούµενο barrier στο τέλος παράλληλου τµήµατος υπονοούµενο barrier στο τέλος ενός omp for εν υπάρχει υπονοούµενο barrier λόγω nowait

OpenMP: Συγχρονισµός Ηεντολήordered επιβάλει την ακολουθιακή σειρά εκτέλεσης για ένα block. #pragma omp parallel private (tmp) #pragma omp for ordered for (I=0;I<N;I++){ tmp = NEAT_STUFF(I); #pragma ordered res = consum(tmp);

OpenMP: Συγχρονισµός Ηεντολήmaster χαρακτηρίζει ένα δοµηµένο block το οποίο εκτελείται µόνο από το νήµα - αρχηγό. Τα υπόλοιπα νήµατα το αγνοούν (δεν υπάρχουν υπονοούµενα barriers ή flushes). #pragma omp parallel private (tmp) { do_many_things(); #pragma omp master { exchange_boundaries(); #pragma barrier do_many_other_things();

OpenMP: Συγχρονισµός Ηεντολή single χαρακτηρίζει ένα block κώδικα το οποίο εκτελείται από ένα µόνο νήµα. Υπονοούνται barrier και flush στο τέλος του single block. #pragma omp parallel private (tmp) { do_many_things(); #pragma omp single { exchange_boundaries(); do_many_other_things();

OpenMP: Συγχρονισµός Ηεντολήflush δηλώνει ένα σηµείο στο οποίο το νήµα επιχειρεί να δηµιουργήσει συνεπή εικόνα της µνήµης. All memory operations (both reads and writes) defined prior to the sequence point must complete. Όλες οι πράξεις µνήµης (αναγνώσεις και εγγραφές) που ορίζονται πριν από αυτό το σηµείο πρέπει να ολοκληρωθούν. Όλες οι πράξεις µνήµης (αναγνώσεις και εγγραφές) που ορίζονται µετά από αυτό το σηµείο πρέπει να εκτελεστούν µετά το flush. Οι µεταβλητές σε registers ή write buffers πρέπει να εγγραφούν στη µνήµη. Τα ορίσµατα του flush ορίζουν ποιες µεταβλητές θα γίνουν flush. Αν δεν υπάρχουν ορίσµατα όλες οι ορατές στο νήµα µεταβλητές γίνονται flush.

OpenMP: Παράδειγµα flush Το παράδειγµα δείχνει πώς χρησιµοποιείται flush για την υλοποίηση συγχρονισµού point-to-point. integer ISYNC(NUM_THREADS) C$OMP PARALLEL DEFAULT (PRIVATE) SHARED (ISYNC) IAM = OMP_GET_THREAD_NUM() ISYNC(IAM) = 0 C$OMP BARRIER CALL WORK() ISYNC(IAM) = 1! I m all done; signal this to other threads C$OMP FLUSH(ISYNC) DO WHILE (ISYNC(NEIGH).EQ. 0) C$OMP FLUSH(ISYNC) END DO C$OMP END PARALLEL Όλα τα άλλα νήµατα θα δουν την εγγραφή µου Ηανάγνωση επιστρέφει «σωστή» τιµή από τη µνήµη.

OpenMP: Υπονοούµενος Συγχρονισµός Barriers υπονοούνται µετά τις ακόλουθες εντολές OpenMP: end parallel end do (except when nowait is used) end sections (except when nowait is used) end critical end single (except when nowiat is used) Flush υπονοείται µετά τις ακόλουθες εντολές OpenMP: barrier critical, end critical end do end parallel end sections end single ordered, end ordered

OpenMP: Συναρτήσεις Bιβλιοθήκης Συναρτήσεις locks omp_init_lock(), omp_set_lock(), omp_unset_lock(), omp_test_lock() Συναρτήσεις περιβάλλοντος χρόνου εκτέλεσης: Αλλαγή/Έλεγχος του αριθµού των νηµάτων omp_set_num_threads(), omp_get_num_threads(), omp_get_thread_num(), omp_get_max_threads() Ενεργοποίηση/απενεργοποίηση εµφώλευσης και dynamic mode omp_set_nested(), omp_set_dynamic(), omp_get_nested(), omp_get_dynamic() Εκτελούµε σε παράλληλο τµήµα; omp_in_parallel() Πόσοι επεξεργαστές υπάρχουν στο σύστηµα; omp_num_procs()

OpenMP: Συναρτήσεις Βιβλιοθήκης Προστασία πόρων µε locks. omp_lock_t lck; omp_init_lock(&lck); #pragma omp parallel private (tmp) { id = omp_get_thread_num(); tmp = do_lots_of_work(id); omp_set_lock(&lck); printf( %d %d, id, tmp); omp_unset_lock(&lck);

OpenMP: Συναρτήσεις Βιβλιοθήκης Για να ελεγχθεί ο αριθµός των νηµάτων που εκτελούν ένα πρόγραµµα αρχικά απενεργοποιείται το dynamic mode και κατόπιν καθορίζεται ο αριθµός των νηµάτων. #include <omp.h> void main() { omp_set_dynamic(0); omp_set_num_threads(4); #pragma omp parallel { int id=omp_get_thread_num(); do_lots_of_stuff(id);

OpenMP: Μεταβλητές Περιβάλλοντος Έλεγχος scheduling των loops εφόσον έχει καθοριστεί omp for schedule(runtime). OMP_SCHEDULE schedule[, chunk_size] Καθορισµός του default αριθµού νηµάτων. OMP_NUM_THREADS int_literal Ενεργοποίηση/απενεργοποίηση dynamic mode OMP_DYNAMIC TRUE FALSE Ενεργοποίηση/απενεργοποίηση παράλληλης εκτέλεσης εµφωλευµένων παράλληλων τµηµάτων OMP_NESTED TRUE FALSE

Βιβλιογραφία - Links http://www.openmp.org OpenMP consortium\ http://developer.intel.com/software/products/compilers Intel Compilers http://www.kai.com Kuck & Associates http://www.pgroup.com Τhe Portland Group http://pdplab.trc.rwcp.or.jp/pdperf/omni/ The OmniMP Compiler http://www.compunity.org OpenMP community http://www.cepba.upc.es/tools/nanos/nanos.htm The NANOS Compiler & Environment OpenMP C and C++ Application Program Interface Version 2.0 Μάρτιος 2002 OpenMP Fortran Application Program Interface Version 2.0 4 Νοεµβρίου 2000

Ευχαριστίες Η παρουσίαση αυτή έχει βασιστεί στο OpenMP tutorial µε τίτλο OpenMP : An API for writing portable SMP application software που παρουσιάστηκε στο SuperComputing 99 Conference από τους Tim Mattson (Intel Corporation) και Rudolf Eigenmann (Purdue University).