Next              Up                Back               Contents

Επόμενο:Κεφάλαιο 3o : Αρχιτεκτονική συστημάτων διαμοιραζόμενης μνήμης Πάνω:Κεφάλαιο 2ο: Παραλληλισμός Δεδομένων Πίσω:Προγραμματιστικές Εργασίες        


 

ΑΣΚΗΣΕΙΣ

 

1. Γράψτε μια σειριακή συνάρτηση που να υπολογίζει και να επιστρέφει το άθροισμα των στοιχείων ενός μονοδιάστατου πίνακα. Γράψτε το κυρίως πρόγραμμα ώστε να εφαρμόζει την συνάρτηση για 4 διαφορετικούς πίνακες. Προσοχή στις συγκρούσεις των καθολικών διαμοιραζόμενων μεταβλητών του προγράμματος.

2. Για να βελτιωθεί η οπτική ποιότητα μιας εικόνας που απεικονίζεται σε ένα διδιάστατο πίνακα εικονοστοιχείων (pixel), εφαρμόζεται ορισμένες φορές ένας αλγόριθμος λείανσης (smoothing). Ένας απλός αλγόριθμος λείανσης αντικαθιστά την τιμή κάθε εικονοστοιχείου με τον μέσο όρο των γειτονικών του εικονοστοιχείων. Κάθε εικονοστοιχείο έχει 8 γείτονες, περιλαμβάνοντας και τους διαγώνιους γείτονες. Ένας άλλος αλγόριθμος αντικαθιστά την τιμή κάθε εικονοστοιχείου με τον μέσο όρο 9 εικονοστοιχείων, περιλαμβάνοντας και το ίδιο το εικονοστοιχείο μαζί με τα 8 γειτονικά. Σε αυτή την άσκηση, πρέπει να γράψετε και να εκτελέσετε ένα παράλληλο πρόγραμμα που να εφαρμόζει αυτό τον αλγόριθμο σε μια εικόνα. Για να απλοποιηθεί το πρόγραμμα, μην τροποποιήσετε τα εικονοστοιχεία που βρίσκονται πάνω στις 4 πλευρές του πίνακα απεικόνισης της εικόνας.

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

4. Φανταστείτε το παρακάτω κομμάτι ενός προγράμματος:

  ...
FORK x := x+1;
FORK y := 23*z;
FORK z := a[i]+a[j];
  ...

Ανεξάρτητα από τον παραλληλισμό αυτής της πρότασης, έχει βρεθεί ότι ο συνολικός χρόνος εκτέλεσης μπορεί να μειωθεί, με την αφαίρεση του τελεστή FORK άρα και του παραλληλισμού. Ποια είναι η εξήγηση για αυτή τη φαινομενική αντίφαση;

5. Το πρόγραμμα της παράλληλης ταξινόμησης σειράς του διαγράμματος 2.3 δημιουργεί n διεργασίες, μία για κάθε στοιχείο του πίνακα. Ξαναγράψτε το πρόγραμμα για να εκτελείται σε ένα σύστημα διαμοιραζόμενης μνήμης που έχει n/5 επεξεργαστές.

6. Ένα άνυσμα απεικονίζεται σε ένα μονοδιάστατο πίνακα και μια μήτρα σε ένα διδιάστατο πίνακα. Θυμηθείτε ότι το γινόμενο δύο ανυσμάτων A και B, είναι ένας αριθμός C που υπολογίζεται με βάση τον πολλαπλασιασμό αντίστοιχων στοιχείων των A και B και μετά προσθέτοντας όλα τα γινόμενα που προκύπτουν (εσωτερικό γινόμενο). Το γινόμενο μιας μήτρας M με ένα άνυσμα A είναι ένα νέο άνυσμα C. Κάθε στοιχείο του ανύσματος C υπολογίζεται ως εξής:

C[ i ] = εσωτερικό γινόμενο του ανύσματος A με τη γραμμή i της M

