ΕΚΔΟΣΗ 1.1 ΑΠΡΙΛΙΟΣ, 2018 ΕΙΣΑΓΩΓΗ ΣΤΑ ΚΑΤΑΝΕΜΗΜΕΝΑ ΣΥΣΤΗΜΑΤΑ ΕΠΙΜΕΛΕΙΑ: Β. ΤΣΑΚΑΝΙΚΑΣ, Β. ΤΑΜΠΑΚΑΣ
CONTENTS ΕΙΣΑΓΩΓΗ ΣΤΑ ΚΑΤΑΝΕΜΗΜΕΝΑ ΣΥΣΤΗΜΑΤΑ... 2 Το πρωτόκολλο ECHO... 2 Εισαγωγή... 2 Το πρωτόκολλο ECHO... 2 Περιγραφή Πρωτοκόλλου... 2 Εργαστηριακή Άσκηση Το πρωτόκολλο ECHO... 4 Βήμα 1:... 4 Δραστηριότητες... 7 Βιβλιογραφία... 10 ΑΠΡΙΛΙΟΣ, 2018 ΕΙΣΑΓΩΓΗ ΣΤΑ ΚΑΤΑΝΕΜΗΜΕΝΑ ΣΥΣΤΗΜΑΤΑ 1
Παραδοχές ΕΙΣΑΓΩΓΗ ΣΤΑ ΚΑΤΑΝΕΜΗΜΕΝΑ ΣΥΣΤΗΜΑΤΑ ΕΙΣΑΓΩΓΗ Τα πρωτόκολλα της οικογένειας του ECHO μπορούν να χρησιμοποιηθούν για να μεταδώσουν αποδοτικά πληροφορία σε ένα δίκτυο, ενώ ταυτόχρονα μπορούν να μας επιτρέψουν ένα δένδρο σύνδεσης μεταξύ των κόμβων. Το πρωτόκολλο ECHO χρησιμοποιείται σε δίκτυο τοπολογίας γενικού γράφου δηλαδή σε αυθαίρετη (οποιαδήποτε) τοπολογία. Είναι κεντρικοποιημένο πρωτόκολλο γιατί αρχικοποιείται από έναν κόμβο, και χρησιμοποιείται συχνά ως δομικό μέρος άλλων προβλημάτων με σκοπό τη μετάδοση πληροφορίας και το συγχρονισμό. Παραδοχές H τοπολογία είναι γενικός γράφος. Υπάρχει μόνο ένας κόμβος που θα αναλάβει τον ρόλο του αρχικοποιητή. Ο χρονισμός είναι ασύγχρονος. Γενική προσέγγιση πρωτοκόλλου: Ο αρχικοποιητής μεταδίδει τη πληροφορία σε όλους τους άλλους κόμβους. Στη συνέχεια όλοι οι μη αρχικοποιητές θα ενημερώσουν τον αρχικοποιητή πως έλαβαν την πληροφορία. ΠΕΡΙΓΡΑΦΗ ΠΡΩΤΟΚΟΛΛΟΥ 1. Ο αρχικοποιητής: a. Στέλνει σε όλους τους γείτονες το μήνυμα token. b. Περιμένει να λάβει από όλους τους γείτονες το μήνυμα token. c. Αποφασίζει. 2. Οι μη-αρχικοποιητές: a. Όταν λάβουν το πρώτο token «σημειώνουν» τον αποστολέα ως πατέρα τους. b. Αναμεταδίδουν το token σε όλους τους γείτονες, εκτός του πατέρα τους. c. Όταν λάβουν από όλους τους γείτονες ένα token το στέλνουν στον πατέρα τους. ΑΠΡΙΛΙΟΣ, 2018 ΕΙΣΑΓΩΓΗ ΣΤΑ ΚΑΤΑΝΕΜΗΜΕΝΑ ΣΥΣΤΗΜΑΤΑ 2
Σε ψευδογλώσσα, το πρωτόκολλο ECHO εμφανίζεται στον παρακάτω πίνακα initiator var recp: integer init 0; /* μετράει τον αριθμό των γειτόνων του p από τους οποίους έχει παραληφθεί το token */ fatherp : δείκτης σε κόμβο init udef; begin forall q Neighp do send <tok> to q; while recp < # Neighp do begin receive <tok>; recp:=recp+1; decide end non-initiator begin receive <tok> from neighbor q; fatherp=q; recp:=recp+1; forall q Neighp, q fatherp do send <tok> to q; while recp < # Neighp do begin receive <tok>; recp:=recp+1; end; send <tok> to fatherp end ΑΠΡΙΛΙΟΣ, 2018 ΕΙΣΑΓΩΓΗ ΣΤΑ ΚΑΤΑΝΕΜΗΜΕΝΑ ΣΥΣΤΗΜΑΤΑ 3
ΕΡΓΑΣΤΗΡΙΑΚΗ ΆΣΚΗΣΗ Σε αυτό το τμήμα της εργαστηριακής άσκησης θα δοκιμάσουμε να υλοποιήσουμε το πρωτόκολλο ECHO και να δοκιμάσουμε την επίδοσή του. Κατά την διάρκεια εκτέλεσης του εργαστηριακού οδηγού θα πρέπει να συμπληρώνετε παράλληλα και την εργαστηριακή σας αναφορά, πρότυπο της οποίας μπορείτε να βρείτε στο openclass του μαθήματος. Η εργαστηριακή αναφορά θα πρέπει να έχει παραδοθεί την ημέρα πριν το επόμενο εργαστήριο, σύμφωνα με τις οδηγίες. Βήμα 1: Στο πρώτο βήμα της εργαστηριακής άσκησης θα προσπαθήσουμε να υλοποιήσουμε το πρωτόκολλο ECHO και να μελετήσουμε την συμπεριφορά τους. Για αυτό το λόγο: 1. Συνδεθείτε σε ένα λειτουργικό Linux (Ubuntu ή LUbuntu). 2. Ανοίξτε ένα terminal 3. Δημιουργήστε έναν φάκελο MPI_ABCD, όπου ABCD το μητρώο σας. Για να το πετύχετε αυτό, εκτελέστε την εντολή mkdir MPI_ABCD. Στην συνέχεια μπείτε στον φάκελο εκτελώντας την εντολή cd MPI_ABCD. 4. Δημιουργήστε το αρχείο echo.c εκτελώντας την εντολή gedit echo.c 5. Αντιγράψτε το παρακάτω πρόγραμμα στο αρχείο σας #include "mpi.h" #include <stdio.h> #include <stdlib.h> int main( int argc, char *argv[] ) { int errs = 0, i, k, neighbournumber,token; int wsize = 5; int father; int *index, *edges, *outindex, *outedges,*neighbours; int nnodes, nedges; MPI_Comm comm1, comm2; MPI_Request request[5]; MPI_Status status, status2; MPI_Init( &argc, &argv ); //preparation of environment of MPI MPI_Comm_size( MPI_COMM_WORLD, &wsize ); // Get the number of Processors int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); if (wsize >= 3) { // If Processor number is more than 3 we can make a graph. index = (int*)malloc(wsize * sizeof(int) ); edges = (int*)malloc(wsize * 2 * sizeof(int) ); neighbours = (int*)malloc(wsize * 10 * sizeof(int) ); // allocate memory for arrays if (!index!edges) { printf( "Unable to allocate %d words for index or edges\n", 3 * wsize ); //Error Control if we cannot allocate memory fflush(stdout); MPI_Abort( MPI_COMM_WORLD, 1 ); ΑΠΡΙΛΙΟΣ, 2018 ΕΙΣΑΓΩΓΗ ΣΤΑ ΚΑΤΑΝΕΜΗΜΕΝΑ ΣΥΣΤΗΜΑΤΑ 4
index[0]=2; // We are filling index values of the graph index[1]=5; index[2]=6; index[3]=8; index[4]=10; edges[0]=1; // We are filling edge values of the graph edges[1]=4; edges[2]=0; edges[3]=2; edges[4]=3; edges[5]=1; edges[6]=1; edges[7]=4; edges[8]=0; edges[9]=3; &comm1 ); MPI_Graph_create( MPI_COMM_WORLD, wsize, index, edges, 0, if (rank == 0) //Initiator { MPI_Graph_neighbors_count(comm1,rank,&neighbourNumber); MPI_Graph_neighbors(comm1,rank,neighbourNumber,neighbours); printf( "My node no is = %d and I have %d neighbours\n", rank, neighbournumber); printf( "My neıghbours are: "); for(i=0;i<neighbournumber;i++) { printf("%d,",neighbours[i]); printf( "\n-------------------------------------\n"); //Send tokens to every neighbour MPI_Send(&token, 1, MPI_INT, neighbours[k], 0, MPI_COMM_WORLD); //wait for a response from evey child, in order to finilize MPI_Irecv(&token, 1, MPI_INT, neighbours[k], 0, MPI_COMM_WORLD, &request[k]); else { MPI_Wait(&request[k], &status); printf("echo finised\n"); MPI_Recv(&token, 1, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status2); father = status2.mpi_source; MPI_Graph_neighbors_count(comm1,rank,&neighbourNumber); ΑΠΡΙΛΙΟΣ, 2018 ΕΙΣΑΓΩΓΗ ΣΤΑ ΚΑΤΑΝΕΜΗΜΕΝΑ ΣΥΣΤΗΜΑΤΑ 5
MPI_Graph_neighbors(comm1,rank,neighbourNumber,neighbours); //send token to all neighbours except father if (neighbours[k]!= father) MPI_Send(&token, 1, MPI_INT, neighbours[k], 0, MPI_COMM_WORLD); //wait for token from all neighbours if (neighbours[k]!= father) MPI_Irecv(&token, 1, MPI_INT, neighbours[k], 0, MPI_COMM_WORLD, &request[k]); if (neighbours[k]!= father) MPI_Wait(&request[k], &status); MPI_Send(&token, 1, MPI_INT, father, 0, MPI_COMM_WORLD); printf("node %d has node %d as father\n", rank, father); MPI_Comm_free( &comm1 ); //Empty comm1 and give to system. MPI_Finalize(); //Finish MPI return 0; 6. Σχεδιάστε τον γράφο που δηλώνεται στο παραπάνω πρόγραμμα. 7. Αφού αποθηκεύσετε και κλείσετε το αρχείο, μεταγλωττίστε το εκτελώντας την εντολή mpicc echo.c o echo 8. Εάν δεν έγινε κάποιο λάθος, ο μεταγλωττιστής δεν θα πρέπει να βγάλει κανένα μήνυμα. Τότε, μπορείτε να εκτελέσετε το πρόγραμμα, τρέχοντας την εντολή mpirun np 5./echo. Σε αυτή την εντολή, η παράμετρος np καθορίζει το πλήθος των διεργασιών που θα δημιουργηθούν στον «κόσμο» μας. 9. Αντιγράψτε την έξοδο του προγράμματος στην εργαστηριακή αναφορά σας. Τι παρατηρείτε; ΑΠΡΙΛΙΟΣ, 2018 ΕΙΣΑΓΩΓΗ ΣΤΑ ΚΑΤΑΝΕΜΗΜΕΝΑ ΣΥΣΤΗΜΑΤΑ 6
ΔΡΑΣΤΗΡΙΟΤΗΤΕΣ Προσπαθήστε να λύσετε τις παρακάτω δραστηριότητες. Οι απαντήσεις κάθε δραστηριότητας θα πρέπει να εμφανίζονται στην εργαστηριακή σας αναφορά. 1. Μετατρέψτε το παράδειγμα του βήματος 1, έτσι ώστε το πρωτόκολλο να τρέξει πάνω στον παρακάτω γράφο index[0]=4; index[1]=6; index[2]=7; index[3]=8; index[4]=10; edges[0]=1; edges[1]=2; edges[2]=3; edges[3]=4; edges[4]=0; edges[5]=4; edges[6]=0; edges[7]=0; edges[8]=0; edges[9]=1; 2. Μετατρέψτε το παράδειγμα του βήματος 1, έτσι ώστε κάθε κόμβος να τυπώνει το πλήθος των φορών που κατείχαν το token. 3. Μετατρέψτε το παράδειγμα του βήματος 1, έτσι ώστε ο αρχικοποιητής να υπολογίζει το χρονικό διάστημα που απαιτήθηκε να εκτελεστεί το πρωτόκολλο. 4. Εκτελέστε το πρωτόκολλο ECHO για τον παρακάτω γράφο. 5. Μετατρέψτε το πρόγραμμα του βήματος 1 έτσι ώστε ο αρχικοποιητής να μπορεί να είναι οποιοσδήποτε κόμβος, ο οποίος θα δίνεται ως είσοδος του προγράμματος. 6. Μετατρέψτε το πρόγραμμα του βήματος 1, έτσι ώστε: a. Κάθε κόμβος μη αρχικοποιητής να παράγει έναν τυχαίο αριθμό R στο διάστημα 1-50 ΑΠΡΙΛΙΟΣ, 2018 ΕΙΣΑΓΩΓΗ ΣΤΑ ΚΑΤΑΝΕΜΗΜΕΝΑ ΣΥΣΤΗΜΑΤΑ 7
b. Κατά την φάση σύγκλισης του αλγορίθμου, τα παιδιά να στέλνουν στον πατέρα τους τον R, ο οποίος θα πρέπει να υπολογίζει το άθροισμά τους και να το προσθέτει στον δικό του τυχαίο αριθμό. Στο τέλος του αλγορίθμου θα πρέπει ο αρχικοποιητής να έχει υπολογίσει το άθροισμα όλων των τυχαίων αριθμών R. 7. Μετατρέψτε το πρόγραμμα του βήματος 1, έτσι ώστε: a. Κάθε κόμβος μη αρχικοποιητής να παράγει έναν τυχαίο αριθμό R στο διάστημα 1-50 b. Κατά την φάση σύγκλισης του αλγορίθμου, τα παιδιά να στέλνουν στον πατέρα τους τον R, ο οποίος θα πρέπει να υπολογίζει το μικρότερο από τα R που έλαβε (συμπεριλαμβανομένου του δικού του) και να ανανεώνει τον δικό του αριθμό. Στο τέλος του αλγορίθμου θα πρέπει ο αρχικοποιητής να έχει υπολογίσει τον μικρότερο από όλους τους τυχαίους αριθμούς R. ΑΠΡΙΛΙΟΣ, 2018 ΕΙΣΑΓΩΓΗ ΣΤΑ ΚΑΤΑΝΕΜΗΜΕΝΑ ΣΥΣΤΗΜΑΤΑ 8
ΑΠΡΙΛΙΟΣ, 2018 ΕΙΣΑΓΩΓΗ ΣΤΑ ΚΑΤΑΝΕΜΗΜΕΝΑ ΣΥΣΤΗΜΑΤΑ 9
ΒΙΒΛΙΟΓΡΑΦΙΑ "MPI: The Complete Reference" by Snir, Otto, Huss-Lederman, Walker, and Dongarra, MIT Press (also in Postscript and html) "Using MPI: Portable Parallel Programming with the Message-Passing Interface, " by Gropp, Lusk and Skjellum, MIT Press Designing and Building Parallel Programs, by Ian Foster, Addison-Wesley, 1995. Parallel Programming with MPI, by Peter Pacheco, Morgan-Kaufmann, 1997. MPI θεωρία και Εφαρμογές, A. Μάργαρης, Εκδόσεις Τζιόλα, 2008. Homepage: http:// www.mcs.anl.gov/mpi ΑΠΡΙΛΙΟΣ, 2018 ΕΙΣΑΓΩΓΗ ΣΤΑ ΚΑΤΑΝΕΜΗΜΕΝΑ ΣΥΣΤΗΜΑΤΑ 10