Next             Up                 Back                   Contents

Επόμενο:8.3 Προγράμματα Διασωλήνωσης σε Συστήματα Κατανεμημένης Μνήμης Πάνω: Κεφάλαιο 8o: Προγράμματα περάσματος μηνυμάτων Πίσω: 8.1 Θύρες Επικοινωνίας


 

8.2 Γλωσσική Υποστήριξη Προγραμματισμού Περάσματος Μηνυμάτων

 

Η Multi-Pascal έχει ορισμένα ειδικά χαρακτηριστικά που είναι σχεδιασμένα έτσι ώστε να υποστηρίζουν τον προγραμματισμό του περάσματος μηνυμάτων που απαιτείται για τα συστήματα κατανεμημένης μνήμης. Αυτά τα επιπλέον χαρακτηριστικά χρειάζονται εξαιτίας της έλλειψης των διαμοιραζόμενων μεταβλητών στις εφαρμογές της Multi-Pascal στα συστήματα κατανεμημένης μνήμης. Ένα από αυτά τα χαρακτηριστικά είναι η δήλωση PORT, η οποία χρησιμοποιείται για να συνδέσει ένα κανάλι με μια διεργασία με σκοπό να επικοινωνεί με άλλες διεργασίες. Η παράγραφος που ακολουθεί θα παρουσιάσει με λεπτομέρειες το συντακτικό και τη σημασιολογία της δήλωσης PORT. Μια άλλη πλευρά της επικοινωνίας είναι η αλληλεπίδραση ανάμεσα στο κυρίως πρόγραμμα και στις διεργασίες παιδιά. Η Multi-Pascal έχει ειδικά χαρακτηριστικά που επιτρέπουν μια κατάλληλη μεταφορά των αρχικών δεδομένων και των τελικών αποτελεσμάτων μεταξύ του κυρίως προγράμματος και των διεργασιών. Αυτό επιτυγχάνεται με τις παραμέτρους της κλήσης διαδικασίας που δημιουργεί κάθε διεργασία. Επίσης στην παράγραφο αυτή παρουσιάζεται το στοιχείο @ για τον έλεγχο της ανάθεσης των διεργασιών στους φυσικούς επεξεργαστές. Αυτό είναι απαραίτητο για να βοηθήσει στην βελτιστοποίηση της απόδοσης του προγράμματος για συγκεκριμένες τοπολογίες συστημάτων κατανεμημένης μνήμης.

Μια επιπλέον τροποποίηση της Multi-Pascal για τα συστήματα κατανεμημένης μνήμης είναι η ελάχιστη χρήση του κλειδώματος. Εξαιτίας της απουσίας των διαμοιραζόμενων μεταβλητών, η έννοια των ατομικών λειτουργιών δεν είναι ιδιαίτερα χρήσιμη στον προγραμματισμό των συστημάτων κατανεμημένης μνήμης. Στις εφαρμογές των συστημάτων διαμοιραζόμενης μνήμης η Multi-Pascal διαθέτει ενεργοποίηση κλειδωμάτων για να βοηθήσει στην τροποποίηση των διαμοιραζόμενων δεδομένων από πολλές διεργασίες. Βέβαια αυτό δεν είναι απαραίτητο στον προγραμματισμό του περάσματος μηνυμάτων και δεν θα είναι καθόλου αποδοτικό αν εφαρμοστεί σε ένα σύστημα κατανεμημένης μνήμης. Έτσι, η χρήση του κλειδώματος περιορίζεται.

 

8.2.1 Η δήλωση PORT

 

