ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΙΑΣ ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΗΛΕΚΤΡΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΚΑΙ ΜΗΧΑΝΙΚΩΝ Η/Υ ΤΕΛΙΚΟ ΔΙΑΓΩΝΙΣΜΑ ΣΤΗΝ ΟΡΓΑΝΩΣΗ ΣΤΟΥΣ Η/Y (ΗΥ232) Τετάρτη, 21 Δεκεμβρίου 2016 ΔΙΑΡΚΕΙΑ ΔΙΑΓΩΝΙΣΜΑΤΟΣ 3 ΩΡΕΣ Για πλήρη βαθμό θα πρέπει να δείξετε καθαρά την δουλειά σας! ΘΕΜΑ 1. ΙΕΡΑΡΧΙΑ ΜΝΗΜΗΣ (5*8 = 40 μονάδες) H ερώτηση αυτή αναφέρεται στην απόδοση της μνήμης cache για τον παρακάτω κώδικα C ο οποίος μεταθέτει (transpose) έναν τετραγωνικό πίνακα A και τον γράφει σε έναν πίνακα Β. #define N 1024 int A[N*N], B[N*N]; int i,j; // Integers are 4 bytes for (i = 0; i < N; i++) for (j = 0; j < N; j++) B[j*N+i] = A[i*N+j]; Οι δύο πίνακες A και B είναι ευθυγραμμισμένοι σε διευθύνσεις των 4KB και αποθηκεύονται στην μνήμη ο ένας μετά τον άλλον. a) Απόδοση cache. Έστω μία 8 KB, 2-way set associative cache, με cache block 32 bytes που ακολουθεί πολιτική LRU για αντικατάσταση blocks. Ποιό είναι το miss rate για τα stores όταν εκτελείται ο κώδικας; Ποιό είναι το miss rate για τα loads; Σκεφτείτε εαν υπάρχει κάποια σύγκρουση (conflict) μεταξύ των πινάκων A και B σε κάποια sets. Προσέξτε την εναλλαγή των προσπελάσεων στον κώδικα: Load A, Store B, Load A, Store B, κλπ. Έχουμε 8 ΚΒ / 32 = 256 blocks ή 256/2 = 128 = 2 7 sets στην cache. Tag Set index = 7 bits Offset = 5 bits To πρώτο load Α αποθηκεύεται στο set 0, block 0. Το πρώτο store B αποθηκεύεται στο set 0, block 1 (έχουμε 2-ways). To δεύτερο load Α πέφτει στο set 0 και είναι Hit. Το δεύτερο store B πέφτει στο set 0 και είναι Miss. Επειδή το πρώτο B είναι το LRU, αυτό θα αντικατασταθεί. To τρίτο load Α πέφτει στο set 0 και είναι πάλι Hit. Το τρίτο store B πέφτει στο set 0 και είναι Miss. Επειδή το δεύτερο B είναι το LRU στο set 0, αυτό θα αντικατασταθεί. Και πάει λέγοντας. Προσέξτε ότι το 2-way associativity και το LRU μας εξασφαλίζουν ότι τα στοιχεία του Β διώχνουν τον εαυτό τους σε κάθε διαδοχικό store. Τα στοιχεία του Α αντιθέτως δεν τα έρχονται σε σύγκρουση (conflict) με τα στοιχεία του Β. Κάθε cache block χωράει 32/4 = 8 ακεραίους. Τα loads γίνονται row-wise και έχουμε πλήρη εκμετάλλευση της χωρικής τοπικότητας. Κάθε 1 load miss ακολουθείται από 7 load hits. Άρα το load miss rate είναι 1/8 = 12,5% Τα stores έχουν stride 4*N που είναι 4096 = 4 ΚΒ (0, 4096, 8192,...). Η πρώτη στήλη είναι 100% write miss (cold misses). Η δεύτερη στήλη θα είναι επίσης 100% write misses (capacity misses) επειδή η cache είναι πολύ μικρή για να μπορέσει να κρατήσει τα αρχικά cache blocks. To write miss rate θα είναι 100% για αυτόν τον κώδικα.
b) Πολιτική αντικατάστασης blocks. Ποιές αλλάγες θα υπάρξουν στο load miss rate εαν αντι για LRU έχουμε πολιτική αντικατάστασης FIFO; Εδώ τα πράγματα είναι λίγο διαφορετικά λόγω του αλγόριθμου FIFO. To πρώτο load Α πέφτει στο set 0, block 0. Το πρώτο store B πέφτει στο set 0, block 1 (έχουμε 2-ways). To δευτερο load Α πέφτει στο set 0 και είναι Hit. Το δεύτερο store B πέφτει πάλι στο set 0 και είναι Miss. Θα διώξει όμως το Α επειδή το Α είναι το πρώτο που μπήκε στο set 0 (FIFO protocol). To τρίτο load Α πέφτει πάλι στο set 0 και είναι Miss. Θα διώξει το πρώτο Β. Το τρίτο store B πέφτει στο set 0 και είναι Miss. Θα διώξει το δεύτερο Β. Τα πρώτα 8 loads του A θα έχουν 4 hits και 4 misses. Τα επόμενα 8 loads πέφτουν πάνω στο set 1 της cache και συνεπώς δεν έχουν conflict με τα stores του Β που συνεχίζουν να πέφτουν στο set 0. H πρώτη γραμμή του πίνακα που γεμίζει 1024/8 = 128 cache blocks θα έχει 3 επιπλέον misses σε σχέση με το ερώτημα (α). Συνολικά θα έχουμε 128+3 load misses στην πρώτη γραμμή. Στην δεύτερη γραμμή (δεύτερη στήλη για τον Β) θα έχουμε ακριβώς το ίδιο σενάριο. Στην πραγματικότητα, το ίδιο ακριβώς σενάριο θα έχουμε για τις πρώτες 8 γραμμές (131 misses σε 1024 reads). Η μόνη διαφορά από εκεί και πέρα είναι ότι το conflicting set είναι το set 1 (οι γραμμές, 8-15), το σετ 2 (γραμμές 16-23) κοκ. Συνολικά λοιπόν για το FIFO protocols: Load Miss Rate = 131/1024 = 12,8% c) Εαν οι παράμετροι της μνήμης cache είναι όπως στο ερώτημα (α), ποιοί από τους επόμενους συνδιασμούς θα είναι οι καλύτεροι όσον αφορά την εκτέλεση του κώδικα. Επιλέξτε καθαρά μία ή περισσότερες απάντησεις και δικαιολογήστε την. Υπενθυμίζουμε ότι μία cache είναι Write-Allocate όταν σε ένα Write Miss, το αντίστοιχο block προσκομίζεται από την μνήμη, γράφεται στην cache, και μετά η CPU γράφει σε αυτό το block στην cache. Mία cache είναι No Write-Allocate όταν σε ένα Write Miss τα δεδομένα γράφονται μόνο στην μνήμη προσπερνώντας την cache. i. Write-Allocate, Write-Back ii. Write-Allocate, Write-Through iii. No Write-Allocate, Write-Back iv. No Write-Allocate, Write-Through Μας ενδιαφέρει η συμπεριφορά της ιεραρχίας μνήμης σε περίπτωση writes. Όπως είδαμε στην ερώτηση (α), έχουμε 100% write miss rate. Write Allocate Write Back, Write Allocate Write Through Το Write Allocate προτόκολλο γενικά δεν είναι καλό για αυτόν τον κώδικα. Όλα τα write misses στην L1 Cache μεταφέρουν ένα 32-byte block από την κύρια μνήμη στην L1 Cache το οποίο δεν πρόκειται να χρησιμοποιηθεί ξανά (δεν υπάρχει locality). Στην περίπτωση μάλιστα Write Allocate Write Back, θα διώξουμε πάλι το block πίσω στην κύρια μνήμη (block eject), με συνολικό κόστος 32+32 = 64 bytes. Η έλλειψη locality κάνει το No Write Allocate καλύτερη επιλογή. Σε κάθε write miss, απλά στέλνουμε τα 4 bytes του B[i][j] στην κύρια μνήμη προσπερνώντας την cache. Επειδή δεν υπάρχει ποτέ Write Hit, δεν έχει σημασία εαν η cache θα είναι Write Back ή Write Through. d) Απόδοση Μετάφρασης Διεύθυνσης. Έστω ότι ο κώδικας εκτελείται σε ένα σύστημα εικονικής μνήμης. Εστω ότι το μέγεθος των σελίδων είναι 4 KB και η TLB μνήμη είναι άμεσης απεικόνισης (direct-mapped) και έχει 1024 εισόδους (entries). Πόσα TLB misses συμβαίνουν όταν εκτελεσθεί ο κώδικας; Κάθε γραμμή καταλαμβάνει μία σελίδα (4*1024 = 4 KB). To πρώτο load Α δημιουργεί ένα TLB miss και γεμίζει το entry TLB[0]. To επόμενο store Β δημιουργεί ένα TLB miss και γεμίζει το entry TLB[0] διώχνοντας τον pointer στην σελίδα Α[0]. Το δεύτερο load A είναι πάλι miss στο TLB[0] διώχνοντας τον pointer του B. To δεύτερο store Β δημιουργεί πάλι ένα miss, στην TLB[1] αυτήν την φορά. Στο πρώτο outer iteration (i=0), θα έχουμε 2 load misses απο το A και 1024 store misses από το B. Συνολικά 2+1024.
To γενικό pattern για το outer loop iteration i (γραμμή i και στήλη i) είναι ως εξής: ο πινακας A δημιουργεί 2 TLB misses (το πρώτο όταν j=0, και το δεύτερο επειδή ο B θα το κάνει προς στιγμή eject απο το TLB) ενώ ο Β έχει επίσης 2 misses στο TLB (για j = i-1 και j=i). Επειδή το i παίρνει τις τιμές 1 μέχρι και 1023, θα έχουμε 1023*(2+2) = 4*1023 misses για i>0. Συνολικά λοιπόν θα έχουμε 2+1024+4*1023 = 5118 TLB misses. e) Σας δίδεται η δυνατότητα να βελτιώσετε τον χρόνο εκτέλεσης του παραπάνω προγράμματος με το να αλλάξετε κάποια χαρακτηριστικά της ιεραρχίας μνήμης σε σχέση με το ερώτημα (α). Θα πρέπει να επιλέξετε από την παρακάτω λίστα, ποια είναι τα πιο σημαντικά χαρακτηριστικά τα οποία, εφόσον αυξηθούν, θα βελτιώσουν σημαντικά (και όχι μόνο οριακά ή καθόλου) την απόδοση του συγκεκριμένου κώδικα. Θα πρέπει να κυκλώσετε και να εξηγήσετε την απάντηση σας. Κάθε λανθασμένη απάντηση θα έχει αρνητική βαθμολογία -0,5 μονάδες στις 100. Κάθε σωστή απάντηση που δεν εξηγείται επαρκώς θα παίρνει 0 μονάδες. i. DATA CACHE SIZE (Σημαντικό Μη Σημαντικό) Σημαντικό για να αυξήσουμε το Hit Rate του πίνακα B. Εαν το μέγεθος της cache είναι πάρα πολύ μεγάλο, το store miss rate πέφτει σχεδόν στο 1/8 (θα έχουμε μόνο cold misses). Το load miss rate από τον πίνακα A είναι ανεξάρτητο από το μέγεθος της cache. ii. iii. iv. DATA CACHE BLOCK SIZE (Σημαντικό Μη Σημαντικό) Σημαντικό για την μείωση των load misses από τοn πίνακα A. DATA TLB SIZE (Σημαντικό Μη Σημαντικό) Ασήμαντο αφου το TLB miss rate είναι πολύ μικρό έτσι και αλλιώς και οφείλεται σε compulsory misses και σε conflict misses μόνο. PHYSICAL PAGES PREFETCHES (Σημαντικό Μη Σημαντικό) Σημαντικό λόγω της μείωσης της πιθανότητας σφάλματος σελίδας. v. MAIN MEMORY ROW BUFFER SIZE (Σημαντικό Μη Σημαντικό) Σημαντικό για μείωση του χρόνου προσπέλασης της κύριας μνήμης, ιδίως λόγω του ότι τα δεδομένα του πίνακα Α διαβάζονται ανά γραμμή και υπάρχει μεγάλη χωρική τοπικότητα. ΘΕΜΑ 2. ΑΠΟΔΟΣΗ ΜΝΗΜΗΣ (20 μονάδες) Έστω ένα σύστημα ιεραρχίας μνήμης Α με τρία επίπεδα μνήμης cache. Έστω ότι χρειάζομαστε 1 κύκλο μηχανής για να προσπελάσουμε την L1-Cache, 10 κύκλους στην συνέχεια για την L2, και 30 κύκλους στην συνέχεια για την L3. Έστω ότι χρειαζόμαστε 100 κύκλους μηχανής για την προσπέλαση της κύριας μνήμης από την L3-Cache. Η L1 Cache έχει Hit Rate 90%, η L2 Cache έχει Global Miss Rate 5%, και η L3 Cache έχει Local Miss Rate 60%. Χρησιμοποιώντας γνωστές τεχνικές όπως μεγαλύτερη συσχετιστικότητα (associativity), οι σχεδιαστές του συστήματος Α προσπάθησαν και κατάφεραν να βελτιώσουν το L1 Cache Hit rate se 95%, το L2 Global Miss Rate στο 4%, και το L3 Cache Local Miss Rate στο 50%. Δυστυχώς το νέο σύστημα ιεραρχίας μνήμης Β έχει αυξημένο χρόνο προσπέλασης κάθε επιπέδου μνήμης (L1, L2, L3, κύρια μνήμη) κατά 10% σε σχέση με το σύστημα Α. Η άσκηση αυτή σας ζητάει να δείξετε ποσοτικά ποιό από τα δύο συστήματα μνήμης είναι καλύτερο. Θεωρείστε ότι o επεξεργαστής μας παράγει φυσικές διευθύνσεις. Λύση Για να βρούμε ποιό σύστημα Α ή Β είναι το καλύτερο, αρκεί να βρούμε το ΑΜΑΤ κάθε συστήματος. ΑΜΑΤ = Hit Time (L1) + Miss Rate (L1) * Miss Penalty (L1->L2) + Miss Rate (L1) * Local Miss Rate (L2) * Miss Penalty (L2->L3) +
Miss Rate (L1) * Local Miss Rate (L2) * Local Miss Rate (L3) * Miss Penalty (L3->Memory) = Hit Time (L1) + Miss Rate (L1) * Miss Penalty (L1->L2) + Global Miss Rate (L2) * Miss Penalty (L2->L3) + Global Miss Rate (L2) * Local Miss Rate (L3) * Miss Penalty (L3->Memory). Συνεπώς: ΑΜΑΤ A = 1 + 0,1*10 + 0,05*30 + 0,05*0,6*100 = 6,5 ΑΜΑΤ B = 1*1,1 + 0,05*(10*1,1) + 0,04*(30*1,1) + 0,04*0,5*(100*1,1) = 5,17 Άρα το σύστημα Β είναι καλύτερο από το σύστημα Α γιατί είναι 6,5/5,17 = 1,257 φορές γρηγορότερο κατα μέσο όρο. ΘΕΜΑ 3. ΔΙΑΚΛΑΔΩΣΕΙΣ (20 μονάδες) Σε ένα σύγχρονο επεξεργαστή υψηλής απόδοσης με πολλά στάδια διοχέτευσης (super-pipelined), υπάρχει πρόβλεψη (prediction) για όλες τις εντολές που είναι δυνατόν να αλλάξουν την ροή του προγράμματος. Αυτοί οι μηχανισμοί ενεργοποιούνται στα πρώτα στάδια διοχέτευσης. Η άσκηση αυτή σας ζητάει να προτείνετε κάποιον hardware μηχανισμό πρόβλεψης για την εντολή jr $ra του MIPS. Υπενθυμίζω ότι η εντολή αυτή χρησιμοποιείται στον MIPS για επιστροφή (return) από μία υπορουτίνα. Τονίζω ότι ζητάμε την πρόβλεψη συγκεκριμένα για την jr $ra και όχι γενικά για την εντολή jr rs για έναν οποιοδήποτε καταχωρητή rs. Λύση Μιλώντας γενικά, η πρόβλεψη μιάς εντολής διακλάδωσης απαιτεί πρόβλεψη (a) για την κατεύθυνση (Taken, Not Taken) και (b) για την διεύθυνση προορισμού (Target Address). Στην συγκεκριμένη περίπτωση η μόνη πρόβλεψη που απαιτείται είναι η πρόβλεψη για την διεύθυνση προορισμού, αφού η εντολή jr είναι πάντα Taken. Εδω θα πρέπει να βασιστούμε στο ότι η εντολή είναι ουσιαστικά επιστροφή (return) από μία υπορουτίνα func και ότι για κάθε εντολή jr $ra, θα υπάρχει και η αντίστοιχη εντολή jal func. jal f1 jal f2 jal f3 jr $ra // return from f3 jr $ra // return from f2 jr $ra // return from f1 Ένα πολύ ακριβές σύστημα πρόβλεψης είναι να χρησιμοποιήσουμε μιά μνήμη στοίβας (stack) για να αποθηκεύουμε την διεύθυνση επιστροφής. Αυτή είναι η διεύθυνση που αποθηκεύθηκε στον $ra όταν εκτελέσθηκε η εντολή jal. Το σύστημα πρόβλεψης θα δουλεύει ως εξής στο παρακάτω παράδειγμα: όταν εκτελεσθεί μία εντολή jal 0x1000: jal foo 0x1004: add... foo:
0x6000: jr $ra // return from foo η τιμή του PC+4 (δηλ. το 0x1004) θα αποθηκευθεί στην στοίβα πρόβλεψης. Όταν ο PC πάρει την διεύθυνση 0x6000 (δηλ. πάμε να προσπελάσουμε την jr $ra για να επιστρέψουμε από την συνάρτηση foo), θα έχουμε match στo BTB (όπου μπορούμε να τοποθετούμε και τις εντολές jr $ra), θα αναγνωρίσουμε ότι υπάρχει μία εντολή $jr ra στην διεύθυνση 0x6000 και ότι θα πρέπει να προσπελάσουμε την στοίβα. Πραγματικά, προσπελαύνουμε το TOP element της στοίβας (που περιέχει την διεύθυνση 0x1004) και το χρησιμοποιούμε για να προσπελάσουμε την επόμενη εντολή (την εντολή add). Με αυτόν τον τρόπο μπορούμε να έχουμε 100% επιτυχία προβλέψεων. ΘΕΜΑ 4. ΚΩΔΙΚΟΠΟΙΗΣΗ ΔΙΕΥΘΥΝΣΕΩΝ (20 μονάδες) Έστω ότι κάποιος σχεδιαστής ενός συστήματος ιεραρχίας μνήμης επέλεγε το παρακάτω σχήμα για τα πεδία της φυσικής μνήμης των n bits: Φυσική Μνήμη Address Tag: (n-m-b) bits Block Offset : b bits Index: m bits. Προσέξτε ότι η θέση των πεδίων Block Offset και Index έχουν αναστραφεί σε σχέση με ότι γνωρίζουμε. Πιστεύεται ότι αυτό το σχήμα θα δουλέψει σωστά και, εφόσον το πιστεύετε, ποια νομίζετε ότι είναι τα πλεονεκτήματα και τα μειονεκτήματα σε σχέση με το γνωστό μας configuration; Εξηγήστε λεπτομερώς την απάντηση σας. Θα δουλέψει σωστά, αλλά πάσχει από έλλειψη spatial locality για προσπελάσεις που είναι η μία δίπλα στην άλλη. Εαν, για παράδειγμα, έχουμε n=8, m=4, b=2, Tag=2 τότε διαβάζοντας σειριακά έναν πίνακα, οι διευθύνσεις 0, 1, 2, 3, 4,... θα είναι ως εξής: 00 00 0000 00 00 0001 00 00 0010 00 00 0011 Τα 4 τελευταία bits είναι το index. Διαδοχικές διευθύνσεις προσπευλάνουν διαφορετικά sets και δεν εκμεταλλεύονται καθόλου την χωρική τοπικότητα (spatial locality) μέσα σε ένα cache block.