Γράψτε ένα παράλληλο πρόγραμμα που να υπολογίζει το γινόμενο μιας μήτρας [20x20] με ένα άνυσμα που περιέχει 20 στοιχεία.

7. Φανταστείτε την παρακάτω έκδοση του προγράμματος παράλληλης ταξινόμησης σειράς όπου η διαδικασία PutinPlace έχει μεταφερθεί στο σώμα του κυρίως προγράμματος ως τμήμα ενός βρόχου FORALL:

PROGRAM NewRankSort;
 CONST  n=100;
 VAR values, final:  ARRAY [1..n] OF INTEGER;
     i: INTEGER;
     src, testval, j, rank: INTEGER;

  BEGIN
  FOR i := 1 to n Do
		Readln(values[i] ); (*  Αρχικοποιεί τις τιμές που θα ταξινομηθούν  *)	
		FORALL  src := 1 TO n DO
  		BEGIN
	   			testval := values[src];
	   			j := src; (* το j θα μετακινηθεί σειριακά σε όλο τον πίνακα  *) 
	   			rank := 0;
	   			REPEAT
	      			j  :=  j MOD n+1;
					IF testval >= values[j] THEN rank := rank + 1;
   			UNTIL  j=src;
					final[rank] := testval;	(*τοποθετεί τις τιμές στη  *) 								 (* ταξινομημένη θέση  *)
	   		END;
END.

α) Το πρόγραμμα αντιμετωπίζει ένα σοβαρό πρόβλημα και δεν θα παράγει τα σωστά αποτελέσματα. Εξηγείστε τη φύση του προβλήματος.

β) Υποδείξτε ορισμένες μικρές τροποποιήσεις που θα διορθώσουν το πρόβλημα και θα

επιτρέψουν στο πρόγραμμα να λειτουργήσει σωστά.

8. Το πρόγραμμα παράλληλης ταξινόμησης σειράς δεν θα λειτουργήσει σωστά εάν η λίστα που είναι προς ταξινόμηση περιέχει όμοιες τιμές.

α) Εξηγείστε τη φύση του σφάλματος που προκύπτει εξαιτίας των όμοιων τιμών που

υπάρχουν στη λίστα.

β) Υποδείξτε μια μικρή τροποποίηση που θα διορθώσει το πρόβλημα του προγράμματος.

9. Στο πρόγραμμα παράλληλου πολλαπλασιασμού μητρών που παρουσιάζεται στο κεφάλαιο, δημιουργούνται n2 διεργασίες. Ξαναγράψτε το πρόγραμμα για ένα σύστημα διαμοιραζόμενης μνήμης που διαθέτει μόνο n επεξεργαστές. Προσέξτε ιδιαίτερα τη χρήση των διαμοιραζόμενων και τοπικών μεταβλητών ώστε να αποφευχθούν οι παρεμβολές ανάμεσα στις παράλληλες διεργασίες.

10. Φανταστείτε την παρακάτω πρόταση FORALL:

FORALL i := 1 TO 200 GROUPING size DO
A[i] := 10*A[i];

Χρησιμοποιείστε το διαλογικό σύστημα της Multi-Pascal για να υπολογίσετε την επιτάχυνση που επιτυγχάνεται από αυτή την πρόταση καθώς η μεταβλητή size παίρνει τις τιμές από 1 έως 25. Ποιο είναι το άριστο μέγεθος ομάδος που μεγιστοποιεί την επιτάχυνση; Εξηγείστε τους λόγους του γενικού προτύπου αυτής της απόκλισης. Ποιος είναι ο λόγος της αύξησης στην αρχή και ποιο ο λόγος της μείωσης στο τέλος;