Μια δήλωση PORT χρησιμοποιείται για να αντιστοιχήσει μια μεταβλητή καναλιού με μια διεργασία, έτσι ώστε να μπορεί η διεργασία αυτή να λάβει μηνύματα από άλλες διεργασίες μέσω του καναλιού. Κάθε διεργασία μπορεί να γράψει τιμές μεσα σε κάθε κανάλι, αλλά κάθε διεργασία μπορεί να διαβάσει τιμές μόνο από το κανάλι που της έχει ανατεθεί. Όλες οι μεταβλητές καναλιού πρέπει να δηλώνονται στην αρχή του κυρίως προγράμματος με τον συνηθισμένο τρόπο. Όταν μια διεργασία δημιουργείται με κάποια από τις μεθόδους της Multi-Pascal (FORALL ή FORK) πρέπει να συμπεριλαμβάνεται και μια δήλωση PORT για αναθέτει ένα η περισσότερα κανάλια στη διεργασία. Η γενική σύνταξη μιας δήλωσης PORT είναι η παρακάτω:

(PORT <channel-list>)<statement>;

Το τμήμα <statement> καθορίζει το σώμα της διεργασίας που δημιουργείται, η οποία είναι τις περισσότερες φορές κλήση. Το <channel-list> είναι μια σειρά από αναφορές καναλιών οι οποίες χωρίζονται μεταξύ τους. Μια αναφορά καναλιού μπορεί να είναι είτε:

 

1. μια μεταβλητή καναλιού είτε

2. ένας πίνακας καναλιών

 

Η κατηγορία 1 είναι μια συνηθισμένη αναφορά καναλιού που μπορεί να εμφανιστεί σε μια έκφραση σε αυτή τη θέση του προγράμματος. Η εγκυρότητα της αναφοράς καναλιού καθορίζεται από δηλώσεις στην αρχή του κυρίως προγράμματος. Η αναφορά μεταβλητής καναλιού αναγνωρίζει ένα συγκεκριμένο κανάλι που ανατίθεται στη διεργασία που δημιουργείται. Η κατηγορία 2 είναι κάθε έγκυρη αναφορά πίνακα, πιθανόν ένας πολυδιάστατος πίνακας, στον οποίο το στοιχειώδες στοιχείο είναι ένα κανάλι. Σε αυτή την περίπτωση η δήλωση PORT θα αναθέσει όλο τον πίνακα των καναλιών στη διεργασία που δημιουργείται. Έτσι, κάθε κανάλι του πίνακα μπορεί να χρησιμοποιηθεί από αυτή τη διεργασία για τη λήψη μηνυμάτων.

Το συντακτικό των δηλώσεων ανάθεσης για την εγγραφή ή την ανάγνωση από κανάλι είναι το ίδιο με το αντίστοιχο των πολυεπεξεργαστών: η εγγραφή στα κανάλια γίνεται χρησιμοποιώντας το όνομά τους στην αριστερή πλευρά της δήλωσης ανάθεσης και η ανάγνωση χρησιμοποιώντας το όνομα των καναλιών στη δεξιά πλευρά της δήλωσης ανάθεσης. Η μόνη διαφορά είναι ο περιορισμός ότι μόνο μια διεργασία έχει τη δυνατότητα εκτέλεσης μιας λειτουργίας ανάγνωσης σε ένα δεδομένο κανάλι. Η διεργασία αυτή είναι εκείνη στην οποία έχει ανατεθεί το κανάλι με τη δήλωση PORT.

Έστω οι ακόλουθες δηλώσεις καναλιών που εμφανίζονται στην αρχή του κυρίως προγράμματος:

 

VAR C: CHANNEL OF CHAR;

    archan: ARRAY [1..10] OF CHANNEL OF INTEGER;

Για αυτές τις δηλώσεις είναι έγκυρες οι ακόλουθες δηλώσεις PORT:

( PORT C )

( PORT archan[2] )

( PORT archan )

 

Στην παραπάνω λίστα η πρώτη δήλωση PORT αναθέτει το κανάλι C στη νεοδημιουργηθείσα διεργασία. Η δεύτερη δήλωση PORT αναθέτει το κανάλι archan[2] στη νέα διεργασία: όλα τα υπόλοιπα εννιά κανάλια του πίνακα archan δεν επηρεάζονται από αυτή τη δήλωση. Η τρίτη δήλωση PORT αναθέτει όλα τα κανάλια του πίνακα archan στη νέα διεργασία.

