Παράλληλα και κατανεμημένα συστήματα

Πολυεπεξεργαστές

Στους πολυεπεξεργαστές η μνήμη συνήθως διασπάται σε πολλαπλά τμήματα προκειμένου να επιτρέπονται ταυτόχρονες προσπελάσεις σε αυτά από διαφορετικούς επεξεργαστές (χωρίς αυτό να αναιρεί φυσικά την ύπαρξη ενιαίου χώρου διευθύνσεων), ενώ το δίκτυο διασύνδεσης είναι στην απλούστερη περίπτωση ένας δίαυλος, δηλαδή ένα κοινό μέσο μετάδοσης το οποίο κάθε δεδομένη στιγμή μόνο ένας επεξεργαστής μπορεί να χρησιμοποιεί για επικοινωνία με κάποιο τμήμα μνήμης. Ως εκ τούτου οι πολυεπεξεργαστές διαύλου δεν παρουσιάζουν επαρκή κλιμακωσιμότητα, καθώς ο δίαυλος δεν διαθέτει αρκετή χωρητικότητα ώστε να εξυπηρετεί ταυτόχρονα αιτήσεις από πολλούς διαφορετικούς επεξεργαστές. Αυτό συνεπάγεται ότι οι επιδόσεις δεν αυξάνονται αναλογικά με το πλήθος των επεξεργαστών, αφού με την προσθήκη νέων επεξεργαστών πολλαπλασιάζονται τα διαστήματα αναμονής του καθενός για κατάληψη του διαύλου. Η λύση του διαύλου πάντως είναι η απλούστερη καθώς οι συνήθεις σειριακοί υπολογιστές έτσι κι αλλιώς διαθέτουν έναν δίαυλο για την επικοινωνία του επεξεργαστή με τη μνήμη και τις μονάδες Εισόδου / Εξόδου. Αν ωστόσο χρειαζόμαστε ένα σύστημα με περισσότερες από 10-20 CPU πρέπει να καταφύγουμε σε δίκτυα μεταγωγής, όπου μεταξύ κάθε επεξεργαστή και κάθε τμήματος της μνήμης δημιουργείται μία μοναδική διαδρομή.
Ανεξάρτητα από το είδος της διασύνδεσης, για την αύξηση των επιδόσεων και την αποφυγή υπερφόρτωσης του δικτύου, κάθε CPU διαθέτει τη δική της τοπική κρυφή μνήμη. Στα παράλληλα συστήματα όμως παρουσιάζεται το λεγόμενο «πρόβλημα της συνεκτικότητας» (cache coherence): ένα κοινόχρηστο δεδομένο που έχει αντιγραφεί σε πολλές κρυφές μνήμες μπορεί να τροποποιηθεί ανεξάρτητα στην καθεμία χωρίς να το γνωρίζει η κύρια ή οι άλλες κρυφές μνήμες, με αποτέλεσμα να υπάρχει ασάφεια ως προς το ποια είναι η σωστή τιμή του κάθε στιγμή. Το πρόβλημα αυτό επιλύεται στην περίπτωση ύπαρξης διαύλου με «πρωτόκολλα παρακολούθησης», όπου το υλικό κάθε επεξεργαστή παρακολουθεί όλη την πληροφορία που διακινείται στο κοινό μέσο και δρα ανάλογα, ενώ στην περίπτωση δικτύου μεταγωγής με «πρωτόκολλα καταλόγων», στους οποίους κάθε τμήμα της μνήμης διατηρεί έναν πίνακα με πληροφορίες για το ποιοι επεξεργαστές έχουν κάθε δεδομένο στην κρυφή τους μνήμη ώστε όποτε χρειάζεται να γίνονται οι κατάλληλες ενημερώσεις. Σε κάθε περίπτωση πάντως τα πρωτόκολλα συνεκτικότητας επιβαρύνουν το σύστημα, αφού αυξάνουν την κίνηση στο δίκτυο διασύνδεσης, με το πρόβλημα να μειώνεται (όχι όμως να απαλείφεται) μόνο αν καταβληθεί προσπάθεια ώστε τα παράλληλα προγράμματα να μην τροποποιούν συχνά κοινόχρηστα δεδομένα. Τα παράλληλα συστήματα κοινής μνήμης με δίαυλο στα οποία όλες οι CPU είναι ισότιμες και μπορούν όλες να αναλάβουν την εκτέλεση του λειτουργικού συστήματος ονομάζονται «συμμετρικοί πολυεπεξεργαστές» (SMP). Πάντως ακόμη και οι πολυεπεξεργαστές μεταγωγής στην πράξη έχουν περιορισμένη κλιμακωσιμότητα λόγω τετραγωνικά αυξανόμενου ως προς το πλήθος των επεξεργαστών κόστους κατασκευής του δικτύου διασύνδεσης, με αποτέλεσμα αν χρειαζόμαστε ένα σύστημα με παραπάνω από 64 CPU συνήθως να καταφεύγουμε σε πολυυπολογιστές.

