ΕΘΝΙΚΟ ΜΕΤΣΟΒΙΟ ΠΟΛΥΤΕΧΝΕΙΟ ΤΜΗΜΑ ΧΗΜΙΚΩΝ ΜΗΧΑΝΙΚΩΝ ΔΠΜ Σ Υ ΠΟΛ ΟΓΙ ΣΤΙΚ ΗΣ ΜΗΧ ΑΝ ΙΚΗ Σ Μάθημα: Υπολογιστικές Τεχνικές και Αλγόριθμοι Επίλυσης Μέρος Ι Διδάσκων: Μανόλης Παπαδρακάκης, Καθηγητής Ε.Μ.Π. ΒΑΣΙΚΕΣ ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ ΣΕ ΠΑΡΑΛΛΗΛΟ ΠΕΡΙΒΑΛΛΟΝ Γιώργος Σταυρουλάκης, Διπλ. Πολ. Μηχ., Διπλ. ΔΠΜΣ Υπολ. Μηχ., Υποψήφιος Διδάκτωρ Ε.Μ.Π. Νοέμβριος 2004
0. Πίνακας περιεχομένων 0. Πίνακας περιεχομένων... 2 1. Εισαγωγή... 3 2. Παράλληλα υπολογιστικά περιβάλλοντα... 5 2.1 Αριθμός επεξεργαστικών μονάδων... 5 2.2 Είδος μνήμης... 6 2.3 Ροή διεργασιών και δεδομένων... 9 3. Μοντέλα ανάπτυξης λογισμικού σε περιβάλλον πολυεπεξεργασίας... 11 3.1 Επικοινωνία και ανταλλαγή μηνυμάτων... 11 3.2 Είδη παραλληλίας και παράλληλων αλγορίθμων... 12 3.3 Εφαρμογή της μεθόδου των πεπερασμένων στοιχείων με το μοντέλο master-slae... 14 4. Λογισμικά ανταλλαγής μηνυμάτων... 17 4.1 Hello world! με τη χρήση του MPI... 18 4.2 Δομή προγραμμάτων MPI... 19 4.3 Εντολές πληροφοριών MPI... 20 4.4 Εντολές αποστολής και λήψης δεδομένων MPI... 20 4.5 Εντολές συλλογικής αποστολής και λήψης δεδομένων MPI... 21 5. Η μέθοδος συζυγών διανυσματικών κλίσεων... 23 5.1 Ο παράλληλος αλγόριθμος... 23 5.2 Ο παράλληλος κώδικας... 24
1. Εισαγωγή Η συνεχής αύξηση ενδιαφέροντος σε ακριβείς εξομοιώσεις πολύπλοκων κατασκευών έχει ως αποτέλεσμα όλο και αυξανόμενες απαιτήσεις σε υπολογιστικούς πόρους και ισχύ. Μοντέλα πεπερασμένων στοιχείων με περισσότερους από 250.000 βαθμούς ελευθερίας (degrees of freedom d.o.f.) συναντώνται συχνά στις αυτοκινητοβιομηχανίες και στην αεροναυπηγική. Ας θεωρήσουμε ως παράδειγμα το μοντέλο του αυτοκινήτου το οποίο απεικονίζεται στο σκίτσο 1.1. Αυτό το μοντέλο κατασκευάστηκε από γνωστή αυτοκινητοβιομηχανία και χρησιμοποιείται για τη μελέτη θορύβου, δονήσεων και κραδασμών και αποτελείται από 264.000 βαθμούς ελευθερίας. Ο υπολογισμός των 50 πρώτων ιδιομορφών αυτού του μοντέλου κάνοντας χρήση του πακέτου MSC/NASTRAN σε έναν CRAY Y-MP με 8 επεξεργαστές απαιτεί 3.289 CPU δευτερόλεπτα και 68.203 Ι/Ο δευτερόλεπτα. Ένα άλλο παράδειγμα μιας πολύ απαιτητικής σε υπολογιστικούς πόρους προσομοίωσης είναι αυτό μιας αεροδιαστημικής ακάτου το οποίο πραγματοποιήθηκε μετά από το ατύχημα του Challenger. Το μοντέλο πεπερασμένων στοιχείων της ακάτου είναι ένα από τα μεγαλύτερα του είδους του το οποίο έχει αναλυθεί με το MSC/NASTRAN και αριθμεί 281.584 βαθμούς ελευθερίας. Μια απλή στατική ανάλυση αυτού του μοντέλου σε έναν CRAY X-MP απαιτεί περίπου 6.5 CPU hours και πάνω από 20 Gigabytes χώρου στο σκληρό δίσκο. Κάνοντας χρήση του ANSYS, η ελαστοπλαστική ανάλυση ενός μοντέλου με 18.678 βαθμούς ελευθερίας το οποίο προσομοίωνε ένα κυλινδρικό τμήμα της ακάτου απαιτεί 18.42 CPU ωρών σε έναν CRAY X- MP. Σε αυτό το σημείο θα πρέπει να αναφέρουμε ότι στα δύο αυτά παραδείγματα, ο CPU χρόνος που αναφέρεται απαιτείται για μόνο μία
ανάλυση. Εντούτοις, όπως είναι γνωστό, ένας πλήρης σχεδιασμός συνήθως απαιτεί δεκάδες αναλύσεων, γεγονός το οποίο πιστοποιείται από το γεγονός ότι χιλιάδες CPU ωρών έχουν χρησιμοποιηθεί για τον σχεδιασμό της ακάτου του δεύτερου παραδείγματος. Από τα ως άνω παραδείγματα γίνεται φανερό ότι οι ανάγκες για υπολογιστική ισχύ (σε σχέση με αυτήν που παρέχεται από έναν επεξεργαστή) είναι ακόμα πολύ αυξημένες και ο μόνος τρόπος για να μπορέσουμε να λύσουμε σε επίπεδο σχεδιασμού πραγματικά προβλήματα είναι με τη χρήση της παράλληλης επεξεργασίας. Ως παράλληλη επεξεργασία ορίζουμε την υπολογιστική διαδικασία η οποία εκτελείται σε υπολογιστικά περιβάλλοντα με περισσότερες της μίας επεξεργαστικές μονάδες οι οποίες λειτουργούν και επεξεργάζονται δεδομένα ταυτόχρονα. Η παράλληλη επεξεργασία χρησιμοποιεί πολλούς επεξεργαστές όπου όλοι εργάζονται προς λύση του ιδίου προβλήματος με στόχο την ισομερή κατανομή του υπολογιστικού φόρτου. Στην ιδανική περίπτωση, αν είναι ο υπολογιστικός χρόνος που απαιτεί μια επεξεργαστική μονάδα για να λύσει ένα πρόβλημα και n ο αριθμός των επεξεργαστικών μονάδων, ο χρόνος που απαιτείται από ένα σύστημα παράλληλης επεξεργασίας για τη λύση του ίδιου προβλήματος είναι ίσος με: t n tn t = n Στα παρακάτω κεφάλαια θα δούμε σε πόσα και ποιά είδη χωρίζονται τα παράλληλα υπολογιστικά περιβάλλοντα, ποιά είδη παράλληλης επεξεργασίας υπάρχουν και με ποιό τρόπο υλοποιούμε προγραμματιστικά αλγορίθμους που κάνουν χρήση της παράλληλης επεξεργασίας.
2. Παράλληλα υπολογιστικά περιβάλλοντα Υπάρχουν πολλοί τύποι υπολογιστικών συστημάτων με δυνατότητες πολυεπεξεργασίας τα οποία μπορούν να χωρισθούν σε κατηγορίες ανάλογα με τον αριθμό των επεξεργαστών, το είδος της μνήμης και τον τρόπο ανταλλαγής μηνυμάτων μεταξύ των επεξεργαστών. Οι κύριες κατηγορίες παράλληλων υπολογιστών, ανάλογα με τον τύπο των βασικών χαρακτηριστικών τους, παρουσιάζονται παρακάτω. 2.1 Αριθμός επεξεργαστικών μονάδων Ανάλογα με τον αριθμό των επεξεργαστικών μονάδων, τα παράλληλα υπολογιστικά περιβάλλοντα διακρίνονται σε: Πυκνής δομής (fine-grained) ή μαζικής παραλληλίας (massiely parallel) όταν αποτελούνται από μερικές εκατοντάδες επεξεργαστικές μονάδες Μεσαίας δομής (medium-grained) όταν αποτελούνται από μερικές δεκάδες επεξεργαστικές μονάδες και Αραιής δομής (coarse-grained) όταν αποτελούνται από μερικούς επεξεργαστές. Επειδή ο αριθμός των επεξεργαστικών μονάδων ενός παράλληλου υπολογιστικού περιβάλλοντος υψηλών επιδόσεων μπορεί να αυξομειώνεται, ένα πολύ σημαντικό χαρακτηριστικό των παράλληλων υπολογιστικών συστημάτων είναι η επεκτασιμότητα τους (scalability), δηλαδή η ιδιότητά τους να επιτυγχάνουν γραμμική αύξηση (στην ιδανική περίπτωση) της απόδοσής τους με την αύξηση του αριθμού των επεξεργαστών. Τα πιο οικονομικά συστήματα παράλληλης επεξεργασίας είναι τα δίκτυα σταθμών εργασίας (workstation networks). Εντούτοις, στην περίπτωση αυτή περιορίζεται η αύξηση της αποτελεσματικότητας του δικτύου με την προσθήκη νέων επεξεργαστικών μονάδων (σταθμοί εργασίας workstations) εξαιτίας της σχετικά αργής επικοινωνίας μεταξύ των επεξεργαστικών μονάδων. Για να επιτευχθεί ικανοποιητική βελτίωση της απόδοσης του συστήματος θα πρέπει η ανταλλαγή δεδομένων μεταξύ των επεξεργαστικών μονάδων να πραγματοποιείται σε μικρό χρονικό διάστημα σε σχέση με αυτό που απαιτείται για τους τοπικούς υπολογισμούς οι οποίοι πραγματοποιούνται σε κάθε επεξεργαστική μονάδα.
2.2 Είδος μνήμης Το είδος μνήμης είναι το σημαντικότερο χαρακτηριστικό των παράλληλων υπολογιστικών συστημάτων διότι επηρεάζει σε μεγάλο βαθμό τον τρόπο ανάπτυξης λογισμικού. Έτσι, ανάλογα με το είδος μνήμης, τα παράλληλα υπολογιστικά περιβάλλοντα διακρίνονται σε: Κοινής μνήμης (shared memory) στα οποία τα δεδομένα του προβλήματος αποθηκεύονται σε μνήμη η οποία είναι διαθέσιμη σε όλες τις επεξεργαστικές μονάδες του υπολογιστικού συστήματος και σε Κατανεμημένης μνήμης (distributed memory) στα οποία τα δεδομένα του προβλήματος κατανέμονται στις τοπικά προσπελαυνόμενες μνήμες των επεξεργαστικών μονάδων του υπολογιστικού συστήματος. Το πρώτο είδος υπολογιστικών συστημάτων συναντάται σε συστήματα υπολογιστών με λίγες επεξεργαστικές μονάδες (αραιής δομής), συνήθως 4 ως και 16, αλλά μεγάλης ισχύος (π.χ. CRAY ή SGI). Τα μειονεκτήματα ενός τέτοιου είδους υπολογιστικών συστημάτων είναι αφενός το μεγάλο κόστος αγοράς και αφετέρου η μέτρια προς κακή επεκτασιμότητά τους αφού η προσπέλαση της κοινής μνήμης γίνεται μέσω διαύλων επικοινωνίας πεπερασμένου εύρους ζώνης (bandwidth). Έτσι, η αύξηση του αριθμού των επεξεργαστικών μονάδων αυξάνει τη συχνότητα προσπέλασης στην κοινή μνήμη και έχει ως αποτέλεσμα τη συμφόρηση των διαύλων επικοινωνίας και κατά συνέπεια πτώση της απόδοσής τους. Τα πλεονεκτήματα ενός τέτοιου υπολογιστικού συστήματος είναι αφενός η αποτελεσματικότερη επικοινωνία μεταξύ των επεξεργαστών (αφού δεν έχομε μετακίνηση δεδομένων από και προς τις τοπικές μνήμες των επεξεργαστών), γεγονός το οποίο συνεπάγεται μεγαλύτερη απόδοση σε σχέση με τα
κατανεμημένης μνήμης, και αφετέρου η ευκολότερη συγγραφή και παραγωγή κατάλληλου λογισμικού σε σχέση με αυτή των υπολογιστικών συστημάτων κατανεμημένης μνήμης. Το δεύτερο είδος υπολογιστικών συστημάτων είναι ένα είδος στο οποίο κάθε επεξεργαστική μονάδα έχει τη δική του μνήμη την οποία δε μοιράζεται με τους υπόλοιπους. Απλώς ανταλλάσσει δεδομένα με μερικές ή και όλες τις υπόλοιπες επεξεργαστικές μονάδες με τη χρήση κατάλληλων διαύλων. Υπάρχουν διάφορες τοπολογίες υπολογιστών με κατανεμημένη μνήμη, όπως π.χ. σειράς, δακτυλίου, καννάβου κλπ. Οι παράμετροι οι οποίες χαρακτηρίζουν αυτή την τοπολογία του δικτύου είναι οι εξής: Η διάμετρος η οποία ορίζεται ως η μέγιστη απόσταση την οποία πρέπει να διανύσει ένα μήνυμα μεταξύ δύο κόμβων Ο βαθμός κάθε κόμβου ο οποίος ορίζεται ως ο αριθμός των συνδέσεων του με άλλους κόμβους Οι ως άνω παράμετροι είναι καθοριστικής σημασίας για μια τοπολογία δικτύου διότι επηρεάζουν σημαντικά το κόστος και την απόδοσή τους.
Τα μειονεκτήματα ενός τέτοιου είδους υπολογιστικών συστημάτων αφενός η δυσκολότερη συγγραφή κατάλληλου λογισμικού το οποίο να εκμεταλλεύεται στο έπακρο την επεξεργαστική ισχύ ενός τέτοιου συστήματος και αφετέρου η επικοινωνία μεταξύ των επεξεργαστικών μονάδων είναι πιο αργή σε σχέση με αυτή των συστημάτων κοινής μνήμης. Αυτό οφείλεται στη χρήση διαύλων μικρότερου εύρους ζώνης και στο γεγονός ότι τα μηνύματα μεταξύ των επεξεργαστικών μονάδων συνήθως περιέχουν πολύ μεγαλύτερη ποσότητα δεδομένων, συγκρινόμενα με αυτά των συστημάτων κοινής μνήμης, διότι σε αυτά πολλές φορές ενυπάρχουν δεδομένα τα οποία δεν είναι διαθέσιμα σε όλες τις επεξεργαστικές μονάδες. Το μεγάλο πλεονέκτημα ενός τέτοιου είδους επεξεργαστικού συστήματος είναι ότι η κατασκευή του μπορεί να γίνει με επεξεργαστικές μονάδες μικρού κόστους. Έτσι, είναι εφικτή η κατασκευή ενός ισχυρού υπολογιστικού συστήματος με σχετικά χαμηλό κόστος με τη συνεχή προσθήκη επεξεργαστικών
μονάδων. Σε αυτή την κατηγορία ανήκουν και τα δίκτυα σταθμών εργασίας στα οποία οι υπολογιστές συνδέονται με καλώδια συρμάτινα ή οπτικών ινών και η παράλληλη εκτέλεση των προγραμμάτων γίνεται με τη χρήση κατάλληλου προγραμματιστικού μέσου διασύνδεσης για εφαρμογές (application programming interface API) για το οποίο θα κάνουμε ιδιαίτερη μνεία σε επόμενο κεφάλαιο. 2.3 Ροή διεργασιών και δεδομένων Κάθε ηλεκτρονικός υπολογιστής έχει, όπως είναι γνωστό, τρία βασικά μέρη: τη μονάδα ελέγχου, τη μονάδα υπολογισμών (ή επεξεργαστή) και τη μνήμη. Οι παράλληλοι υπολογιστές δεν έχουν απαραίτητα πολλαπλά αντίγραφα των ανωτέρω τμημάτων, εκτός από τη μονάδα υπολογισμών. Όπως ήδη έχουμε αναφέρει παραπάνω, η μνήμη μπορεί να είναι κοινή ή κατανεμημένη και κατά ανάλογο τρόπο μπορεί να υπάρχουν μια ή πολλαπλές μονάδες ελέγχου οι οποίες να «δίνουν» οδηγίες (instructions) και δεδομένα (data) στις μονάδες υπολογισμών. Έτσι σύμφωνα με την ταξινόμηση κατά Flynn, τα είδη παράλληλων αρχιτεκτονικών είναι τα εξής: SISD (Single Instruction-Single Data) το οποίο είναι το απλό ακολουθιακό (sequential) μοντέλο υπολογισμών όπου διεξάγεται μία σειρά υπολογισμών ανά ομάδα δεδομένων SIMD (Single Instruction-Multiple Data) στο οποίο οι επεξεργαστικές μονάδες εκτελούν τις ίδιες πράξεις με διαφορετικά δεδομένα. Αυτή η αρχιτεκτονική είναι κατάλληλη για παραλληλία μικρού όγκου υπολογισμών (data-loop parallelism ή fine-grain parallelism) και είναι ανεφάρμοστη σε συστήματα με πολλές επεξεργαστικές μονάδες MISD (Multiple Instruction-Single Data) το οποίο είναι το αντίστροφο του μοντέλου SIMD το οποίο και αποτελεί απλώς μία θεωρητική δυνατότητα με αδυναμία εφαρμογής σε πρακτικά προβλήματα
MIMD (Multiple Instruction-Multiple Data) στο οποίο κάθε επεξεργαστική μονάδα έχει την αυτονομία ενός SISD μοντέλου για αυτό και αποτελεί τη μόνη αρχιτεκτονική γενικής εφαρμογής αφού δεν αντιμετωπίζει τα προβλήματα κανονικότητας των δεδομένων και συγχρονισμού της αρχιτεκτονικής SIMD. Οι συνηθέστερες αρχιτεκτονικές είναι τύπου SIMD ή τύπου MIMD με την επικρατέστερη να είναι τύπου MIMD. Σε αυτό το σημείο θα ήταν σκόπιμο να υπενθυμίσουμε ότι εκτός από τα κανονικά συστήματα πολυεπεξεργασίας, μπορούμε να χρησιμοποιήσουμε ένα δίκτυο υπολογιστών, είτε σειριακών είτε παράλληλων, ως ένα ενιαίο υπολογιστικό περιβάλλον πολυεπεξεργασίας με τη χρήση κατάλληλου API. Τα πιο διαδεδομένα λογισμικά αυτού του τύπου είναι τα PVM (Parallel Virtual Machine) και MPI (Message Passing Interface) με το οποίο και θα ασχοληθούμε εκτενέστερα σε επόμενο κεφάλαιο.
3. Μοντέλα ανάπτυξης λογισμικού σε περιβάλλον πολυεπεξεργασίας Η ανάπτυξη αποτελεσματικών αλγορίθμων που να μπορούν να εκμεταλλευθούν πλήρως τις δυνατότητες των υπερυπολογιστών δεν είναι εύκολο έργο και βασικό ρόλο στην επίτευξη αυτού του στόχου είναι το είδος του αλγορίθμου και η αρχιτεκτονική του συστήματος. Η ανάπτυξη παράλληλου λογισμικού είναι μία διεργασία η οποία συνήθως δεν μπορεί να γίνει αυτόματα. Εντούτοις, υπάρχουν κάποια προγράμματα τα οποία παραλληλοποιούν με αυτόματο τρόπο εφαρμογές οι οποίες έχουν αναπτυχθεί σε σειριακό περιβάλλον. Τα λογισμικά αυτά έχουν δύο βασικά μειονεκτήματα: Η βελτίωση της απόδοσης των κωδίκων που επιτυγχάνουν είναι σχετικά περιορισμένη Ο παράλληλος κώδικας που προκύπτει είναι περίπλοκος αφήνοντας πολύ λίγες δυνατότητες στον προγραμματιστή Κατά συνέπεια, ο προγραμματιστής έχει δύο επιλογές: είτε να προσαρμόσει τον υπολογιστικό κώδικα που χρησιμοποιούσε σε σειριακό περιβάλλον στο παράλληλο σύστημα που διαθέτει, είτε να μορφώσει εξαρχής τον υπολογιστικό κώδικα και να τον προσαρμόσει με μεγαλύτερη αποτελεσματικότητα στις ιδιαιτερότητες της παράλληλης αρχιτεκτονικής. Στην πρώτη περίπτωης, με τη χρήση εργαλείων του παράλληλου συστήματος τα οποία εντοπίζουν τα σημεία του κώδικα τα οποία επιδέχονται παραλληλοποίηση αλλά και της γνώσης των ιδιαιτεροτήτων του υπολογιστικού συστήματος και των αλγορίθμων διαχείρισης και επίλυσης των προβλημάτων που αντιμετωπίζει ο κώδικας είναι δυνατόν να επιτευχθεί μεγάλη μείωση του πραγματικού χρόνου εκτελέσεως των υπολογισμών. Η παραλληλοποίηση των προγραμμάτων επικεντρώνεται στους επαναληπτικούς βρόχους (loops) όπου πραγματοποιείται μεγάλος όγκος υπολογισμών σε κάθε επανάληψη, πολλές φορές χωρίς να υπάρχουν εξαρτήσεις δεδομένων μεταξύ των επαναλήψεων. 3.1 Επικοινωνία και ανταλλαγή μηνυμάτων Συνήθως σε κάθε αριθμητικό αλγοριθμικό κώδικα παράλληλης επεξεργασίας είναι απαραίτητη η ανταλλαγή ή συγκέντρωση δεδομένων σε κάποια φάση των υπολογισμών. Η επικοινωνία μεταξύ των επεξεργαστών πρέπει να ρυθμίζεται κατάλληλα ούτως ώστε να μην υπάρχουν αναμονές των επεξεργαστικών μονάδων αλλά και να μην εκτελούνται υπολογισμοί με μη
επικαιροποιημένα δεδομένα. Οι παράλληλοι αλγόριθμοι πρέπει να αναπτύσσονται με τέτοιο τρόπο, ούτως ώστε να υπάρχει μεγάλος όγκος ανεξάρτητων εργασιών οι οποίες να εκτελούνται παράλληλα για να ελαχιστοποιείται το επικοινωνιακό κόστος. Ακόμα, πρέπει να συγχρονίζονται οι παράλληλες διεργασίες για την αποφυγή συγκρούσεων (collisions) είτε κατά την ανάγνωση και εγγραφών κοινών μεταβλητών στη μνήμη είτε στους διαύλους επικοινωνίας. Τα σημεία όπου οι επεξεργαστικές μονάδες χρειάζεται να επικοινωνήσουν μεταξύ τους ονομάζονται σημεία συγχρονισμού (synchronization points). Η ανταλλαγή των μηνυμάτων μεταξύ των επεξεργαστικών μονάδων γίνεται με τους εξής τρόπους: Χωρίς συγχρονισμό (asynchronous communication) όπου ο αποστολέας του μηνύματος στέλνει ένα μήνυμα στον παραλήπτη και συνεχίζει τους υπολογισμούς που έχει αναλάβει χωρίς επιβεβαίωση ότι το μήνυμα ελήφθη. Με συγχρονισμό (synchronized communication) όπου ο αποστολέας του μηνύματος περιμένει επιβεβαίωση από τον παραλήπτη ότι έλαβε το μήνυμα το οποίο εστάλη και συνεχίζει μετά τους υπολογισμούς που έχει αναλάβει. Ο πρώτος τρόπος είναι και ο ταχύτερος για την ανταλλαγή μηνυμάτων αλλά ενέχει κινδύνους σε περίπτωση σφαλμάτων συστήματος (π.χ. ελαττωματικό καλώδιο σύνδεσης δικτύου) ή υπερφόρτωσης των διαύλων επικοινωνίας. 3.2 Είδη παραλληλίας και παράλληλων αλγορίθμων Τα είδη αλγοριθμικής παραλληλίας παρουσιάζονται παρακάτω και είναι τα εξής: Φυσική παραλληλία (natural parallelism) η οποία αφορά υπολογισμούς οι οποίοι μπορούν να πραγματοποιηθούν ταυτόχρονα χωρίς παρέμβαση του προγραμματιστή σε αλγοριθμικό επίπεδο. Τέτοιοι υπολογισμοί είναι π.χ. η μόρφωση τοπικών μητρώων στιβαρότητας ή ο υπολογισμός των τάσεων στη μέθοδο πεπερασμένων στοιχείων. Τεχνητή ή υπολογιστική παραλληλία (artificial or computational parallelism) η οποία αφορά υπολογισμούς μη επιδεχόμενους φυσική παραλληλοποίηση αλλά απαιτείται χρήση ειδικών υπολογιστικών μεθόδων σε αλγεβρικό επίπεδο για να επιτευχθεί η παραλληλοποίησή τους. Τέτοιοι υπολογισμοί είναι π.χ. η επίλυση
γραμμικών συστημάτων με τη μέθοδο του διαμερισμού των πεδίων σε υποπεδία (domain decompositioning). Είναι προφανές ότι η υλοποίηση αλγορίθμων οι οποίοι εμπίπτουν στο δεύτερο είδος της αλγοριθμικής παραλληλίας παρουσιάζουν σαφώς μεγαλύτερη δυσκολία σε σχέση με το πρώτο. Τα κυριότερα μοντέλα παραλληλοποίησης διεργασιών είναι τα εξής: Pipelining or processor farming όπου όλες οι επεξεργαστικές μονάδες κάνουν χρήση του ίδιου υπολογιστικού κώδικα και των ίδιων δεδομένων. Αυτή η τεχνική έχει μειωμένες απαιτήσεις σε επικοινωνία κατά την εκτέλεση των πράξεων αλλά δεν παρουσιάζει ικανοποιητική επεκτασιμότητα σε πολλούς επεξεργαστές Geometric parallelism όπου κάθε επεξεργαστική μονάδα κάνει χρήση του ίδιου υπολογιστικού κώδικα αλλά διαφορετικών δεδομένων (π.χ. μέθοδος πεπερασμένων στοιχείων με υποφορείς) και ανταλλάσσει πληροφορίες με επεξεργαστικές μονάδες οι οποίες έχουν γειτονικά δεδομένα. Η τεχνική αυτή παρουσιάζει καλή επεκτασιμότητα άρα και ικανοποιητική επιτάχυνση των υπολογισμών Algorithmic parallelism όπου σε κάθε επεξεργαστική μονάδα έχει γίνει κατανομή όχι μόνο διαφορετικών δεδομένων αλλά και διαφορετικού υπολογιστικού κώδικα. Αυτή τεχνική έχει μεγάλο εύρος εφαρμογών αλλά επειδή συνήθως απαιτεί συχνή επικοινωνία μεταξύ των επεξεργαστικών μονάδων δεν παρουσιάζει ικανοποιητική επεκτασιμότητα λόγω υπερφόρτωσης του διαύλου επικοινωνίας. Task farming (master-slae model) όπου μία από τις επεξεργαστικές μονάδες οργανώνει τις υπόλοιπες για την εκτέλεση των υπολογισμών και φροντίζει να κατανέμει ισομερώς τον υπολογιστικό φόρτο, κρατώντας κατ αυτό τον τρόπο συνεχώς απασχολημένες τις επεξεργαστικές μονάδες. Αυτή η τεχνική εφαρμόζεται μόνο σε συστήματα κατανεμημένης μνήμης, είναι αρκετά αποτελεσματική και η απόδοσή της εξαρτάται από τη διαθεσιμότητα της τοπικής μνήμης. Η επιλογή του μοντέλου παραλληλίας που θα χρησιμοποιηθεί κατά την υλοποίηση ενός αλγορίθμου εξαρτάται από το είδος του προβλήματος, δηλαδή το μέγεθος του όγκου των παράλληλων υπολογισμών (granularity) που αναλαμβάνει κάθε επεξεργαστική μονάδα. Το μέγεθος αυτό καθορίζει σε μεγάλο βαθμό και το πόσο καλά είναι μοιρασμένο το υπολογιστικό φορτίο (load balancing) στις επεξεργαστικές μονάδες. Το μέγεθος των παράλληλων υπολογισμών διακρίνεται στις εξής κατηγορίες:
Fine-grain, όπου ο όγκος των παράλληλων υπολογισμών αποτελείται από ελάχιστες αριθμητικές πράξεις Medium-grain, όπου οι παράλληλοι υπολογισμοί είναι μερικές εκατοντάδες ή χιλιάδες αριθμητικές πράξεις Large or coarse-grain, όπου οι υπολογισμοί σε κάθε επεξεργαστικής μονάδας είναι αρκετά εκατομμύρια αριθμητικές πράξεις. Η πρώτη κατηγορία μπορεί να εφαρμοσθεί αποτελεσματικά σε υπολογιστές υψηλών επιδόσεων με διανυσματικές υπολογιστικές δυνατότητες ή σε συστήματα μαζικής παραλληλίας. Η δεύτερη κατηγορία εμφανίζει καλή αναλογία παράλληλων υπολογισμών και επικοινωνιακού κόστους αλλά παρουσιάζει δυσκολίες στην εφαρμογή της σε μεγάλα προβλήματα και σε συστήματα με πολλούς επεξεργαστές. Τέλος το τρίτο είδος, το οποίο έχει την καλύτερη απόδοση αφού μειώνει στο ελάχιστο το επικοινωνιακό κόστος, είναι το πιο κατάλληλο για συστήματα κοινής μνήμης αλλά μπορεί να εμφανίσει προβλήματα όταν η κατανομή του υπολογιστικού φορτίου δεν είναι ισομερής. 3.3 Εφαρμογή της μεθόδου των πεπερασμένων στοιχείων με το μοντέλο master-slae Ένα παράλληλο πρόγραμμα πεπερασμένων στοιχείων υλοποιημένο με το μοντέλο task farming ή master-slae διεξάγει υπολογιστικές διαδικασίες οι οποίες συνοψίζονται στα παρακάτω στάδια: Γένεση δικτύου πεπερασμένων στοιχείων (mesh generation), διαδικασία η οποία παρουσιάζει αρκετές δυσκολίες κατά την παραλληλοποίησή της και για αυτό κατά κανόνα πραγματοποιείται σειριακά από τον master κόμβο. Διαμέριση φορέα σε υποφορείς (mesh partitioning) όπου το δίκτυο πεπερασμένων στοιχείων το οποίο έχει παραχθεί ομαδοποιείται σε υποδίκτυα (submeshes), κάθε ένα από τα οποία ορίζει έναν υποφορέα (substructure or subdomain). Η διαμέριση πραγματοποιείται σειριακά από τον master κόμβο. Ακόμα, αν απαιτείται από τον αλγόριθμο επίλυσης, μπορεί το δίκτυο να χωριστεί σε αριθμό υποφορέων μεγαλύτερο του αριθμού των επεξεργαστικών μονάδων οπότε και πραγματοποιείται επιπλέον η δημιουργία ομάδων υποφορέων (subdomain cluster). Ενεργοποίηση slae κόμβων, διαδικασία κατά την οποία ο master κόμβος, έχοντας στη μνήμη ένα διαμερισμένο σε υποφορείς δίκτυο πεπερασμένων στοιχείων, ενεργοποιεί τις διαδικασίες που
εκτελούνται στους slae κόμβους και αναθέτει σε αυτούς υποφορείς ή ομάδες υποφορέων και τους εφοδιάζει με τα απαραίτητα δεδομένα, όπως συντεταγμένες κόμβων, ιδιότητες υλικών, φορτία κλπ. Τέλος, όλοι οι κόμβοι μορφώνουν τις δομές δεδομένων στις οποίες αποθηκεύονται πληροφορίες προς αποστολή για τη διευκόλυνση της ανταλλαγής μηνυμάτων σε επόμενα στάδια. Μόρφωση μητρώου στιβαρότητας και διανύσματος επικόμβιων δράσεων για κάθε υποφορέα, όπου και αρχίζει ουσιαστικά το παράλληλο τμήμα του λογισμικού ανάλυσης με τη μέθοδο των πεπερασμένων στοιχείων. Οι slae κόμβοι υπολογίζουν παράλληλα τα μητρώα στιβαρότητας και τα διανύσματα επικόμβιων δράσεων των υποφορέων αξιοποιώντας τα δεδομένα που έχουν λάβει από τον master κόμβο στο προηγούμενο στάδιο. Κάθε slae κόμβος πραγματοποιεί τους υπολογισμούς που αντιστοιχούν στους υποφορείς που του έχουν ανατεθεί χωρίς καμία ανάγκη επικοινωνίας με τον master κόμβο. Τέλος, αν απαιτείται η μορφή αποθήκευσης των μητρώων να είναι με τη μορφή ενεργών στηλών (skyline storage), τότε γίνεται επαναρίθμηση των βαθμών ελευθερίας του κάθε υποφορέα, ούτως ώστε να μειωθούν στο ελάχιστο οι απαιτήσεις μνήμης για την αποθήκευσή τους. Η διαδικασία αυτή εκτελείται και αυτή παράλληλα από τους slae κόμβους χωρίς να είναι αναγκαία η επικοινωνία τους με τον master κόμβο. Παραγοντοποίηση μητρώου στιβαρότητας και προσδιορισμός μετακινήσεων στερεού σώματος όπου απαιτείται. Γίνεται παραγοντοποίηση των μητρώου δυσκαμψίας κάθε υποφορέα στους slae κόμβους αφού πρώτα προσδιοριστούν οι κινήσεις στερεού σώματος προκειμένου να γίνουν οι κατάλληλες διαδικασίες για να είναι δυνατή η παραγοντοποίηση του μητρώου. Επίλυση εξισώσεων ισορροπίας. Έχοντας πλέον διαθέσιμες όλες τις απαιτούμενες δομές δεδομένων, καλείται ένας παράλληλος αλγόριθμος επίλυσης συστημάτων γραμμικών εξισώσεων με σκοπό τον υπολογισμό των επικόμβιων μετατοπίσεων των υποφορέων. Στο στάδιο αυτό η επικοινωνία είναι στις περισσότερες περιπτώσεις απαραίτητη. Μετεπεξεργασία αποτελεσμάτων (result post-processing) όπου γίνεται χρήση των υπολογισμένων επικόμβιων μετατοπίσεων με σκοπό τον προσδιορισμό των τάσεων των στοιχείων και, εφόσον απαιτείται, του σφάλματος της λύσης. Οι παραπάνω υπολογισμοί των τάσεων
γίνονται από τους slae κόμβους και εκτελούνται παράλληλα, ενώ αυτοί της εκτίμησης σφάλματος ενδέχεται να χρειάζεται επικοινωνία με τον master κόμβο. Από τα παραπάνω στάδια, γίνεται φανερό ότι, από τη στιγμή που αρχίζουν οι παράλληλοι υπολογισμοί των slae κόμβων, η συμμετοχή του master κόμβου είναι περιορισμένη και ο ίδιος χρησιμοποιείται κυρίως κατά την επίλυση των εξισώσεων ισορροπίας για να συγκεντρώνει, να αθροίζει και να επαναδιανέμει πληροφορίες σχετικές με τους ενδοσυνοριακούς βαθμούς ελευθερίας των υποφορέων. Με αυτό τον τρόπο επιτυγχάνεται η σύνδεση των ανεξάρτητων υπολογισμών που πραγματοποιούν οι slae κόμβοι. Τα απαιτούμενα βήματα επικοινωνίας διεξάγονται αξιοποιώντας αποθηκευμένες πληροφορίες με τις οποίες: οι slae κόμβοι είναι σε θέση να εντοπίζουν τους βαθμούς ελευθερίας των υποφορέων τους που ανήκουν στο σύνορο με άλλους υποφορείς, ενώ ο master κόμβος είναι ενήμερος για τους βαθμούς ελευθερίας που ανήκουν σε κάθε υποφορέα, καθώς και ποιοί από αυτούς τους βαθμούς ελευθερίας ανήκουν στο σύνορο με άλλους υποφορείς. Τέλος, θα πρέπει να σημειώσουμε ότι το στάδιο επίλυσης των εξισώσεων ισορροπίας παρουσιάζει ιδιαίτερο ενδιαφέρον λόγω των απαιτήσεων επικοινωνίας που συνεπάγεται. Η αδυναμία εφαρμογής των άμεσων μεθόδων για την επίλυση των εξισώσεων σε περιβάλλον πολυεπεξεργασίας είχε ως αποτέλεσμα την ανάπτυξη επαναληπτικών μεθόδων επίλυσης για την αξιοποίηση διαδικτυωμένων υπολογιστικών συστημάτων.
4. Λογισμικά ανταλλαγής μηνυμάτων Διάφορα συστήματα μπορούν να χρησιμοποιηθούν για τη διαχείριση των μηνυμάτων που ανταλλάσσονται κατά την εκτέλεση παράλληλων προγραμμάτων σε ένα διαδικτυωμένο υπολογιστικό σύστημα. Τα συστήματα αυτά παρέχουν ρουτίνες-υποπρογράμματα για την ενεργοποίηση διαδικασιών (tasks or processes) ούτως ώστε οι διαδικασίες αυτές να επικοινωνούν και να συγχρονίζονται μεταξύ τους κατά τη διάρκεια της παράλληλης εκτέλεσης των υπολογισμών. Η επικοινωνία μεταξύ τους γίνεται μέσω διαύλων επικοινωνίας ενώ αν μιλάμε για ένα διαδικτυωμένο υπολογιστικό σύστημα τότε γίνεται μέσω καλωδίων ή οπτικών ινών. Τα πιο διαδεδομένα συστήματα ανταλλαγής μηνυμάτων είναι τα εξής: Socket interface ο οποίος παρέχει τη δυνατότητα για κλήσεις συστήματος (system calls) για άμεση πρόσβαση σε υπηρεσίες επικοινωνίας μέσω των πρωτοκόλλων TCP/IP ή UDP. Remote procedure call (RPC) ο οποίος επενεργεί επί των πρωτοκόλλων TCP/IP ή UDP σε υψηλότερο επίπεδο από το προηγούμενο σύστημα αφού κατά τις αιτήσεις για επικοινωνία μέσω του δικτύου πολλές λεπτομέρειες παραμένουν αδιαφανείς για τον προγραμματιστή. Το σύστημα αυτό εφαρμόζεται κατά τη χρήση του μοντέλου task farming ή master-slae αφού η επικοινωνία RPC λαμβάνει τη μορφή μηνυμάτων αίτησης από τον master κόμβο, ο οποίος ζητά να γίνει κάποια εργασία προς κάποιον ή κάποιους slae κόμβους οι οποίοι διεκπεραιώνουν την εργασία και επιστρέφουν δεδομένα στον master κόμβο. API ανταλλαγής μηνυμάτων (message passing APIs) τα οποία παρέχουν ένα σύνολο ρουτινών για τις πιο δημοφιλείς και ευρέως χρησιμοποιούμενες γλώσσες προγραμματισμού ούτως ώστε να είναι δυνατή η διαχείριση των απαιτήσεων επικοινωνίας που παρουσιάζουν οι παράλληλες εφαρμογές κατανεμημένης μνήμης. Τα λογισμικά αυτά, όπως π.χ. το PVM ή το MPI, παρουσιάζονται ως οι πιο διαδεδομένες λύσεις για τη διαχείριση των απαιτήσεων επικοινωνίας σε κατανεμημένα λογισμικά ανάλυσης με τη μέθοδο των πεπερασμένων στοιχείων. Η προτίμηση αυτή βασίζεται στο γεγονός ότι αυτά τα λογισμικά προσφέρουν υψηλού βαθμού μεταφερσιμότητα (portability) και στον σχετικά απλό τρόπο διαχείρισης των απαιτήσεων επικοινωνίας που παρέχονται από τέτοια APIs.
Στη συνέχεια θα ασχοληθούμε με το API MPI και θα δούμε τις κυριότερες ρουτίνες του μαζί με κάποια παραδείγματα γραμμένα στη γλώσσα FORTRAN 90/95. 4.1 Hello world! με τη χρήση του MPI Το πρώτο πρόγραμμα το οποίο συναντάμε σε κάθε εγχειρίδιο προγραμματισμού είναι ένα πρόγραμμα το οποίο απλά τυπώνει το μήνυμα Hello world! και έχει ως στόχο να μας δείξει με τον πιο απλό τρόπο κάποια βασικά χαρακτηριστικά της γλώσσας προγραμματισμού την οποία μελετάμε. Μια παραλλαγή του παραπάνω προγράμματος χρησιμοποιεί παραλληλία απλά με το να «λέει» σε κάθε επεξεργαστική μονάδα, την οποία από εδώ και στο εξής θα την ονομάζουμε διαδικασία (process) να στέλνει ένα μήνυμα χαιρετισμού σε κάποια άλλη επεξεργαστική μονάδα. Στο MPI, οι διαδικασίες οι οποίες συμμετέχουν στην εκτέλεση παράλληλου κώδικα αριθμούνται με μια σειρά θετικών ακεραίων. Έτσι, αν εκτελούνται n διαδικασίες αυτές θα έχουν βαθμό (rank) 0, 1,, n-1. Παρακάτω, παρατίθεται πηγαίος κώδικας σε FORTRAN 95 ο οποίος λέει στις διαδικασίες 1 ως n-1 να στείλουν ένα μήνυμα στη διαδικασία 0 και αυτή τυπώνει στην οθόνη τα μηνύματα τα οποία λαμβάνει. Program MPIHelloWorld Implicit None Include "fmpi.h" Integer :: irank, inoofprocs, ierr, isource, idest, itag=50 Character, Len=50 :: cmessage Type (MPI_Status) :: status Call MPI_Init(iErr) Call MPI_Comm_rank(MPI_COMM_WORLD, irank, ierr) Call MPI_Comm_size(MPI_COMM_WORLD, inoofprocs, ierr) if (irank.gt.0) then idest = 0 Write(cMessage, *) "Greetings from process:", irank Call MPI_Send(cMessage, 50, MPI_CHARACTER, idest, itag, & MPI_COMM_WORLD, ierr) else Do isource=1, inoofprocs 1 Call MPI_Rec(cMessage, 50, MPI_CHARACTER, isource, & itag, MPI_COMM_WORLD, status, ierr) Write(*, *) cmessage End Do end if Call MPI_Finalize(iErr) End Program
Έτσι, κατά την εκτέλεση του παραπάνω πηγαίου κώδικα σε δύο διαδικασίες, θα λάβουμε τα παρακάτω μηνύματα στην οθόνη: Greetings from process: 1 ενώ αν το εκτελέσουμε σε πέντε διαδικασίες θα λάβουμε τα παρακάτω: Greetings from process: 1 Greetings from process: 2 Greetings from process: 3 Greetings from process: 4 Τα γεγονότα τα οποία συμβαίνουν συνοπτικά κατά την εκτέλεση του παραπάνω κώδικα είναι τα εξής: Γίνεται αίτηση στο λειτουργικό σύστημα για την τοποθέτηση ενός αντιγράφου του προγράμματος σε κάθε διαδικασία Κάθε διαδικασία αρχίζει να εκτελεί το πρόγραμμα Διαφορετικές διαδικασίες εκτελούν διαφορετικές εντολές μέσω εντολών διακλάδισης, γεγονός το οποίο βασίζεται στο βαθμό κάθε διαδικασίας 4.2 Δομή προγραμμάτων MPI Σε κάθε πρόγραμμα το οποίο χρησιμοποιεί το MPI για την ανταλλαγή μηνυμάτων κατά την παράλληλη επεξεργασία, θα πρέπει πάντα να υπάρχει η εντολή: Include "fmpi.h" ούτως ώστε να συμπεριληφθούν στη μεταγλώτισση (compilation) του προγράμματος οι απαραίτητες σταθερές και τύποι δεδομένων που χρειάζεται το MPI για τη λειτουργία του. Ακόμα, πρέπει πάντα να γίνεται μια αρχικοποίηση (initialization) στην εκκίνηση της εφαρμογής και μια διεργασία τερματισμού (finalization) στο πέρας της. Αυτό επιτυγχάνεται αντίστοιχα με τις εντολές: και Call MPI_Init(iErr) Call MPI_Finalize(iErr) Οι παραπάνω δυο εντολές παίρνουν ένα μόνο όρισμα τύπου Integer στο οποίο εγγράφεται η τιμή 0 αν όλα έχουν πάει καλά ή κάποια άλλη τιμή η οποία και είναι ο κωδικός σφάλματος αν έχει προκύψει κάποιο σφάλμα κατά την εκτέλεση της εντολής. Αξίζει να σημειώσουμε εδώ ότι όλα τα ορίσματα που
χρησιμοποιούμε θα είναι τύπου Integer εκτός και αν αναφέρουμε κάτι διαφορετικό. Έτσι ένας τυπικός πηγαίος κώδικας σε MPI είναι ως εξής: Program... Implicit None Include "fmpi.h" Integer :: ierr,... Call MPI_Init(iErr)... Call MPI_Finalize(iErr) End Program 4.3 Εντολές πληροφοριών MPI Δύο ακόμα βασικές εντολές οι οποίες χρησιμοποιούνται στο MPI είναι οι ακόλουθες: και Call MPI_Comm_rank(MPI_COMM_WORLD, irank, ierr) Call MPI_Comm_size(MPI_COMM_WORLD, inoofprocs, ierr) Η πρώτη εντολή έχει ως στόχο να τοποθετήσει στο όρισμα irank το βαθμό (rank) της διαδικασίας (process) η οποία εκτελείται εκείνη τη στιγμή. Το όρισμα ierr υπάρχει σε όλες τις εντολές του MPI. Στόχος του είναι, όπως αναφέραμε και προηγουμένως, να αποθηκευθεί σε αυτό κάποιος κωδικός σφάλματος σε περίπτωση που η εντολή δεν έχει εκτελεσθεί επιτυχώς. Τέλος στη θέση του πρώτου ορίσματος τοποθετούμε τη σταθερά MPI_COMM_WORLD και στα προγράμματα MPI με τα οποία θα ασχοληθούμε εδώ θα την χρησιμοποιούμε όπου απαιτείται. Περισσότερες πληροφορίες για τη χρήση αυτής της σταθεράς μπορεί κανείς να βρει στο εγχειρίδιο του MPI. Η δεύτερη εντολή έχει ως στόχο να τοποθετήσει στο όρισμα inoofprocs το συνολικό αριθμό των διεργασιών της εφαρμογής που εκτελούνται ταυτόχρονα, ενώ τα υπόλοιπα ορίσματα έχουν την ίδια ακριβώς χρήση με αυτή της εντολής MPI_Comm_rank. 4.4 Εντολές αποστολής και λήψης δεδομένων MPI Άλλες δύο εντολές που έχουν συχνή χρήση στο MPI και χρησιμοποιούνται για την ανταλλαγή μηνυμάτων μεταξύ των διαφόρων διεργασιών είναι οι εξής: και Call MPI_Send(cMessage, 50, MPI_CHARACTER, idest, itag, & MPI_COMM_WORLD, ierr) Call MPI_Rec(cMessage, 50, MPI_CHARACTER, isource, itag, & MPI_COMM_WORLD, status, ierr)
Η πρώτη εντολή έχει ως στόχο να αποστείλει τα περιεχόμενα του ορίσματος cmessage (το οποίο στην συγκεκριμένη περίπτωση είναι τύπου character αλλά γενικά μπορεί να είναι οποιουδήποτε τύπου) που έχει μήκος 50 (δεύτερο όρισμα) και είναι τύπου char (τρίτο όρισμα το οποίο έχει την τιμή της σταθεράς MPI_CHAR) στη διαδικασία με βαθμό (rank) το περιεχόμενο του ορίσματος idest. Αντιστοιχία τύπων δεδομένων MPI με αυτούς της γλώσσας FORTRAN Τύπος δεδομένων MPI (MPI_DATATYPE) MPI_COMPLEX MPI_DOUBLE_COMPLEX MPI_LOGICAL MPI_REAL MPI_DOUBLE_PRECISION MPI_INTEGER MPI_CHARACTER Τύπος δεδομένων FORTRAN COMPLEX DOUBLE COMPLEX LOGICAL REAL DOUBLE PRECISION INTEGER CHARACTER Στο όρισμα itag περιέχεται ένας αριθμός ο οποίος έχει ως στόχο να δώσει στο μήνυμα το οποίο αποστέλλεται κάποιου είδους ταυτότητα (tag=ετικέττα) και χρησιμοποιείται από τον παραλήπτη για την ταυτοποίησή του. Πρακτικά το όρισμα itag χρησιμοποιείται για να ομαδοποιήσει δεδομένα και μηνύματα τα οποία ανταλλάσσονται μεταξύ των διαδικασιών. Έτσι, αν για παράδειγμα θέλουμε να αποστείλουμε δύο αριθμούς στην ίδια διαδικασία και ο ένας χρησιμοποιείται σε κάποιο υπολογισμό και ο άλλος είναι προς εκτύπωση, μπορούμε να τους στείλουμε με διαφορετικό itag ούτως ώστε να μπορεί ο παραλήπτης να διακρίνει με το κατάλληλο itag ποιός είναι για τους υπολογισμούς και ποιός για την εκτύπωση. Τέλος, τα άλλα δύο ορίσματα έχουνε την ίδια λειτουργία με αυτή που αναφέρθηκε για την εντολή MPI_Comm_rank. 4.5 Εντολές συλλογικής αποστολής και λήψης δεδομένων MPI Σε έναν παράλληλο κώδικα υπάρχει πολλές φορές η ανάγκη είτε λήψης δεδομένων από όλες τις διαδικασίες (slae processes) σε μία κεντρική (master process), π.χ. για την άθροιση όρων ενός εσωτερικού γινομένου το οποίο έχει υπολογιστεί παράλληλα είτε αποστολής δεδομένων από μία διαδικασία σε όλες τις υπόλοιπες. Αυτού του τύπου η επικοινωνία καλείται συλλογική επικοινωνία (collectie communication) και στο MPI χρησιμοποιούνται για την τέλεσή της οι παρακάτω εντολές:
και Call MPI_BCast(Message, isize, MPI_DATATYPE, iroot, & MPI_COMM_WORLD, ierr) Call MPI_Reduce(Operand, Message, isize, MPI_DATATYPE, MPI_OPERAND, & iroot, MPI_COMM_WORLD, ierr) Όνομα τελεστή (MPI_OPERAND) MPI_MAX MPI_MIN MPI_SUM MPI_PROD MPI_LAND MPI_BAND MPI_LOR MPI_BOR MPI_LXOR MPI_BXOR Σημασία Μέγιστο Ελάχιστο Άθροισμα Γινόμενο Logical AND Bitwise AND Logical OR Bitwise OR Logical Exclusie OR Bitwise Exclusie OR Έτσι αν θέλαμε να στείλουμε από τη διαδικασία 0 σε όλες τις διαδικασίες το όρισμα fvalue τύπου double precision θα γράφαμε: Call MPI_BCast(fValue, 1, MPI_DOULBE_PRECISION, 0, MPI_COMM_WORLD, ierr) Τέλος, αν θέλαμε να λάβουμε από όλες τις διαδικασίες τις τιμές του ορίσματος fvalue και να τις αθροίσουμε στο όρισμα fsum της διαδικασίας 0 θα γράφαμε: Call MPI_Reduce(fValue, fsum, 1, MPI_DOUBLE_PRECISION, MPI_SUM, & 0, MPI_COMM_WORLD, ierr) Για περισσότερες πληροφορίες γύρω από το MPI επισκεφθείτε το διαδικτυακό τόπο: http://www-unix.mcs.anl.go/mpi/ ενώ για να κατεβάσετε μια έκδοση για Windows NT/2000/XP: http://www-unix.mcs.anl.go/mpi/mpich/mpich-nt/
5. Η μέθοδος συζυγών διανυσματικών κλίσεων Η μέθοδος συζυγών διανυσματικών κλίσεων παρουσιάστηκε από τους Hestenes και Stiefel το 1952 και είναι μια επαναληπτική μέθοδος επίλυσης γραμμικών συστημάτων η οποία ενδείκυνται προς παραλληλοποίηση. Έτσι, άν έχουμε να λύσουμε το γραμμικό σύστημα: [ K ]{ u} = { f } τότε η παραπάνω μέθοδος περιγράφεται με τον παρακάτω αλγόριθμο: Αρχικές τιμές: (0) (0) (0) (0) { u } = 0, { δ } = { g } = { f } [ K]{ u } = { f } Για k=0,1,... μέχρι σύγκλισης η = k ( k ) T ( k ) { g } { g } { ( k ) T } [ ]{ ( k δ K δ ) } { ( k + 1) } { ( k u = u ) } +η { δ ( k ) } { ( k + 1) } { ( k g = g ) } +η [ K ]{ δ ( k ) } β k + 1 = ( k + 1) T ( k + 1) { g } { g } { ( k ) T } { ( k g g ) } ( k + 1) ( k + 1) { } { } { ( k = g + β δ ) } δ k + 1 k k 5.1 Ο παράλληλος αλγόριθμος Αν έχουμε ν διαδικασίες στις οποίες θέλουμε να κατανείμουμε τον υπολογιστικό φόρτο της επίλυσης ενός συστήματος με τη μέθοδο των συζυγών διανυσματικών κλίσεων και το μέγεθος του διανύσματος {f} είναι m, τότε αποστέλουμε σε κάθε διαδικασία m/n στοιχεία του διανύσματος {f} και ο αλγόριθμος έχει ως εξής: Αρχικές τιμές: (0) (0) (0) (0) { u } = 0, { δ } = { g } = { f } [ K]{ u } = { f } Για k=0,1,... μέχρι σύγκλισης ( k ) ( k ) T ( k ) n = { g } { g } Άθροιση στον master ( k ) 0 n = a= 1 n ( k ) a
d { } [ ]{ } ( k ) T δ K δ ( ) ( k ) k = Άθροιση στον master d ( k ) 0 = n= 1 d ( k ) n ( k ) n0 Στον master η 0 = και αποστολή σε όλες τις διαδικασίες ( k ) d 0 ( k ) { } { } { } ( k+ 1) ( k ) ( k u ) ( k ) = u +η δ { } { } [ ]{ } ( k+ 1) ( k ) ( k g = g +η ) K δ ( k ) d { } { } ( k + 1) T ( k g g 1) ( k ) = + Άθροιση στον master d ( k ) 0 = n= 1 d ( k ) n β ( k + 1) d = n ( k ) 0 ( k ) 0 ( k+ 1) ( k+ 1) { } { } { } ( k = + β ) δ g k+ 1 δ 5.2 Ο παράλληλος κώδικας Παρακάτω παρατείθεται μια υπορουτίνα που λύνει παράλληλα ένα σύστημα με τη μέθοδο των διανυσματικών κλίσεων Subroutine SoleCG(iEqNo, istart, iend, ftolerance, pikix, pfk, pfrhs) Implicit None Include "fmpi.h" Integer, Intent(IN) :: ieqno, istart, iend, pikix(ieqno) Double Precision, Intent(IN) :: ftolerance, pfk(1) Double Precision, Intent(INOUT) :: pfrhs(ieqno) Logical :: bismaster Integer :: I, J, ierr Double Precision :: DotProduct, fresidual, fd, fdnext, fn, fnumerator, fdenominator, & ftemp Double Precision, Pointer :: pfu(:), pfd(:), pfg(:), pfdk(:), pftemp(:)! Main routine Call MPI_Comm_rank(MPI_COMM_WORLD, I, ierr) bismaster = I.EQ.0 fd = 0D0
ftemp = 0D0 Allocate(pfu(iEqNo), pfd(ieqno), pfg(ieqno), pfdk(ieqno), pftemp(ieqno))! Calculate u=0, d=-g=rhs-k*u Do I = istart, iend pfu(i) = 0D0 pfd(i) = pfrhs(i) pfg(i) = -pfrhs(i) ftemp = ftemp + pfrhs(i) * pfrhs(i) End Do! Collect and add sum of squares from all processes and calculate fd= d Call MPI_Reduce(fTemp, fd, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD, ierr) fd = dsqrt(fd) Call MPI_BCast(fd, 1, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD, ierr) fresidual = 10D20 Do While (fresidual.gt.ftolerance)! Calculate h=(g'*g)/(d'*k*d)! Collect and add all parts of g'*g fnumerator = 0D0 fdenominator = 0D0 ftemp = DotProduct(iStart, iend, pfg, pfg) Call MPI_Reduce(fTemp, fnumerator, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD, ierr)! Calculate d'*k (we need the WHOLE d ector which we store at pfdk!!) Do I = 1, ieqno pfdk(i) = 0D0 pftemp(i) = 0D0 End Do Call MPI_Reduce(pfd, pfdk, ieqno, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD, ierr) Call MPI_BCast(pfdK, ieqno, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD, ierr) Call MulSkylineVec(iStart, iend, pikix, pfk, pfdk, pftemp)! Collect and add all parts of the d'*k multiplication and send back to all Do I = 1, ieqno pfdk(i) = 0D0 End Do Call MPI_Reduce(pfTemp, pfdk, ieqno, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD, ierr) Call MPI_BCast(pfdK, ieqno, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD, ierr)! Collect and add all parts of (d'*k)*d ftemp = DotProduct(iStart, iend, pfdk, pfd) Call MPI_Reduce(fTemp, fdenominator, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD, ierr)! Master performs the diision to calculate h and sends result to all processes if (bismaster.eq..true.) fn = fnumerator / fdenominator
ierr) Call MPI_BCast(fn, 1, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD,! Calculate RHS=u+h*d, gnext=g+n*k*d Do I = istart, iend pfrhs(i) = pfu(i) + fn * pfd(i) pfg(i) = pfg(i) + fn * pfdk(i) End Do! Calculate h=(gnext'*gnext)/(g'*g) if (bismaster.eq..true.) fdenominator = fnumerator! Collect and add all parts of gnext'*gnext ftemp = DotProduct(iStart, iend, pfg, pfg) fnumerator = 0D0 Call MPI_Reduce(fTemp, fnumerator, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD, ierr)! Master performs the diision to calculate h and sends result to all processes if (bismaster.eq..true.) fn = fnumerator / fdenominator Call MPI_BCast(fn, 1, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD, ierr)! Calculate d=-g+n*d, fdnext= d fdnext = 0D0 ftemp = 0D0 Do I = istart, iend pfd(i) = fn * pfd(i) - pfg(i) pfu(i) = pfrhs(i) ftemp = ftemp + pfd(i) * pfd(i) End Do! Collect and add sum of squares from all processes and calculate fdnext= dnext Call MPI_Reduce(fTemp, fdnext, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD, ierr) fdnext = dsqrt(fdnext) Call MPI_BCast(fdNext, 1, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD, ierr)! Calculate residual=fdnext/fd fresidual = fdnext / fd End Do DeAllocate(pfu, pfd, pfg, pfdk) End Subroutine