Η λίστα της αναφοράς καναλιού PORT μπορεί να καθορίζει ξεχωριστά στοιχεία κάθε πίνακα καναλιών που δηλώνεται στην αρχή του κυρίως προγράμματος, συμπεριλαμβανομένων και πολυδιάστατων πινάκων. Για παράδειγμα θεωρείστε τον διδιάστατο πίνακα A που δηλώνεται με τον ακόλουθο τρόπο:

 

VAR A: ARRAY [1..10, 1..20] OF CHANNEL OF REAL;

Για αυτό τον πίνακα έχουμε τις ακόλουθες έγκυρες δηλώσεις PORT:

( PORT A[3,4] )

( PORT A[1,1]; A[2,3] )

( PORT A )

( PORT A[2] )

Οι δύο παραπάνω πρώτες δηλώσεις PORT αναθέτουν καθορισμένα κανάλια του πίνακα A στη νέα διεργασία. Η τρίτη δήλωση PORT αναθέτει όλο τον δι-διάστατο πίνακα A στη νέα διεργασία. Η τελευταία δήλωση αναθέτει τη δεύτερη γραμμή του πίνακα. Είναι ιδιαίτερα σημαντικό να κατανοήσουμε ότι η χρήση των δηλώσεων PORT δεν αλλάζουν τον τρόπο με τον οποίο γίνεται η αναφορά των μεταβλητών καναλιών μέσα στο πρόγραμμα. Στο παραπάνω παράδειγμα όλες οι διεργασίες εξακολουθούν να έχουν πρόσβαση στον A ως ένα πίνακα μεταβλητών καναλιών και μπορούν να αναφερθούν σε οποιοδήποτε στοιχείο του A με το συνηθισμένο τρόπο και με τη συνηθισμένη δεικτοδότηση. Η μόνη διαφορά είναι ο περιορισμός σχετικά με την ανάγνωση κάθε καναλιού μόνο από τη διεργασία που του έχει ανατεθεί.

Κάθε έγκυρη έκφραση της Multi-Pascal μπορεί να χρησιμοποιηθεί για την αναγνώριση δεικτών σε μια δήλωση PORT λίστας καναλιών αναφοράς. Οι εκφράσεις δεικτοδότησης υπολογίζονται δυναμικά κατά τη διάρκεια εκτέλεσης του προγράμματος με το συνηθισμένο τρόπο συλλογής των συγκεκριμένων στοιχείων του πίνακα. Αν υποθέσουμε ότι οι μεταβλητές i, j, k δηλώνονται ως Integer έχουμε τις ακόλουθες έγκυρες δηλώσεις PORT:

 

( PORT A[1,j] )

( PORT A[i+1, j] )

( PORT A[i, j] )

( PORT A[k, j+2*k] )

 

Κάθε κανάλι που δηλώνεται στην αρχή του κυρίως προγράμματος και δεν συμπεριλαμβάνεται σε καμία από τις δηλώσεις PORT ανατίθεται εξ ορισμού στο κανάλι επικοινωνίας της κύριας διεργασίας. Ο σκοπός κάθε δήλωσης PORT είναι η ανάθεση ενός καναλιού σε μια διεργασία. Μια τεχνική εφαρμογής των δηλώσεων PORT είναι να δημιουργήσει η κύρια διεργασία ένα πίνακα PORT από όλες τις δηλώσεις PORT. Κάθε εγγραφή αυτού του πίνακα θα αποτελείται από ένα αριθμό αναγνώρισης καναλιού, αριθμό αναγνώρισης διεργασίας και τον αριθμό επεξεργαστή στον οποίο εκτελείται η διεργασία. Αυτός ο πίνακας PORT μπορεί να μεταδοθεί σε όλες τις διεργασίες, έτσι ώστε κάθε διεργασία να γνωρίζει που να στέλνει τα μηνύματά της.

 