11. Ο σειριακός χρόνος εκτέλεσης της εντολής FORALL ορίζεται ως ο χρόνος που χρειάζεται για να εκτελεστεί η ίδια πρόταση με το FORALL αφού αντικατασταθεί από το FOR. Η επιτάχυνση της δήλωσης FORALL παράγεται από τη διαίρεση του χρόνου εκτέλεσης της προς το χρόνο σειριακής εκτέλεσης. Φανταστείτε μια πρόταση εντολής FORALL που δημιουργεί n παράλληλες διεργασίες. Το μέγεθος των διεργασιών είναι τέτοιο ώστε να έχουν χρόνο εκτέλεσης 10 φορές μεγαλύτερο από το χρόνο σειριακής εκτέλεσης. Διατυπώστε μια αλγεβρική παράσταση ως προς n που υπολογίζει τη μέγιστη δυνατή επιτάχυνση της πρότασης FORALL που εκτελείται σε ένα παράλληλο σύστημα με p επεξεργαστές. Διαλέξτε για το σκοπό αυτό, ένα μέγεθος ομάδος για τη FORALL που να μεγιστοποιεί την επιτάχυνση.

12. Θεωρείστε το παρακάτω τμήμα προγράμματος:


PROGRAM Sample;
 VAR a,b: INTEGER;
  BEGIN
    a := 4;
    b := 2;
    VAR t,a  NTEGER;
    BEGIN
		a := 7;
		t := 10;
		b := t+5;
    END;
    Writeln(a,b);
  END.

Ποιες θα είναι οι τελικές τιμές των μεταβλητών a και b που θα εμφανισθούν στο τέλος; Εξηγείστε τους λόγους της απάντησης σας.

 

13. Θεωρείστε την παρακάτω πρόταση FORALL που παράγει τον πίνακα C που αποτελεί το άθροισμα των πινάκων Α και Β:

FORALL i := 1 TO 50 DO 
		C[i] := A[i]+B[i];

Σε μια προσπάθεια να παραχθεί μια παρόμοια πρόταση με τη βοήθεια της FORK, χρησιμοποιείται ο παρακάτω βρόχος FOR:


FOR  i := 1 TO 50 DO
      FORK C[i] := A[i]+B[i];

Ωστόσο, όταν η πρόταση εκτελείται, παράγεται ένα εσφαλμένο αποτέλεσμα στον πίνακα C. Εξηγείστε γιατί παράγεται λανθασμένο αποτέλεσμα.

14. (α) Σε αυτό το πρόβλημα πρέπει να γράψετε ένα παράλληλο πρόγραμμα που θα εκτελεί αναζήτηση σε μια συνδεδεμένη λίστα για μια δοθείσα τιμή. Κάθε μονάδα δεδομένων της συνδεδεμένης λίστας είναι ένας πίνακας πραγματικών τιμών. Το πρόγραμμα θα πρέπει να δημιουργεί παράλληλες διεργασίες, που η κάθε μια θα κάνει αναζήτηση σε ένα διαφορετικό πίνακα. Οι παρακάτω τύποι δηλώσεων πρέπει να χρησιμοποιηθούν στην αρχή του προγράμματος καθώς επίσης και η διαδικασία Search. Μην δώσετε προσοχή στην αρχικοποίηση της λίστας.


PROGRAM SearchList;
TYPE	arraytype = ARRAY [1..100] OF REAL;
	pnttype = ^itemtype;
	itemtype = RECORD
			data: arraytype;
			next: pnttype;
END;     
VAR found: BOOLEAN;
    listhead: pnttype;

PROCEDURE Search(inarray: arraytype);
 VAR i : INTEGER;
  BEGIN
	FOR i := 1 TO 100 DO
	  IF  inarray[i] = value THEN found := TRUE;
END;


(β) Θα μπορέσει το πρόγραμμα να πετύχει μια καλή επιτάχυνση για μια λίστα με 10 στοιχεία;