Αυτόματη παραλληλοποίηση

Στις περισσότερες περιπτώσεις ένα παράλληλο πρόγραμμα έχει σχεδιαστεί κατάλληλα και ο πηγαίος κώδικας έχει γραφεί από τον προγραμματιστή έτσι ώστε να υποστηρίζει παραλληλισμό («ρητός παραλληλισμός»). Επειδή η διαδικασία αυτή είναι επίπονη, χρονοβόρα και απαιτεί ειδικές γνώσεις εκ μέρους του προγραμματιστή, έχουν υπάρξει πολλές προσπάθειες για την αυτόματη παραλληλοποίηση τμημάτων σειριακού πηγαίου κώδικα (συνήθως επαναληπτικών βρόχων) από κατάλληλους μεταγλωττιστές. Στην περίπτωση αυτή ο προγραμματιστής συγγράφει τυπικό σειριακό κώδικα, χωρίς κλήσεις σε κάποια υποστηρικτική βιβλιοθήκη όπως των νημάτων POSIX, του OpenMP ή του MPI, και κατά τη μεταγλώττιση εντοπίζονται αυτομάτως τα σημεία που επιδέχονται παραλληλισμό.

Γλώσσες ταυτόχρονου προγραμματισμού

Πέρα από τις, συμπληρωματικές μεταξύ τους, λύσεις της αυτόματης παραλληλοποίησης και της προσθήκης εξειδικευμένων βιβλιοθηκών και επεκτάσεων σε συνήθεις γλώσσες προγραμματισμού όπως η C ή η Fortran, κατά καιρούς έχουν εμφανιστεί και ορισμένες γλώσσες προγραμματισμού σχεδιασμένες από τη βάση τους με στόχο την εγγενή υποστήριξη ταυτοχρονισμού, είτε παράλληλου είτε ψευδοπαράλληλου. Ακόμη και συνηθισμένες γλώσσες γενικού σκοπού παρέχουν κάποια στοιχειώδη εγγενή υποστήριξη για ταυτοχρονισμό και αμοιβαίο αποκλεισμό (π.χ. η Java και η C#), αλλά οι εξειδικευμένες γλώσσες ταυτόχρονου προγραμματισμού είναι βελτιστοποιημένες συγκεκριμένα προς αυτή την κατεύθυνση.

Ζητήματα σχεδίασης

Η διαδιεργασιακή επικοινωνία στα πολυυπολογιστικά συστήματα συνήθως υλοποιείται σε χαμηλό επίπεδο με το σύνηθες δικτυακό μοντέλο πελάτη-διακομιστή, όπου οι πελάτες αιτούνται μέσω του δικτύου υπηρεσίες που παρέχουν οι διακομιστές και αναμένουν απάντηση. Οι πελάτες θα πρέπει να γνωρίζουν πού να απευθυνθούν για μία υπηρεσία και υπάρχουν τρεις τρόποι για την αντιστοίχηση υπηρεσιών-διακομιστών: χρήση συγκεκριμένων διευθύνσεων τύπου υπηρεσία@μηχάνημα, η οποία όμως παραβιάζει τη διαφάνεια θέσης (π.χ. Παγκόσμιος Ιστός), επιλογή τυχαίας διεύθυνσης από την υπηρεσία και ανακοίνωσή της με πολυδιανεμόμενο μήνυμα, ή χρήση ενός διακομιστή ονομάτων ο οποίος συνδέει ASCII ονόματα υπηρεσιών με χαμηλού επιπέδου δικτυακές διευθύνσεις και τον οποίον συμβουλεύονται οι εφαρμογές. Η επικοινωνία χαμηλού επιπέδου μεταξύ δύο υπολογιστών προγραμματιστικά επιτυγχάνεται μέσω κατάλληλων κλήσεων συστήματος (π.χ. send() και recv(), από το API των υποδοχών που παρέχει το λειτουργικό σύστημα για διαδιεργασιακή επικοινωνία μέσω δικτύου).
Στο μοντέλο πελάτη-διακομιστή εμφανίζονται δύο ζητήματα που πρέπει να αντιμετωπιστούν: η αρχιτεκτονική εξυπηρέτησης που προσφέρουν και η κλιμακωσιμότητά τους. Η αρχιτεκτονική μπορεί να είναι είτε ακολουθιακή, όπου κάθε φορά εξυπηρετείται ένας πελάτης σειριακά, είτε παράλληλη, όπου ο διακομιστής δημιουργεί νέα διεργασία ή νέο νήμα για την εξυπηρέτηση κάθε πελάτη και ο χρονοπρογραμματιστής του λειτουργικού του συστήματος αναλαμβάνει την ταυτόχρονη εκτέλεσή τους. Η αύξηση της κλιμακωσιμότητας επιτυγχάνεται με προσθήκη κρυφής μνήμης, χρήση ισχυρότερου υπολογιστή (π.χ. με περισσότερους επεξεργαστές), κατανομή των δεδομένων ή / και των αλγορίθμων σε πολλαπλούς διακομιστές κλπ. Αντί για το μοντέλο πελάτη-διακομιστή όμως μπορεί να αξιοποιηθεί ένα μοντέλο ομότιμης επικοινωνίας, όπου όλοι οι κόμβοι είναι ισότιμοι και μπορούν να λειτουργούν τόσο ως πελάτες όσο και ως διακομιστές. Έτσι η προσθήκη περισσότερων κόμβων σε μία ομότιμη εφαρμογή ανταλλαγής και διαμοιρασμού αρχείων μέσω Διαδικτύου (π.χ. eMule) αυξάνει στην πραγματικότητα την κλιμακωσιμότητα του ολικού συστήματος (αφού με κάθε νέο κόμβο που συμμετέχει προστίθενται νέες συνδέσεις στο λογικό δίκτυο επικάλυψης της εφαρμογής, όπως και περισσότερος αποθηκευτικός χώρος), ενώ η προσθήκη περισσότερων πελατών που αναμένουν την εξυπηρέτησή τους από έναν διακομιστή μεταφοράς αρχείων (π.χ. FTP) οδηγεί σταδιακά στον κορεσμό του τελευταίου, αφού το σύστημα χαρακτηρίζεται από στατική κλιμακωσιμότητα.
Στα κατανεμημένα συστήματα πολλές φορές είναι επιθυμητή η κατασκευή πολλαπλών συνεργαζόμενων διεργασιών, που μπορεί να τοποθετούνται σε διαφορετικούς δικτυωμένους υπολογιστές, για την επίτευξη ενός στόχου. Αυτές οι ομάδες διεργασιών αποτελούν ένα μηχανισμό αφαίρεσης και μία κατανεμημένη εφαρμογή πρέπει να μπορεί να επικοινωνεί μαζί τους ατομικά χωρίς να γνωρίζει το ακριβές πλήθος ή τις διευθύνσεις των μελών. Αυτό επιτυγχάνεται είτε με υποστήριξη από το υλικό του δικτύου (πολυδιανομή, εκπομπή), είτε με χαμηλότερου επιπέδου αποστολή μηνυμάτων σε κάθε μέλος της ομάδας ξεχωριστά, διαφανώς για τον χρήστη. Οι ομάδες μπορούν να είναι είτε κλειστές, όπου επιτρέπεται επικοινωνία μόνο μεταξύ μελών της ομάδας, είτε ανοιχτές, όπου επιτρέπεται επιπλέον και η αμφίδρομη επικοινωνία των μελών της ομάδας με τον «έξω κόσμο», ενώ επίσης μπορούν να είναι ιεραρχικές, με εσωτερική δομή όπου υπάρχει ένας συντονιστής και οι υπόλοιπες διεργασίες θεωρούνται εργάτες, ή ομότιμες, όπου όλα τα μέλη είναι ισότιμα. Το πρόβλημα με τις ιεραρχικές ομάδες είναι ότι αν καταρρεύσει ο συντονιστής καταστρέφεται όλη η εργασία, ενώ το πρόβλημα με τις ομότιμες ομάδες είναι ότι προκειμένου να ληφθεί μία απόφαση πρέπει να διεξαχθεί «ψηφοφορία» όπου κάθε μέλος στέλνει ένα μήνυμα με την ψήφο του στα άλλα. Δύο άλλα ζητήματα, η λύση των οποίων εξαρτάται από την εκάστοτε εφαρμογή, είναι ο ταυτοχρονισμός (αν υπάρχουν δηλαδή περιορισμοί σχετικά με τη σειρά παραλαβής δύο μηνυμάτων σε κάθε μέλος) και τα σφάλματα (είναι αποδεκτή η λήψη ενός μηνύματος μόνο από ένα υποσύνολο των μελών;).