ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΗΛΕΚΤΡΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΚΑΙ ΜΗΧΑΝΙΚΩΝ Η/Υ ΔΕΥΤΕΡΗ ΠΡΟΟΔΟΣ ΣΤΗΝ ΟΡΓΑΝΩΣΗ ΣΤΟΥΣ Η/Y (ΗΥ232) Δευτέρα, 3 Νοεμβρίου 25 ΔΙΑΡΚΕΙΑ ΔΙΑΓΩΝΙΣΜΑΤΟΣ 3 ΛΕΠΤΑ Για πλήρη βαθμό θα πρέπει να δείξετε καθαρά την δουλειά σας! Επέκταση εντολών του επεξεργαστή MIPS (3 = 5 + + 5 μονάδες) Στην μικροαρχιτεκτονική διοχέτευσης του MIPS, θέλουμε να υλοποιήσουμε την εντολή store με postincrement sw+ rt, imm(rs) η οποία ακολουθεί το Ι-format και υλοποιεί την παρακάτω λειτουργία: Μ[rs] = rt; Πεδίο opcode rs rt imm rs += imm Bits 3:26 25:2 2:6 5: Η άσκηση αυτή σας ζητάει να υλοποιήσετε την εντολή αυτή ξεκινώντας από την βασική αρχιτεκτονική διοχέτευσης του MIPS που σας δίδεται στο έντυπο. Όλες οι αλλαγές θα πρέπει να γίνουν πάνω στο σχήμα που σας δίδεται και θα πρέπει να είναι καθαρογραμμένες! Πιο συγκεκριμένα θα πρέπει: α) να υλοποιήσετε όλες τις αλλαγές στο τμήμα δεδομένων. Μπορείτε να προσθέσετε καινούργια modules (πχ πολυπλέκτες, ALUs, κοκ), αλλά δεν επιτρέπεται να αλλάξετε την λειτουργικότητα ή το μέγεθος κανενός ήδη υπάρχοντος module. Επίσης μπορείτε να προσθέσετε καινούργια σήματα και συνδέσεις. Για αυτό το ερώτημα, αγνοείστε τυχόν θέματα προώθησης (forwarding) της sw+ σε σχέση με προηγούμενες εντολές. β) να υλοποιήσετε όλες τις αλλαγές στο τμήμα ελέγχου. Αυτό συμπεριλαμβάνει τις τιμές τυχόν νέων σημάτων ελέγχου που θα δημιουργηθούν για τις ανάγκες της εντολής αυτής και για τις παλιές εντολές, καθώς και τις τιμές των ήδη υπαρχόντων σημάτων ελέγχου που φαίνονται στο σχήμα για την sw+. Στον παρακάτω πίνακα σας δίνονται οι τιμές των σημάτων ελέγχου για μερικές εντολές που εκτελεί ο επεξεργαστής και εσείς θα πρέπει να συμπληρώσετε τα λευκά κενά. γ) Μπορείτε να επισημάνετε, όπου υπάρχουν, περιπτώσεις forwarding ή stalling που θα υπάρξουν με την εντολή sw+ σε σχέση με άλλες εντολές που εκτελούνται μετά από την sw+ στον κώδικα; a) Σε αντίθεση με την συμβατική εντολή lw, η sw+ δεν κάνει πρόσθεση για να βρεί την πραγματική διεύθυνση προσπέλασης, αλλά χρησιμοποιεί μόνο την τιμή του καταχωρητή βάσης. Αυτό σημαίνει ότι η ALU μπορεί να χρησιμοποιηθεί για το post-increment rs = rs + imm. Μία αποδεκτή
υλοποίηση του νέου pipeline φαίνεται στο παρακάτω σχήμα, όπου χρειαζόμαστε δύο επιπλέον πολυπλέκτες όπως φαίνεται με πράσινο χρώμα. P C 4 PCSrc Add MemWrite Zero ALU Instruction address [3-] register 2 Result Address Instruction memory IF/ID Sign extend register Write register Write data Control Instr [2-6] Instr [5 - ] RegWrite data data 2 Registers ID/EX M EX << 2 ALUSrc RegDst Add rs ALUOp RegDst2 Instr [25-2 EX/MEM M Branch Zero AddrSrc Data memory Write data Mem PCSrc data MEM/ MemToReg b) Στο παρακάτω πίνακα αληθείας φαίνονται οι τιμές των παλαιών και των νέων σημάτων ελέγχου για όλες τις περιπτώσεις εντολών. Εντολή RegWrite RegDst ALUSr Branch MemWrite MemToRe ALUOp PCSrc AddrSrc RegDst2 c g [:] R-format X lw (add) lw X X (add) beq X X (sub) X sw+ X (add) c) Μπορούμε να χρησιμοποιήσουμε τον ήδη υπάρχοντα μηχανισμό επαναπροώθησης (forwarding) από το στάδιο MEM στο στάδιο EX. Δεν απαιτείται καινούργιο hardware: sw+ $t, 8($t) // $t += 8 add $s, $t, $t2 Δεν έχουμε πρόβλημα με νέα stalls που να δημιουργεί ειδικά η εντολή sw+ Ερώτηση Κρίσης (5 μονάδες) Η απλότητα της αρχιτεκτονικής του MIPS κάνει την προσπέλαση των εντολών στο στάδιο IF πολύ εύκολη: κάθε εντολή έχει μήκος 32 bits, και συνεπώς διαβάζοντας τα επόμενα 4 bytes από την μνήμη εντολών (Instruction Memory) μπορούμε να είμαστε σίγουροι ότι θα διαβάσουμε στο pipeline μια ολόκληρη εντολή.
Υπάρχουν αρχιτεκτονικές στις οποίες δεν συμβαίνει αυτό επειδή οι εντολές έχουν διαφορετικό μέγεθος. Για παράδειγμα στην αρχιτεκτονική της Intel x86, οι εντολές μπορούν να έχουν μήκος από μέχρι και 7 bytes. Μπορείτε να σκεφτείτε και να περιγράψετε έναν αποδοτικό τρόπο για να διαβάζονται και να αποκωδικοποιούνται οι εντολές από την μνήμη εντολών στο pipeline σε έναν τέτοιο επεξεργαστή σαν της Intel; Απάντηση: Τα bytes διαβάζονται από την μνήμη εντολών πάντα σε σταθερές ποσότητες σε κάθε κύκλο μηχανής. Για επεξεργαστές σαν τον x86, μπορούμε για παράδειγμα να διαβάζουμε 8 ή 6 ή 32 bytes σε κάθε κύκλο μηχανής και όταν αυτή η ποσότητα διαβαστεί μέσα στην CPU, ο πολύ πιο πολύπλοκος instruction decoder θα σπάει την ποσότητα αυτή σε εντολές x86 σειριακά. Σημειώστε ότι υπάρχει πιθανότητα να χρειαστεί πάνω από ένας κύκλος μηχανής για να διαβαστεί μια εντολή από την μνήμη στην CPU, όταν, για παράδειγμα, μια εντολή επεκτείνεται πέρα από το όριο της ποσότητας που διαβάζεται στον έναν κύκλο μηχανής. Στην περίπτωση αυτή, ο instruction decoder θα αποθηκεύσει το κομμάτι της εντολής που διαβάσαμε στον έναν κύκλο και θα περιμένει τους επόμενους κύκλους για να πάρει το υπόλοιπο κομμάτι της εντολής. Αρχιτεκτονικής Διοχέτευσης πολλαπλών μονοπατιών (5 μονάδες) Θεωρήστε τον ακόλουθο κώδικα MIPS κινητής υποδιαστολής που εκτελείται στον επεξεργαστή του Σχήματος. l.d $f6, 34($s) # FP load double precision l.d $f2, 42($s) mult.d $f, $f2, $f4 sub.d $f8, $f6, $f2 div.d $f, $f, $f6 add.d $f6, $f8, $f2 s.d $f, ($s) Ο επεξεργαστής είναι μια επέκταση της γνωστής μικροαρχιτεκτονικής του MIPS στην οποία προσθέτουμε νέες μονάδες εκτέλεσης για κάποιες εντολές κινητής υποδιαστολής. Εκτός του σταδίου ΕΧ που χρησιμοποιείται για τις εντολές ακεραίων και εντολές load/store, υπάρχουν και δύο διατάξεις για πρόσθεση και πολλαπλασιασμό κινητής υποδιαστολής διπλής ακρίβειας. Οι διατάξεις αυτές είναι οργανωμένες με διοχέτευση έτσι ώστε νέες εντολές πρόσθεσης/πολλαπλασιασμού να μπορούν να ξεκινούν εκτέλεση σε κάθε κύκλο μηχανής. Υπάρχει επίσης και μία διάταξη διαίρεσης κινητής υποδιαστολής διπλής ακρίβειας η οποία έχει χρόνο απόκρισης κύκλων μηχανής και η οποία δεν έχει διοχέτευση. Υπάρχουν μονάδες προώθησης (forwarding) μεταξύ του σταδίου ΜΕΜ και του σταδίου και του πρώτου σταδίου κάθε pipeline. Για παράδειγμα από το ΜΕΜ στα στάδια ΕΧ, Μ, Α και στην είσοδο του διαιρέτη. Η ύπαρξη πολλαπλών μονοπατιών επιτρέπει την εκτέλεση εντολών παράλληλα με άλλες εντολές και πιθανόν την εγγραφή του αρχείου καταχωρητών (register file) εκτός σειράς εντολών εάν δεν υπάρχει εξάρτηση δεδομένων (data dependence). Ή άσκηση σας ζητάει να δώσετε το διάγραμμα χρονισμού για την εκτέλεση του παραπάνω προγράμματος MIPS στον νέο μας επεξεργαστή. Σε ποιόν κύκλο μηχανής τερματίζεται το πρόγραμμα; Για ευκολία χρησιμοποιείστε τον πίνακα που σας δίνεται στο τέλος του φυλλαδίου.
Integer Execution Unit EX FP multiply M M2 M3 M4 M5 M6 IF ID FP adder MEM A A2 A3 A4 FP divider Σχήμα. Ο επεξεργαστής πολλαπλών μονοπατιών. Η τελευταία εντολή (s.d) τερματίζεται στον κύκλο 24. 2 3 4 5 6 7 8 9 2 3 4 5 6 7 8 9 2 3 4 l.d IF ID EX M l.d IF ID EX M mult.d IF ID ID M M2 M3 M4 M5 M6 M sub.d IF IF ID A A2 A3 A4 M div.d IF ID ID ID ID ID D D2 D3 D4 D5 D6 D7 D8 D9 D M add.d IF IF IF IF IF ID A A2 A3 A4 M s.d IF IF IF ID ID ID ID ID ID ID EX M Πρόβλεψη εντολών διακλάδωσης (3*7 = 2 μονάδες) Έστω ο παρακάτω κώδικας C:
int array[] = { /* random values */ }; int sum =, sum2 =, sum3 =, sum4 = ; for (int i = ; i < ; i ++) { // LOOP BRANCH if (i % 4 == ) // IF CONDITION sum += array[i]; // TAKEN PATH else sum2 += array[i]; // NOT-TAKEN PATH } if (i % 2 == ) // IF CONDITION 2 sum3 += array[i]; // TAKEN PATH else sum4 += array[i]; // NOT-TAKEN PATH Η άσκηση σας ζητάει να υπολογίσετε την ακρίβεια της πρόβλεψης των εντολών διακλάδωσης που υπάρχουν στον κώδικα. Οι εντολές διακλάδωσης είναι το LOOP BRANCH (Taken κάθε φορά που επαναλαμβάνεται το loop και Not Taken όταν το loop τερματίζει), και οι δύο εσωτερικές εντολές διακλάδωσης (Taken όταν η συνθήκη if είναι αληθής και Not Taken όταν είναι ψευδής). a) Ποιο είναι το ποσοστό σωστής πρόβλεψης για κάθε μία από τις τρείς διακλαδώσεις όταν χρησιμοποιούμε για πρόβλεψη μία FSM του ενός bit η οποία προβλέπει την διακλάδωση σύμφωνα με την αμέσως προηγούμενη εκτέλεση της; Υποθέστε ότι η αρχική κατάσταση κάθε FSM είναι Not Taken. Loop Branch: Η πρώτη και η τελευταία πρόβλεψη θα είναι λάθος. Οι υπόλοιπες 998 θα είναι σωστές. Άρα ποσοστό σωστών προβλέψεων : 998/ = 99,8% If-condition : Πρόβλεψη ΝΤ Τ ΝΤ ΝΤ ΝΤ Τ ΝΤ ΝΤ ΝΤ Τ ΝΤ ΝΤ Εκτέλεση Τ ΝΤ ΝΤ ΝΤ Τ ΝΤ ΝΤ ΝΤ Τ ΝΤ ΝΤ ΝΤ Σωστές προβλέψεις στο 5% των περιπτώσεων If-condition 2: Πρόβλεψη ΝΤ Τ ΝΤ Τ ΝΤ Τ ΝΤ Τ ΝΤ Τ ΝΤ Τ Εκτέλεση Τ ΝΤ Τ ΝΤ Τ ΝΤ Τ ΝΤ Τ ΝΤ Τ ΝΤ Σωστές προβλέψεις στο % των περιπτώσεων b) Ποιο είναι το ποσοστό σωστής πρόβλεψης για κάθε μία από τις τρείς διακλαδώσεις όταν χρησιμοποιούμε για πρόβλεψη μία FSM των δύο bits; Υποθέστε ότι η αρχική κατάσταση κάθε FSM είναι Strongly Not Taken. Loop Branch: Η πρώτη και η δεύτερη πρόβλεψη θα είναι λάθος (πρόβλεψη Not Taken, εκτέλεση Taken). Επίσης η τελευταία πρόβλεψη θα είναι λάθος (πρόβλεψη Taken, εκτέλεση Not Taken). Οι υπόλοιπες 997 θα είναι σωστές. Άρα ποσοστό σωστών προβλέψεων : 997/ = 99,7%
If-condition : Πρόβλεψη ΝΤ NT NT NT NT NT NT NT NT NT NT NT Εκτέλεση Τ ΝΤ ΝΤ ΝΤ Τ ΝΤ ΝΤ ΝΤ Τ ΝΤ ΝΤ ΝΤ Όλες οι προβλέψεις του predictor είναι Not Taken. Σωστές προβλέψεις στο 75% των περιπτώσεων. If-condition 2: Πρόβλεψη ΝΤ NT NT NT NT NT NT NT NT NT NT NT Εκτέλεση Τ ΝΤ Τ ΝΤ Τ ΝΤ Τ ΝΤ Τ ΝΤ Τ ΝΤ Όλες οι προβλέψεις του predictor είναι Not Taken. Σωστές προβλέψεις στο 5% των περιπτώσεων. c) Ποιο είναι το ποσοστό σωστής πρόβλεψης για κάθε μία από τις τρείς διακλαδώσεις όταν χρησιμοποιούμε για πρόβλεψη πάλι μία FSM των δύο bits όπου τώρα η αρχική κατάσταση κάθε FSM είναι Weakly Taken; Loop Branch: Μόνο η τελευταία πρόβλεψη θα είναι λάθος (πρόβλεψη Taken, εκτέλεση Not Taken). Οι υπόλοιπες 999 θα είναι σωστές. Άρα ποσοστό σωστών προβλέψεων : 999/ = 99,9% If-condition : Πρόβλεψη Τ Τ Τ ΝΤ ΝΤ ΝΤ ΝΤ ΝΤ ΝΤ ΝΤ ΝΤ ΝΤ Εκτέλεση Τ ΝΤ ΝΤ ΝΤ Τ ΝΤ ΝΤ ΝΤ Τ ΝΤ ΝΤ ΝΤ Οι 4 πρώτες προβλέψεις έχουν 2 αστοχίες. Από εκεί και πέρα έχουμε 3 σωστές προβλέψεις στις 4 διακλαδώσεις. Άρα 2 +,75*(-4) = 749 σωστές προβλέψεις με ποσοστό 74,9%. If-condition 2: Πρόβλεψη Τ Τ Τ Τ Τ Τ Τ Τ Τ Τ Τ Τ Εκτέλεση Τ ΝΤ Τ ΝΤ Τ ΝΤ Τ ΝΤ Τ ΝΤ Τ ΝΤ Όλες οι προβλέψεις του predictor είναι Taken. Σωστές προβλέψεις στο 5% των περιπτώσεων. Απόδοση Συστήματος (9 μονάδες) Έστω ο παρακάτω κώδικας C ο οποίος εκτελείται για διαφορετικές τιμές του ακεραίου X τις οποίες δίνει ο χρήστης. const unsigned int N = <<3; // N is a large number int data[n] = { /* random values in range [, 23] */ }; long long sum = ; int X; read (X);
for (int i = ; i < N; i ++) { if (data[i] < X) sum += data[i]; else sum -= data[i] } Μπορείτε να συγκρίνετε τον χρόνο εκτέλεσης του προγράμματος αυτού για δύο διαφορετικές τιμές του Χ: X = 52 και X = 5; Θα πρέπει να εξηγήσετε εάν η εκτέλεση του προγράμματος διαφέρει για τα δύο αυτά τρεξίματα, και εάν, ναι, γιατί να δώσετε επιχειρήματα γιατί συμβαίνει αυτό. Απλή απάντηση ΝΑΙ/OXI χωρίς άλλη εξήγηση θα μηδενίζεται. Λύση Η άσκηση αυτή είναι όμοια με την άσκηση που κάναμε στην τάξη. Το Χ=52 είναι ακριβώς στην μέση του διαστήματος [, 23] των τιμών που παίρνει ο πίνακας data[], και συνεπώς θα υπάρχει ίση πιθανότητα για την εντολή if να είναι Taken ή Not Taken. Επειδή οι τιμές που αποθηκεύονται στον πίνακα data[] είναι τυχαίες στο διάστημα [, 23], o branch predictor δεν μπορεί να βασιστεί στην προηγούμενη συμπεριφορά του branch για να προβλέψει την μελλοντική συμπεριφορά και έχει ίσες πιθανότητες να μαντέψει Taken και Not Taken. Το branch misprediction θα είναι 5%. Αυτό το γεγονός θα δημιουργεί έναν πολύ μεγάλο αριθμό από χρονοβόρα pipeline flushes που κάθε ένα μπορεί και να στοιχίζει 5-2 κύκλους μηχανής ανάλογα με τον επεξεργαστή που τρέχει τον κώδικα μας. Όταν το X = 5, το branch θa εκτελεί συνήθως το else-statement της εντολής if και ο branch predictor θα δίνει συνήθως αυτήν την πρόβλεψη που θα είναι και ή σωστή. Άρα ο αριθμός των flushes θα είναι πολύ μικρότερος και συνεπώς και ο χρόνος εκτέλεσης του προγράμματος θα είναι μικρότερος για X=5.