15. Θεωρείστε το πρόγραμμα του κεφαλαίου που χρησιμοποιεί τον τελεστή FORK για να δημιουργήσει παράλληλες διεργασίες που εφαρμόζουν μια διαδικασία σε κάθε στοιχείο μιας συνδεδεμένης λίστας. Ξαναγράψτε το πρόγραμμα χρησιμοποιώντας αυτή τη φορά μια πρόταση FORALL για τη διεργασία των διεργασιών αντί του τελεστή FORK. Αυτό θα απαιτήσει μια μικρή αναδιοργάνωση του προγράμματος και τη προσθήκη ορισμένων νέων μεταβλητών. Προσπαθήστε να ελαχιστοποιήσετε τις αλλαγές που χρειάζεται το νέο πρόγραμμα.

16. Η παρούσα άσκηση παρέχει εξάσκηση πάνω στην εφαρμογή των κανόνων εμβέλειας των μετρητών των προτάσεων FORALL (βλέπε παράγραφο 2.5.2). Δώστε το ακριβές αποτέλεσμα καθενός από τα 3 παρακάτω προγράμματα:


PROGRAM Test1;
 VAR i: integer;
  BEGIN
		i := 25;
	  		FORALL i := 1 TO 10 DO
				WRITELN(i);
				WRITELN(i);
  END.


PROGRAM Test2;
 VAR  i: INTEGER;


PROCEDURE Print;
  BEGIN 
		Writeln(i);
  END;


  BEGIN
	i := 25;
	FORALL  i := 1 TO 10 DO
	 Print;
  END.


PROGRAM Test3;
 VAR i: INTEGER;


PROCEDURE Print(val: integer);
  BEGIN
		Writeln(val);
  END;


  BEGIN
		i := 25;
		FORALL i := 1 TO 10 DO
			Print(i);
END.


17. Η παρακάτω πρόταση υπολογίζει το άθροισμα των στοιχείων ενός πίνακα Α:

OR	i := 1 TO n DO
	sum :=  sum + A[i];

Στην προσπάθεια να υπολογιστεί το άθροισμα παράλληλα, δίδεται η παρακάτω πρόταση:

FORALL i := 1 TO n DO
	 sum := sum + A[i];

Εξηγείστε γιατί η πρόταση FORALL παράγει λανθασμένο αποτέλεσμα για το άθροισμα.

18. Για ένα συγκεκριμένο αλγόριθμο, υποθέστε ότι 8% του κώδικα του είναι αμιγώς σειριακός που δεν μπορεί να μετατραπεί σε παράλληλο κώδικα. Χρησιμοποιήστε το νόμο του Amdahl για να σχεδιάσετε ένα γράφημα της μέγιστης επιτάχυνσης του αλγόριθμου καθώς ο αριθμός των επεξεργαστών παίρνει τιμές από 1 έως 30. Στο ίδιο γράφημα, σχεδιάστε την καμπύλη μέγιστης επιτάχυνσης για ένα αλγόριθμο που περιέχει μόνο 4% σειριακό κώδικα.

19. Το γράφημα του σχεδιαγράμματος 2.7 υποθέτει ότι το σύστημα κατανεμημένης μνήμης διαθέτει 100 επεξεργαστές. Υπολογίστε και σχεδιάστε το γράφημα ξανά, υποθέτοντας ότι το σύστημα έχει μόνο 50 επεξεργαστές.

20. Φανταστείτε ένα σειριακό πρόγραμμα του οποίου το συνολικό πλήθος υπολογισμών είναι O(n3). Υποθέστε ότι στην παράλληλη έκδοση του προγράμματος, η αρχικοποίηση πρέπει να γίνει σειριακά και επομένως το σύνολο υπολογισμών είναι O(n). Ωστόσο, το υπόλοιπο του προγράμματος λειτουργεί παράλληλα. Χρησιμοποιήστε το νόμο του Amdahl για να διατυπώστε μια γενική αλγεβρική παράσταση που υπολογίζει τη μέγιστη επιτάχυνση του προγράμματος σε ένα σύστημα κατανεμημένης μνήμης με p επεξεργαστές.

21. Υπό το πρίσμα του νόμου του Amdahl, εξηγείστε γιατί είναι σημαντικό σε συστήματα κατανεμημένης μνήμης να έχουν ειδικά σχεδιασμένα, υψηλού εύρους ζώνης συστήματα εισόδου-εξόδου ( I / O ).

 