8.2.2 Επικοινωνία με το κυρίως πρόγραμμα

 

Στα προγράμματα συστημάτων κατανεμημένης μνήμης το κυρίως πρόγραμμα εξυπηρετεί μια ειδική λειτουργία: αλληλεπιδρά με τον χρήστη και διαβάζει τα αρχικά δεδομένα των πινάκων από το δίσκο. Επίσης δημιουργεί τις διεργασίες παιδιά που πραγματοποιούν τους παράλληλους υπολογισμούς, στη συνέχεια συλλέγει τα τελικά υπολογισμένα αποτελέσματα και τα αναφέρει στο χρήστη ή τα γράφει στο δίσκο. Εξαιτίας αυτού του ειδικού ρόλου είναι χρήσιμο να έχουμε κάποια χαρακτηριστικά της Multi-Pascal σχεδιασμένα έτσι ώστε να διευκολύνουν την αλληλεπίδραση του κυρίως προγράμματος με τις διεργασίες παιδιά. Τα χαρακτηριστικά αυτά πρέπει να επικεντρωθούν στην κατανομή όλων των αρχικών δεδομένων στις διεργασίες και τη συλλογή των τελικών υπολογισμένων αποτελεσμάτων.

Στα προγράμματα των συστημάτων διαμοιραζόμενης μνήμης τα αρχικά δεδομένα συνήθως τοποθετούνται σε πίνακες διαμοιραζόμενων δεδομένων που βρίσκονται στη φυσικά διαμοιραζόμενη μνήμη. Από εκεί μπορούν να προσπελαστούν απευθείας από όλες τις διεργασίες. Όμως, σε ένα σύστημα κατανεμημένης μνήμης η έλλειψη της φυσικά διαμοιραζόμενης μνήμης κάνει αναγκαία τη χρήση ενός άλλου μηχανισμού. Η μέθοδος που χρησιμοποιείται στα συστήματα αυτά βασίζεται στο πέρασμα των απαιτούμενων αρχικών δεδομένων σε κάθε διεργασία χρησιμοποιώντας τις παραμέτρους των κλήσεων διαδικασίας που δημιουργούν κάθε διεργασία. Γενικά, τα αρχικά δεδομένα μπορούν να επιμεριστούν έτσι ώστε μόνο ένα τμήμα των δεδομένων που χρειάζονται να δοθούν σε κάθε δημιουργημένη διεργασία. Εφόσον η δημιουργία κάθε διεργασίας σχεδόν πάντα γίνεται με την κλήση διαδικασίας στα προγράμματα των συστημάτων κατανεμημένης μνήμης, οι παράμετροι τιμής (VALUE parameters) της διαδικασίας παρέχουν ένα κλασσικό μηχανισμό της γλώσσας για δεδομένα που αντιγράφονται από το κυρίως πρόγραμμα στις διεργασίες παιδιά. Όταν η πρώτη δήλωση μιας διεργασίας είναι μια κλήση διαδικασίας σε Multi-Pascal ο υπολογισμός των παραμέτρων της διαδικασίας γίνεται από το κυρίως πρόγραμμα, επιτρέποντας έτσι τα τοπικά δεδομένα του κυρίως προγράμματος να “αντιγραφούν” σε παραμέτρους τιμών και να “περαστούν” στη διεργασία παιδί.