ΠΡΟΤΕΙΝΟΜΕΝΕΣ ΛΥΣΕΙΣ

1.  

           Program K2A1;

               var pin:array [1..4,1..5] of integer;

                       i,j:integer;

               procedure calculate(pnt:integer);

                   var sum,k:integer;

             begin

               sum:=0;

               for k:=1 to 5 do

                   sum:=sum+pin[pnt,k];

                   writeln(sum);

               end

        begin

        for i:=1 to 4 do

           for j:=1 to 5 do

               readln(pin[i,j]);

        forall i:=1 to 4 do

        calculate(i);

        end.

2.

        Program K2A2;

            constn=768;

                      m=1024;

            var pin:array [1..n,1..m] of integer;

                  i,j:integer;

            procedure smooth(t,s:integer);

               begin

                   pin[t,s]:=[pin[t-1,s-1]+pin[t-1,s]+pin[t-1,s+1]+pin[t,s-1]+pin[t,s]+pin[t,s+1]+pin[t+1,s-1]+pin[t+1,s]+pin[t+1,s+1]]/9;

               end;

        begin

            for i:=1to n do

               for j:=1 to m do

                   pin[i,j]:=1;

            forall i:=2to n-1 do

               forall j:=2 to m-1 do

                   smooth(i,j);

        end.

3.

        ProgramK2A3;

            Const n=6;

            Var A:array[1..n,1..n] of integer;

                   i,j,Num:integer;

                   Found:boolean;

            ProcedureSearch(element:integer);

            Begin

                  if element=Num then Found:=true;

            End;

        Begin

           Found:=false;

            write('Δώσε τον αριθμό αναζήτησης')

            readln(Num);

            for i:=1 to n do

               for j:=1 to n do

                   readln(a[i,j]);

            forall i:=1 to n do

               forall j:=1 to n grouping 2 do

                   Search(a[i,j]);

            if found then writeln('Ο αριθμός βρέθηκε');

            else writeln('Ο αριθμός δεν βρέθηκε');

        End.

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

 

5.

        Program K2A5;

            CONST n=10;

            var values,final:array [1..n] of integer;

                  i:integer;

            procedure putinplace(src:integer);

               var testval,j,rank:integer;

            begin

               testval:=values[src];

               j:=src;

               rank:=0;

               repeat

                   j:=j MOD n+1;

                   if testval >= values[j] then rank:=rank+1;

               until j=src;

               final[rank]:=testval;

            end;

       begin

            for i:=1 to n do

               index[i]:=0;

            for i:=1 to n do

               readln(values[i]);

            forall i:=1to n grouping 5 do

               putinplace(i);

        end.

6.

        Program K2A6;

            CONST n=20;

            var matrix:array [1..n,1..n] of integer;

                vector,c:array [1..n] of integer;

                i:integer;

            procedure multiply(i:integer);

                var j:integer;

            begin

                for k:=1 to n do

                    c[i]:=c[i]+vector[k]*matrix[i,k];

            end;

        begin

            forall i:=1 to n do

                multiply(i);

        end.

8.

        Program K2A8;

            CONST n=8;

            var values,final:array [1..n] of integer;

                  i: integer;    

            procedure putinplace(src:integer);

               var testval,j,rank,sum:integer;

            begin

               testval:=values[src];

               j:=src;

               rank:=0;

               sum:=0;

            repeat

               j:=j MOD n+1;

               if testval >= values[j] then rank:=rank+1;

               if testval = values[j] then sum:=sum+1;

            until j=src;

            repeat

               final[rank-sum+1]:=testval;

               sum:=sum-1;

            until sum=0;

            end;

        begin

            for i:=1 to n do

               readln(values[i]);

            forall i:=1 to n do

               putinplace(i);

            for i:=1 to n do

                writeln(final[i],values[i]);

        end.

10. Ο συνολικός αριθμός των διεργασιών παιδιών που δημιουργούνται είναι n/size. Ο συνολικός χρόνος δημιουργίας όλων των διεργασιών είναι επομένως cn/size. Επομένως ο χρόνος εκτέλεσης για τη FORALL έχει ως εξής :

cn/size+sizeT.

Για να ελαχιστοποιηθεί ο χρόνος εκτέλεσης σε σχέση με το size, απλά παίρνουμε την πρώτη παράγωγο ως προς size και τη θέτουμε ίση με το 0. Το αποτέλεσμα είναι το ακόλουθο:

image.

Στο πρόβλημά μας το βέλτιστο μέγεθος ομάδας είναι size=12.

 

12. Οι τελικές μεταβλητές των τιμών θα είναι 4 και 15 γιατι το a συμπεριλαμβάνεται στην ομάδα εντολών  που αρχίζει με το var ενώ το b όχι.

 

13. Το αποτέλεσμα είναι λανθασμένο επειδή στην περίπτωση του FORK αφού δημιουργηθούν και οι n διεργασίες παιδιά ο βρόχος for θα σταματήσει να εκτελείται και η εκτέλεση της κύριας διεργασίας θα συνεχίσει, ενώ στην περίπτωση του FORALL η διεργασία γονέας περιμένει όλα τα παιδιά να τερματίσουν.

 

17. Ο παράλληλος υπολογισμός δεν μπορεί να επιτευχθεί με την μετατροπή του εσωτερικού βρόχου FOR σε εντολή FORALL. Οι επαναλήψεις του εσωτερικού βρόχου χρησιμοποιούν τη μεταβλητή sum για να συσσωρεύσουν το άθροισμα: η μεταβλητή sum διαβάζει και γράφει σε κάθε επανάληψη του βρόχου. Επομένως, αυτές οι σειριακές επαναλήψεις δεν μπορόυν απλά να μοιραστούν σε διαφορετικούς επεξεργαστές που θα εκτελούνται παράλληλα. Αν γινόταν αυτό τότε οι επεξεργαστές θα προσπαθούσαν να διαβάσουν και να μεταβάλλουν την τιμή της sum, γεγονός που θα προκαλούσε παρεμβολές και θα παρήγαγε λανθασμένα αποτελέσματα.

 

18. Για να σχεδιάσουμε το γράφημα θα χρησιμοποιήσουμε τον νόμο του Amdahl.

Αριθμός Επεξεργαστών Μέγιστη Επιτάχυνση(f=0.08) Μέγιστη Επιτάχυνση(f=0.04)
1 1 1
2 1,851851852 1,923076923
3 2,586206897 2,777777778
4 3,225806452 3,571428571
5 3,787878788 4,310344828
6 4,285714286 5
7 4,72972973 5,64516129
8 5,128205128 6,25
9 5,487804878 6,818181818
10 5,813953488 7,352941176
11 6,111111111 7,857142857
12 6,382978723 8,333333333
13 6,632653061 8,783783784
14 6,862745098 9,210526316
15 7,075471698 9,615384615
16 7,272727273 10
17 7,456140351 10,36585366
18 7,627118644 10,71428571
19 7,786885246 11,04651163
20 7,936507937 11,36363636
21 8,076923077 11,66666667
22 8,208955224 11,95652174
23 8,333333333 12,23404255
24 8,450704225 12,5
25 8,561643836 12,75510204
26 8,666666667 13
27 8,766233766 13,23529412
28 8,860759494 13,46153846
29 8,950617284 13,67924528
30 9,036144578 13,88888889

 

                    image

 

 


     Next              Up                Back               Contents

Επόμενο:Κεφάλαιο 3o : Αρχιτεκτονική συστημάτων διαμοιραζόμενης μνήμης Πάνω:Κεφάλαιο 2ο: Παραλληλισμός Δεδομένων Πίσω:Προγραμματιστικές Εργασίες