Η δομή ενός τυπικού προγράμματος φαίνεται στο σχήμα 8.3. Τα αρχικά δεδομένα τοποθετούνται από το κυρίως πρόγραμμα στον διδιάστατο πίνακα inputdata. Όταν η διεργασία i δημιουργείται χρησιμοποιεί μια παράμετρο τιμής για να αντιγράψει την i-οστή σειρά αυτού του πίνακα. Οι δύο παράμετροι i και inputdata[i] υπολογίζονται από το κυρίως πρόγραμμα. Αυτές οι μεταβλητές είναι και οι δύο τοπικές για το κυρίως πρόγραμμα και έτσι μπορούν να αναγνωστούν και να αντιγραφούν κατά τη διάρκεια αυτού του υπολογισμού παραμέτρων. Στην συνέχεια αυτοί οι υπολογισμοί παραμέτρων “δένονται” με το μήνυμα δημιουργίας διεργασίας και στέλνονται στον προορισμό του φυσικού επεξεργαστή. Όταν η διεργασία αρχίζει να τρέχει στον επεξεργαστή προορισμού, θα εκτελεστεί μέσα στη διαδικασία Process. Η παράμετρος διαδικασίας που ονομάζεται mydata θα περιέχει ένα αντιγραφο της inputdata[i]. Αυτή η παράμετρος είναι μια τοπική παράμετρος για τη διαδικασία και συνεπώς μπορεί να προσπελαστεί με τον συνηθισμένο τρόπο κατά τη διάρκεια εκτέλεσης της διεργασίας.

Αφού κάθε διεργασία ολοκληρώσει την εκτέλεση της θα πρέπει συχνά να επιστρέψει ένα τελικό υπολογισμένο αποτέλεσμα στο κυρίως πρόγραμμα. Αυτά τα τελικά αποτελέσματα από όλες τις διεργασίες συγκεντρώνονται από το κυρίως πρόγραμμα και αναφέρονται στο χρήστη ή γράφονται σε ένα αρχείο του δίσκου. Ένας κλασσικός μηχανισμός της γλώσσας για την επιστροφή αυτών των τελικών αποτελεσμάτων είναι οι παράμετροι διεύθυνσης (VAR parameters) στη διαδικασία καθορισμού διεργασίας. Αντίθετα με τις παραμέτρους τιμών, που περνούν ένα πλήρες αντίγραφο του ορίσματος στη διαδικασία, οι παράμετροι διεύθυνσης περνούν μόνο τη διεύθυνση του ορίσματος. Αυτή η διεύθυνση χρησιμοποιείται στη συνέχεια από τη διαδικασία για να γράψει ή να διαβάσει από τη μεταβλητή ορίσματος απευθείας.

 

PROGRAM Message-Passing;

CONST n= ...; (*Αριθμός των διεργασιών*)

TYPE datatype= ARRAY [1..m]OF REAL;

VAR inchan: ARRAY OF CHANNEL OF INTEGER;

    i: INTEGER ;

    inputdata: ARRAY [1..n] OF datatype; (*Κύριος πίνακας δεδομένων*)

    ...

PROCEDURE Process(i: INTEGER; mydata: datatype);

    VAR ...(*Τοπικές μεταβλητές για τη διαδικασία*)

BEGIN

    ...

END;

BEGIN (*Κυρίως πρόγραμμα*)

    ... (*Διάβασμα αρχικών τιμών για τον πίνακα inputdata*)

    FORALL i:= 1 to n DO (*Δημιουργία των διεργασιών*)

            (PORT inchan[i]) Process((i, inputdata[i]);

   ...

END.

ΣΧΗΜΑ 8.3 Κατανομή των αρχικών δεδομένων στις διεργασίες.

 

Όταν στη Multi-Pascal έχουμε στη διαδικασία καθορισμού διεργασίας παραμέτρους διεύθυνσης, τότε αυτές ονομάζονται παράμετροι απομακρυσμένης διεύθυνσης (Remote-VAR parameters) και έχουν κάποιες ειδικές ιδιότητες. Οι παράμετροι απομακρυσμένης διεύθυνσης είναι μόνο εγγράψιμες (write-only) μέσα στη διεργασία που δημιουργείται. Σε καμία περίπτωση δεν μπορούν να διαβαστούν μέσα στη διεργασία. Συνεπώς, δεν μπορούν να εμφανιστούν στη δεξιά πλευρά μιας δήλωσης ανάθεσης ή σε οποιαδήποτε έκφραση που υπολογίζεται από τη διεργασία. Όμως, οι παράμετροι απομακρυσμένης διεύθυνσης μπορούν να εμφανιστούν στο αριστερό τμήμα δηλώσεων ανάθεσης. Σε αυτή την περίπτωση η τιμή ανάθεσης αυτόματα στέλνεται μέσα από το δίκτυο επικοινωνίας πίσω στο κυρίως πρόγραμμα, όπου γράφεται στην πρωτότυπη μεταβλητή. Αυτή η σημασιολογία είναι βασικά ίδια με τις συνηθισμένες παραμέτρους διεύθυνσης-μια λειτουργία εγγραφής σε μια παράμετρο διεύθυνσης θα τροποποιήσει αυτόματα την πρωτότυπη μεταβλητή. Η μόνη διαφορά με τις μεταβλητές απομακρυσμένης διεύθυνσης είναι ότι η μεταβλητή στόχου βρίσκεται στην τοπική μνήμη ενός απομακρυσμένου επεξεργαστή.

Η χρήση αυτή των παραμέτρων απομακρυσμένης διεύθυνσης που περνούν τα τελικά αποτελέσματα πίσω στο κυρίως πρόγραμμα παρουσιάζεται στο σχήμα 8.4. Ο πίνακας outputdata είναι μια τοπική μεταβλητή του κυρίως προγράμματος και χρησιμοποιείται για τη συλλογή των τελικών αποτελεσμάτων από όλες τις διεργασίες. Καθώς η διεργασία i δημιουργείται, έχει την outputdata[i] σαν παράμετρο απομακρυσμένης διεύθυνσης. Υποθέστε ότι το τελικό αποτέλεσμα “x=45.6” υπολογίζεται από τη διεργασία 3. Το αποτέλεσμα αυτό γράφεται στην παράμετρο απομακρυσμένης διεύθυνσης με τη δήλωση ανάθεσης “out:= x”. Εφόσον η παράμετρος out συνδέεται με το outputdata[3] στο κυρίως πρόγραμμα, η ανάθεση στην out θα δημιουργήσει αυτόματα το μήνυμα “γράψε 45.6 στο outputdata[3]”, το οποίο θα σταλεί μέσα από το δίκτυο επικοινωνίας στον επεξεργαστή 0, όπου εκτελείται το κυρίως πρόγραμμα. Με αυτόν τον τρόπο ο πίνακας outputdata, που είναι τοπικός για το κυρίως πρόγραμμα, θα συγκεντρώσει τα τελικά αποτελέσματα από όλες τις διεργασίες.

Αυτή η χρήση των παραμέτρων τιμών και διεύθυνσης για την επικοινωνία με το κυρίως πρόγραμμα στην Multi-Pascal μοιάζει πολύ με ένα σημαντικό μηχανισμό που ονομάζεται Κλήση Απομακρυσμένης Διαδικασίας (Remote Procedure Call-RPC). Η Κλήση Απομακρυσμένης Διαδικασίας είναι συνηθισμένο χαρακτηριστικό των γλωσσών προγραμματισμού για κατανεμημένα συστήματα που βασίζονται σε δίκτυα υπολογιστών. Μια Κλήση Απομακρυσμένης Διαδικασίας είναι στην ουσία μια αίτηση από έναν υπολογιστή για να εκτελέσει μια συγκεκριμένη διαδικασία σε έναν άλλο υπολογιστή του δικτύου. Η Κλήση Απομακρυσμένης Διαδικασίας έχει δύο τύπους παραμέτρων: τις παραμέτρους εισόδου (in parameters) που περνούν αρχικές τιμές στον υπολογιστή προορισμό και τις παραμέτρους εξόδου (out parameters) που περνούν τα υπολογισμένα αποτελέσματα στον υπολογιστή που έκανε την αίτηση. Η διαδικασία αυτή μοιάζει έντονα με τη χρήση των παραμέτρων τιμής και διεύθυνσης στην Multi-Pascal. Η αντιστοίχηση αυτή του μηχανισμού της Κλήσης Απομακρυσμένης Διαδικασίας με τα προγράμματα κατανεμημένης μνήμης της Multi-Pascal παρέχει ένα ευέλικτο γλωσσικό χαρακτηριστικό που είναι κατάλληλο για ένα συγκεκριμένο τύπο επικοινωνίας που συνήθως συμβαίνει μεταξύ του κυρίως προγράμματος και των διεργασιών-παραγομένων.

 

PROGRAM Message-Passing;

CONST n= ...; (*Αριθμός των διεργασιών*)

TYPE datatype= ARRAY [1..m] OF REAL;

VAR inchan: ARRAY OF CHANNEL OF INTEGER;

    i: INTEGER;

    inputdata: ARRAY [1..n] OF datatype; (*Πρωταρχικός πίνακας δεδομένων*)

    outputdata: ARRAY [1..n] OF REAL; (*Τελικά υπολογισμένα αποτελέσματα*)

    ....   

PROCEDURE Process(i: INTEGER; in: datatypes; VAR out: REAL);

    VAR x: REAL;

    ... (*Άλλες τοπικές μεταβλητές για τη διεργασία*)

BEGIN

    ... (*Υπολογισμός του τελευταίου αποτελέσματος “x”*)

    out:= x; (*Αντιγραφή των τελικών αποτελεσμάτων πίσω στο κυρίως πρόγραμμα*)

END;

BEGIN (*Κυρίως πρόγραμμα*)

    ... (*Ανάγνωση των αρχικών τιμών για τον πίνακα inputdata*)

    FORALL i:= 1 TO n DO (*Δημιουργία των διεργασιών*)

            (PORT inchan[i])Process(i, inputdata[i], outputdata[i]);

    ...   

END.

ΣΧΗΜΑ 8.4 Επικοινωνία με το κυρίως πρόγραμμα

 

8.2.3 Ο τελεστής @ για την ανάθεση διεργασίας σε επεξεργαστή

 

Στις περισσότερες τοπολογίες συστημάτων κατανεμημένης μνήμης η καθυστέρηση επικοινωνίας μεταξύ επεξεργαστών ποικίλει αρκετά και εξαρτάται από τη σχετική απόσταση των επεξεργαστών. Απομακρυσμένοι επεξεργαστές μπορεί να απαιτούν καθυστέρηση επικοινωνίας που είναι 10 ή ακόμα και 100 φορές μεγαλύτερη από αυτήπου απαιτούν κοντινοί επεξεργαστές. Για παράδειγμα, ένα διδιάστατο πλέγμα 10x10 μπορεί να έχει καθυστέρηση επικοινωνίας της τάξης των 50 μονάδων χρόνου για γειτονικούς επεξεργαστές, αλλά αυτό σημαίνει ότι οι επεξεργαστές 0 και 99 έχουν μια καθυστέρηση των 900 μονάδων χρόνου. Για να ελαχιστοποιήσουμε την καθυστέρηση επικοινωνίας σε ένα παράλληλο πρόγραμμα, είναι απαραίτητο να τοποθετήσουμε διεργασίες επικοινωνίας σε κοντινούς επεξεργαστές. Για αυτό το λόγο η γλώσσα Multi-Pascal έχει ένα συγκεκριμένο σύμβολο που επιτρέπει στον προγραμματιστή να αγνοεί τους προκαθορισμένους κανόνες ανάθεσης διεργασιών στους επεξεργαστές. Ο Τελεστής @ προηγείται του ορισμού διεργασίας και του επιθυμητού αριθμού επεξεργαστή και αναθέσει την εκτέλεση της διεργασίας στο συγκεκριμένο επεξεργαστή. Η γενική σύνταξη του τελεστή @ είναι η ακόλουθη:

( @ <expression> ) <statement>;

Το τμήμα <statement> καθορίζει το σώμα της διεργασίας που δημιουργείται. Το <expression> είναι κάθε νόμιμη έκφραση της Multi-Pascal που υπολογίζει την τιμή ενός ακεραίου. Η έκφραση υπολογίζεται κατά τη διάρκεια εκτέλεσης του προγράμματος και χρησιμοποιείται ως ο αριθμός επεξεργαστή που θα ανατεθεί στην νεο-δημιουργημένη διεργασία που καθορίστηκε από το <statement>. Τα παρακάτω παραδείγματα δείχνουν τη χρήση του τελεστή @ σε συνδυασμό με τον τελεστή FORK:

 

FORK ( @3 ) Expand;

FORK ( @i ) Filter(outchan);

FORK ( @i*10+j ) Compute(i);

Ο τελεστής @ μπορεί να χρησιμοποιηθεί σε συνδυασμό με δηλώσεις FORALL, όπως φαίνεται στα παρακάτω παραδείγματα:

 

FORALL i:= 1 TO 50 DO

    ( @ i-1 ) Compute(i);

FORALL j:= 1 TO 10 DO

    ( @ j ) Process(j, A[j]);

Σε μερικά προγράμματα είναι χρήσιμο να γνωρίζει η διεργασία τον αριθμό επεξεργαστή της σαν σημείο αναφοράς για την τοποθετήσει των νεοδημιουργημένων διεργασιών. Η Multi-Pascal έχει την ενσωματωμένη συνάρτηση %Self που μπορεί να χρησιμοποιηθεί σε κάθε έκφραση και να υπολογίσει τον αριθμό επεξεργαστή στον οποίο εκτελείται. Αυτή η συνάρτηση είναι ιδιαίτερα χρήσιμη σαν τμήμα της έκφρασης @, όπως φαίνεται και στα παρακάτω παραδείγματα:

 

FORK ( @ %Self+1 ) Filter(outchan);

FORK ( @ %Self+10 ) Point(i, j);

Όταν ο τελεστής @ δεν είναι παρόν μπροστά από τον ορισμό της διεργασίας, τότε η Mutli-Pascal θα χρησιμοποιήσει τον προκαθορισμένο κανόνα εκχώρησης επεξεργαστή-όπως εξηγείται στο Παράρτημα - σε μια προσπάθεια εξισορρόπησης του φορτίου σε όλους τους επεξεργαστές. Ο προκαθορισμένος κανόνας ταιριάζει κυρίως σε πολυεπεξεργαστές διαμοιραζόμενης μνήμης και επιπλέον στην Πλήρως Συνδεδεμένη τοπολογία συστημάτων κατανεμημένης μνήμης, στα οποία υπάρχει ένας σύνδεσμος επικοινωνίας ανάμεσα σε κάθε ζεύγος επεξεργαστών. Για άλλες αρχιτεκτονικές είναι προτιμότερη η χρήση του τελεστή @ για την τοποθέτηση των επικοινωνούντων διεργασιών σε γειτονικούς επεξεργαστές. Όταν και ο τελεστής @ και το PORT χρησιμοποιούνται μπροστά από τον ίδιο ορισμό διεργασίας, ο τελεστής @ εμφανίζεται πρώτος και έχουμε μόνο μια παρένθεση. Η γενική σύνταξη είναι η ακόλουθη:

 

( @ <expression> PORT <channel-list> ) <statement>;

     Next             Up                Back                   Contents

Επόμενο:8.3 Προγράμματα Διασωλήνωσης σε Συστήματα Κατανεμημένης Μνήμης Πάνω: Κεφάλαιο 8o: Προγράμματα περάσματος μηνυμάτων Πίσω: 8.1 Θύρες Επικοινωνίας