ΕΘΝΙΚΟ ΚΑΙ ΚΑΠΟ ΙΣΤΡΙΑΚΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΑΘΗΝΩΝ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ ΚΑΙ ΤΗΛΕΠΙΚΟΙΝΩΝΙΩΝ ΠΡΟΓΡΑΜΜΑ ΜΕΤΑΠΤΥΧΙΑΚΩΝ ΣΠΟΥ ΩΝ (3 η Κατεύθυνση) ΠΡΟΗΓΜΕΝΗ ΑΡΧΙΤΕΚΤΟΝΙΚΗ ΥΠΟΛΟΓΙΣΤΩΝ ιδάσκων : Καθηγητής Κ. Χαλάτσης Vector Processing Χρήστος Τσόλκας (Μ-499) grad0499@di.uoa.gr Χρυσόστοµος Αντωνίου (Μ-547) grad0547@di.uoa.gr
Περιεχόµενα 1. Ταξινόµηση υπολογιστών 2 2. Εναλλακτικοί τρόποι παραλληλοποίησης 3 3. Vector υπολογιστές 4 3.1. Η προσέγγιση των εικονικών επεξεργαστών 6 4. Πλεονεκτήµατα-µειονεκτήµατα των vector υπολογιστών 7 5. Vector καταχωρητές και λογικές µονάδες 8 6. Αρχιτεκτονικές Vector Memory-Memory και Vector-Register 9 7. Εκτέλεση vector εντολών 10 7.1. Vector εκτέλεση vs scalar εκτέλεση εντολών 11 8. Παράγοντες που αποτρέπουν το vectorization 12 9. Αύξηση της ταχύτητας 14 10. Εφαρµογές 15 Πηγές 17 1
1 Ταξινόµηση υπολογιστών Υπάρχουν πολλοί δυνατοί τρόποι να περιγράψουµε υπολογιστικά συστήµατα. Κατά καιρούς έχουν προταθεί πολυάριθµες κατηγοριοποιήσεις, ανάλογα µε τα χαρακτηριστικά στα οποία κάθε φορά δίδεται έµφαση. Η πιο συνήθης από όλες είναι η ταξινόµηση κατά Flynn. Η τελευταία χωρίζει τις µηχανές ανάλογα µε: 1. Τον αριθµό των δεσµών εντολών (instruction streams) που υπάρχουν 2. Τον αριθµό των δεσµών δεδοµένων (data streams) Με τον όρο «δέσµη εντολών» εννοούµε τα διακριτά και ανεξάρτητα µονοπάτια ελέγχου και κατάστασης. Αυτό σηµαίνει ότι κάθε δέσµη εντολών έχει τον δικό της µετρητή προγράµµατος και τους δικούς της καταχωρητές. Με τον όρο δέσµη δεδοµένων εννοούµε τα ανεξάρτητα τµήµατα δεδοµένων. Ένας πίνακας που περιέχει δεδοµένα µπορεί να αντιµετωπιστεί ως µια σειρά από πολλές και ξεχωριστές δέσµες δεδοµένων. Τόσο οι εντολές (instructions Ι) όσο και τα δεδοµένα (data D) µπορούν να χαρακτηριστούν ως µονά (single S) ή πολλαπλά (multiple M). Συνεπώς προκύπτουν τέσσερις δυνατοί συνδυασµοί: Ροή δεδοµένων (Data Ροή εντολών (Instruction Streams) Streams) Μονή (Single) Πολλαπλή (Multiple) Μονή (Single) SISD SIMD Πολλαπλή (Multiple) MISD MIMD o SISD: Μια και µόνο ροή εντολών εκτελείται χρησιµοποιώντας µόνο µια ροή δεδοµένων. Σε αυτήν την περίπτωση ανήκουν παραδοσιακοί CISC επεξεργαστές τύπου ΕΕ151, pipelined και superscalar επεξεργαστές. o SIMD: Μια και µόνο ροή εντολών εκτελείται χρησιµοποιώντας πολλαπλές ροές δεδοµένων παράλληλα. Χαρακτηριστικές υλοποιήσεις αυτής της κατηγορίας είναι οι vector αρχιτεκτονικές. o MISD: Πολλές ανεξάρτητες ροές εντολών εκτελούνται παράλληλα χρησιµοποιώντας µία κοινή ροή δεδοµένων. εν υπάρχουν αξιόλογες αρχιτεκτονικές βασισµένες σε αυτό το συνδυασµό. o MIMD: Πολλές ανεξάρτητες ροές εντολών εκτελούνται παράλληλα χρησιµοποιώντας η κάθε µια την αντίστοιχή της ροή δεδοµένων. Χαρακτηριστικά παράδειγµα αυτής της κατηγορίας είναι οι παράλληλοι υπολογιστές (που χρησιµοποιούνται λόγου χάρη στη µοντελοποίηση του κλίµατος της γης). Εξίσου γνωστή υλοποίηση αυτής της αρχιτεκτονικής είναι υπολογιστές που έχουν δύο Pentium επεξεργαστές στην ίδια µητρική. Εδώ πρέπει να τονιστεί ότι η ροές δεδοµένων είναι γνωστές στον προγραµµατιστή. Κάποιος που γράφει ένα πρόγραµµα για µια µηχανή MIMD πρέπει να συντάξει περισσότερα από ένα νήµατα εκτέλεσης (ροή εντολών) και να εξασφαλίσει ότι ο χειρισµός των δεδοµένων γίνεται σωστά. Σε έναν superscalar επεξεργαστή πολλαπλές εντολές µπορούν να εκτελεστούν ταυτόχρονα σε 2
διαφορετικά block δεδοµένων χωρίς όµως ο προγραµµατιστής να έχει τη δυνατότητα να επέµβει. Το ενδιαφέρον της κατηγοριοποιήσεως των υπολογιστικών συστηµάτων έγκειται στο ότι µε αυτόν τον τρόπο γίνονται πιο κατανοητές οι δυνατότητες και οι περιορισµοί της κάθε αρχιτεκτονικής. Η ταξινόµηση του Flynn είναι από τις πιο γνωστές και χρησιµοποιείται πιο πολύ από όλες τις υπόλοιπες κατηγοριοποιήσεις. Ο λόγος είναι ότι είναι πολύ απλή. υστυχώς όµως είναι χονδροειδής και αυτό έχει ως αποτέλεσµα τον εµπλουτισµό της κατά καιρούς ώστε να καλύπτει τις τελευταίες τεχνολογικές εξελίξεις. 2 Εναλλακτικοί τρόποι παραλληλοποίησης Αρχιτέκτονες υπολογιστών έχουν υλοποιήσει αρκετές µορφές παραλληλισµού µε σκοπό να πετύχουν µεγαλύτερη αύξηση στην απόδοση από αυτήν που έχει επιτευχθεί µε τις βελτιώσεις στα ηλεκτρονικά κυκλώµατα. Το pipelining ήταν η πρώτη και πιο απλή µορφή παραλληλισµού. Σήµερα χρησιµοποιείται σε όλα τα υπολογιστικά συστήµατα. Πέρα από το pipelining υπάρχουν και άλλα σχήµατα που µπορούν να πετύχουν παραλληλισµό αυξάνοντας τη συνολική απόδοση. Αυτά µπορούν να χωριστούν σε τρεις κατηγορίες: o Instruction Level Parallelism (ILP): Εδώ εκτελούνται ταυτόχρονα περισσότερες από µια εντολές µιας ροής εντολών (instruction stream). Superscalar υπολογιστές έχουν τη δυνατότητα παραλληλισµού εντολών (ILP) από µια scalar δέσµη εντολών. o Thread Level Parallelism (TLP): Στην περίπτωση αυτή εκτελούνται ταυτόχρονα πολλά νήµατα εντολών. Μηχανές µε πολλούς επεξεργαστές εκµεταλλεύονται την τεχνική TLP αναθέτοντας ανεξάρτητα νήµατα εντολών σε ξεχωριστούς επεξεργαστές. o Vector Data Parallelism (DP): Η ίδια λειτουργία πραγµατοποιείται σε µια σειρά από στοιχεία. Vector µηχανές εκµεταλλεύονται την παραλληλοποίηση δεδοµένων (DP) πραγµατοποιώντας πολλές οµοιογενείς λειτουργίες σε ένα διάνυσµα στα πλαίσια µιας vector εντολής την ίδια χρονική στιγµή. Αυτές οι µορφές παραλληλίας δεν αποκλείουν η µια την άλλη. Αυτό σηµαίνει ότι µια µηχανή µπορεί να ενσωµατώσει και τις τρεις τεχνολογίες έτσι ώστε να επιτύχει την µέγιστη δυνατή αύξηση ταχύτητας. Για παράδειγµα ο NEC SX-4 vector υπερυπολογιστής έχει pipelined superscalar vector multiprocessor αρχιτεκτονική αξιοποιώντας όλες τις προαναφερθείσες µορφές παραλληλοποίησης. Η λιγότερο ευέλικτη από όλες είναι η DP. Κάθε παραλληλοποίση που επιτυγχάνεται µε την τελευταία µπορεί να υλοποιηθεί µε τις ILP και TLP. Για παράδειγµα ένας superscalar υπολογιστής µπορεί να εκτελέσει DP λειτουργίες προγραµµατίζοντας πολλές ανεξάρτητες εντολές να εκτελούνται παράλληλα, ενώ µια µηχανή µε πολλούς επεξεργαστές µπορεί να αναθέσει σε αυτούς τις ίδιες εντολές σε µια σειρά από δεδοµένα. Ακριβώς όµως αυτή η δυσκινησία είναι που προσδίδει στην DP το χαρακτηριστικό της απλότητας και την αναδεικνύει ως την πιο φθηνή στην υλοποίηση. Μια data parallel µηχανή χρειάζεται να φέρει στον πυρήνα και να αποκωδικοποιήσει µία και µοναδική εντολή για να περιγράψει µια ολόκληρη 3
ακολουθία από παράλληλες εντολές. Αυτό ελαττώνει την πολυπλοκότητα υλοποίησης. Σχήµα 1 Οι τρεις µορφές παραλληλοποίησης Ένα ακόµη πλεονέκτηµα της DP τεχνικής είναι ότι η απόδοσή της αυξάνεται όσο επεκτείνεται η παραλληλοποίηση. Στην τεχνική ILP η πιθανότητα αλληλεξάρτησης των εντολών αυξάνεται δραµατικά όταν µεγαλώνει ο αριθµός των εντολών που εκτελούνται παράλληλα, πράγµα που θέτει έναν µεγάλο περιορισµό στην αύξηση της απόδοσης κατά την εκτέλεση περισσότερων εντολών παράλληλα. Όµοια στην τεχνική TLP το overhead για το συγχρονισµό και επικοινωνία των εντολών µεταξύ διαφορετικών νηµάτων αυξάνεται δραµατικά καθιστώντας ασύµφορη µια τέτοια προσέγγιση. Για αυτό το λόγο οι vector µηχανές έχουν καλύτερη απόδοση σε παράλληλους κώδικες από τις ILP και TLP. 3 Vector υπολογιστές Οι pipelined και οι superscalar υπολογιστές ονοµάζονται και µονοεπεξεργαστικά (uniprocessor) συστήµατα. Αυτό σηµαίνει ότι οι υπολογιστές αυτοί έχουν µόνο µία ροή εντολών. Με άλλα λόγια διαθέτουν µόνο έναν µετρητή προγράµµατος. Στους Vector υπολογιστές υπάρχει ένας και µοναδικός program counter, οι τυπικοί καταχωρητές, οι λογικές µονάδες (functional units) κοκ. Η διαφορά τους από τους κοινούς SISD υπολογιστές έγκειται στο ότι µια vector µηχανή διαθέτει επιπρόσθετα vector καταχωρητές, vector λογικές µονάδες και vector εντολές που διαχειρίζονται vector δεδοµένα. Μια τυπική µορφή ενός τέτοιου επεξεργαστή δίδεται στο σχήµα 2. 4
Σχήµα 2 Θεωρητική µορφή ενός scalar και ενός vector επεξεργαστή Ένας vector καταχωρητής µπορεί να θεωρηθεί ως µια σειρά από µικρότερους scalar καταχωρητές. Ο καθένας από αυτούς περιέχει έναν αριθµό, κατά κανόνα κινητής υποδιαστολής (floating point). Αυτό συµβαίνει διότι οι vector υπολογισµοί είναι συνήθεις σε επιστηµονικές εφαρµογές στις οποίες γίνεται µοντελοποίηση ενός προβλήµατος, ή σε µαθηµατικούς υπολογισµούς όπου έχουµε συνεχείς µεταβλητές και συναρτήσεις. Σε αυτές τις περιπτώσεις χρησιµοποιούνται υψηλής διαµεταγωγής (throughput) vector λογικές µονάδες για να παραχθούν δεδοµένα από vector καταχωρητές µε µεγάλη ταχύτητα. Για να επιτευχθεί αυτό πρέπει να δοθούν εξειδικευµένες vector εντολές. Μια τέτοια εντολή µπορεί να είναι r r r A = B + C r r v όπου A, B, C είναι διανύσµατα και + είναι η πράξη της διανυσµατικής πρόσθεσης. Σε µια κοινή µηχανή για να παραχθεί το ίδιο αποτέλεσµα θα πρέπει να εκτελεστεί ένας βρόχος που να υπολογίζει το άθροισµα των στοιχείων των δύο πινάκων. Σε µια vector µηχανή ο βρόχος αυτός εκφυλίζεται σε µία και µόνο εντολή: VOP V dest V arg1 V arg2 Όπου VOP µια vector λειτουργία. (όπως για παράδειγµα πρόσθεση, αφαίρεση, πολλαπλασιασµός κλπ) και V dest,v arg1,v arg2 οι vector καταχωρητές (παραδείγµατα vector εντολών φαίνονται στο σχήµα 3). 5
Σχήµα 3 Πρόσθεση και φόρτωση σε έναν vector επεξεργαστή 3.1 Η προσέγγιση των εικονικών επεξεργαστών Παράλληλα µε την παραδοσιακή προσέγγιση ενός vector επεξεργαστή είναι σηµαντικό να τον εξετάσουµε σαν ένα σύνολο από απλούς scalar επεξεργαστές όπως φαίνεται στο σχήµα 4. Ο αριθµός των εικονικών αυτών επεξεργαστών είναι ίσος µε το µήκος των vector καταχωρητών της µηχανής. Η προσέγγιση αυτή αντιµετωπίζει έναν vector καταχωρητή ως µια σειρά από τοπικούς καταχωρητές καθένας εκ των οποίων ανήκει σε έναν εικονικό επεξεργαστή. Κάθε vector εντολή πραγµατοποιεί µια SIMD operation, δηλαδή µια operation ανά επεξεργαστή. Οι επεξεργαστές είναι εικονικοί γιατί οι εντολές τους πολυπλέκονται χρονικά εκµεταλλευόµενοι τους διαθέσιµους φυσικούς πόρους του συστήµατος. Για παράδειγµα η vector unit του Cray-1 µπορεί να θεωρηθεί ότι περιέχει 64 εικονικούς επεξεργαστές, των οποίων οι πράξεις της πρόσθεσης πολυπλέκονται χρονικά για να αξιοποιήσουν την µία και µοναδική λειτουργική µονάδα pipeline πρόσθεσης που διαθέτει. 6
Σχήµα 4: Ο vector επεξεργαστής ως µια σειρά από scalar επεξεργαστές 4 Πλεονεκτήµατα-µειονεκτήµατα των vector υπολογιστών Στα θετικά των vector υπολογιστών συγκαταλέγονται: o Βελτίωση στην πυκνότητα του κώδικα: Η µείωση του αριθµού των εντολών που χρειάζονται για να εκτελεστεί το πρόγραµµα έχει ως αποτέλεσµα την καλύτερη αξιοποίηση της cache µνήµης. Η µείωση στις αστοχίες στην cache επιφέρουν άµεσα αύξηση της ταχύτητας των υπολογισµών. o Ελάττωση του αριθµού των εντολών που χρειάζονται για να εκτελεστεί το πρόγραµµα: Αν διατηρηθούν όλοι οι άλλοι παράγοντες σταθεροί, η µείωση του συνολικού αριθµού των εντολών ενός προγράµµατος έχει ως αποτέλεσµα τη µείωση του χρόνου εκτέλεσης του. o Οργάνωση των δεδοµένων σε patterns που µπορούν να αντιµετωπιστούν πιο αποτελεσµατικά από το υλικό (hardware): Η vector οργάνωση των δεδοµένων είναι πολύ χρήσιµη διότι µειώνει την αλληλεξάρτηση των δεδοµένων κατά την εκτέλεση των εντολών (data dependencies). Αυτό σηµαίνει ότι το hardware είναι πολύ πιο απλό σε σύγκριση µε την out-of-order λογική, πετυχαίνοντας ταυτόχρονα µια ικανοποιητική παραλληλία o Οι βρόγχοι µπορούν να αντικατασταθούν από απλές εντολές εξαλείφοντας έτσι το overhead του βρόγχου: Η εκτέλεση ενός βρόχου απαιτεί αρκετές διακοπές για την εκτέλεση των εντολών από τον επεξεργαστή καθώς και την ύπαρξη branch prediction. Επίσης, σε superscalar υπολογιστές η παραλληλία περιορίζεται από το γεγονός ότι οι εντολές µπορούν να διοχετευτούν στον πυρήνα του επεξεργαστή µε περιορισµένο ρυθµό. 7
Παρόλα αυτά οι vector υλοποιήσεις υστερούν στα εξής: o Επεκτάσεις-Τροποποιήσεις της αρχιτεκτονικής του σετ εντολών (Instruction Set Architecture ISA): Το σετ εντολών θα πρέπει να καθοριστεί από την αρχή ώστε να υποστηρίζει τις vector λειτουργίες και δοµές δεδοµένων, ή θα πρέπει να προστεθούν στις ήδη υπάρχουσες εντολές νέες, ειδικά για vector, λειτουργίες. Στην πρώτη περίπτωση το ήδη υπάρχον λογισµικό δε θα τρέχει, ενώ στη δεύτερη περίπτωση δε θα παρατηρηθεί καµία αύξηση στην ταχύτητα. Το µεγάλο πλεονέκτηµα των super scalar υπολογιστών ήταν ότι η αρχιτεκτονική αυτή πετύχαινε αύξηση των επιδόσεων του ήδη υπάρχοντος κώδικα. Στην πράξη βέβαια αποδείχτηκε ότι νέοι compilers οι οποίοι είχαν γνώση της νέας αρχιτεκτονικής µπορούσαν να πετύχουν ακόµη καλύτερη ταχύτητα. o Επεκτάσεις στις λογικές µονάδες και στους καταχωρητές: Αυτό στην αρχή σήµαινε σηµαντική αύξηση στην επιφάνεια του chip του επεξεργαστή. Η παραγωγή VLSI συστηµάτων κατέστησε σήµερα δυνατή την ύπαρξη πολύ µεγάλων vectors που περιέχουν αριθµούς µε πολλά δεκαδικά ψηφία σε πολύ µικρή επιφάνεια. o Επέκταση του συστήµατος µνήµης: Το σύστηµα µνήµης είναι ένα από τα πιο σηµαντικά ζητήµατα σε µια vector µηχανή. Πρόκειται ουσιαστικά για το διαθέσιµο εύρος ζώνης. Για να εκτελεστεί παράλληλα ένας µεγάλος αριθµός από οδηγίες σε µικρό χρονικό διάστηµα θα πρέπει το σύστηµα µνήµης να έχει διαθέσιµα όλα τα απαραίτητα δεδοµένα εξίσου γρήγορα. Επίσης, η χρήση της cache δεν είναι ιδιαίτερα χρήσιµη στην περίπτωση των vector ή matrix δεδοµένων. Αυτό συµβαίνει διότι η προσπέλαση των στοιχείων ενός vector ή ενός matrix γίνεται συχνά µε έναν προκαθορισµένο τρόπο και στην πλειοψηφία των περιπτώσεων ανακαλείται ολόκληρη η γραµµή ή η στήλη. Έτσι όµως καταλήγουµε σε θέσεις µνήµης οι οποίες έχουν µια σταθερή απόσταση µεταξύ τους (stride). Αν η απόσταση αυτή και ο αριθµός των γραµµών της cache έχουν κοινό πολλαπλάσιο τότε όλα τα δεδοµένα µπορούν να χαρτογραφηθούν σε ένα µικρό υποσύνολο των γραµµών της cache, πράγµα που δεν γίνεται συχνά. Για αυτό το λόγο η πλειοψηφία των vector συστηµάτων δεν αποθηκεύει τα δεδοµένα στην cache και τα φορτώνει απευθείας από την κύρια µνήµη. 5 Vector καταχωρητές και λογικές µονάδες Κάθε σετ καταχωρητών αποτελείται συνήθως από 8 ανεξάρτητους vector καταχωρητές. Καθένας από αυτούς περιέχει 16 έως 64 στοιχεία και κάθε στοιχείο είναι µια 64-bit τιµή κινητής υποδιαστολής (floating point). Οι τιµές αυτές µπορούν να διαφέρουν ανάλογα µε τον σκοπό για τον οποίο χρησιµοποιείται η vector µηχανή και την αντιστάθµιση των πλεονεκτηµάτων της κάθε υλοποίησης. Η πλειοψηφία των vector επεξεργαστών ενσωµατώνουν αρχιτεκτονικές τύπου load/store, πράγµα που σηµαίνει ότι απαιτούνται εντολές vector load και vector store για να γίνει εφικτή η ανταλλαγή δεδοµένων µεταξύ των καταχωρητών και της κύριας µνήµης. Οι λογικές 8
µονάδες της µνήµης (memory functional units) που διακινούν vector δεδοµένα είναι pipelined, έτσι ώστε να παρέχουν ταχύρυθµη διαµεταγωγή δεδοµένων (data throughput). Το κύριο µέληµα, τόσο για τις λογικές µονάδες της µνήµης όσο για τις κοινές (αριθµητικές) µονάδες, είναι η µεγιστοποίηση του troughput. Από τη στιγµή που ο επεξεργαστής εργάζεται σε vectors δεδοµένων µεγάλου µεγέθους συµπεραίνουµε ότι ένα σηµαντικό κριτήριο ταχύτητας είναι το πόσο γρήγορα γίνεται η επεξεργασία ολόκληρου του block δεδοµένων, ακόµη και αν η ταχύτητα επεξεργασίας ενός µεµονοµένου στοιχείου (latency) αυξάνεται. Αντίθετα, στις scalar λογικές µονάδες η latency παίζει καθοριστικό ρόλο στην ταχύτητα. Οι vector λογικές µονάδες πρέπει να είναι σε θέση να εκτελούν κινητής υποδιαστολής πρόσθεση, αφαίρεση, πολλαπλασιασµό, διαίρεση ή αντιστροφή, καθώς και λογικές πράξεις όπως σύγκριση κοκ. Η διαίρεση µπορεί να υλοποιηθεί µε την αλληλουχία αντιστροφής και πολλαπλασιασµού (x/y=x*1/y). Ο λόγος που χρησιµοποιείται η αντιστροφή περισσότερο από την διαίρεση είναι ότι η πρώτη διασωληνώνεται (pipelined) πιο εύκολα και αποδοτικά. Πρέπει όµως να γίνεται µε προσοχή ώστε να µην οδηγηθούµε σε καταστάσεις όπου το αποτέλεσµα είναι µικρής ακρίβειας. Μια vector εντολή φόρτωσης (load instruction) µπορεί να προκαλέσει σφάλµα χρονισµού αν ένα στοιχείο του vector δεν βρίσκεται στην κύρια µνήµη (page miss). Για αυτό το λόγο πολλές υλοποιήσεις δεν επιτρέπουν την αλληλεπικάλυψη (overlap) vector υπολογισµών όταν αυτοί χρησιµοποιούν προγενέστερα vector loads. Με άλλα λόγια ένα vector load πρέπει να µεταφέρει πλήρως ένα vector στον καταχωρητή προτού γίνουν άλλοι υπολογισµοί µε τον εν λόγω καταχωρητή. Υπάρχουν ορισµένες εντολές οι οποίες εργάζονται σε vector δεδοµένα παράγοντας scalar αποτελέσµατα. Ένα χαρακτηριστικό παράδειγµα είναι η vector σύγκριση, όπου όλα τα στοιχεία δυο vector συγκρίνονται ανά δύο και το αποτέλεσµα είναι ένα vector από bit που αντιπροσωπεύουν το αποτέλεσµα της κάθε σύγκρισης. Αν ο vector περιέχει 64 bit, τότε µια και µοναδική 64-bit scalar τιµή (value) µπορεί να αποθηκεύσει το αποτέλεσµα της σύγκρισης. Ένα άλλο παράδειγµα vector υπολογισµού µε scalar αποτέλεσµα είναι η εντολή accumulate. Στην περίπτωση αυτή τα στοιχεία των vector V1 και V2 προστίθενται ανά δύο και το αποτέλεσµα µπορεί να αποθηκευτεί σε έναν scalar καταχωρητή ίδιου µήκους µε αυτό των vectors. Ένα σηµαντικό ζήτηµα είναι αυτό που σχετίζεται µε την επεξεργασία vectors, το µήκος των οποίων είναι µικρότερο από το µήκος του vector καταχωρητή. Μια απλή προσέγγιση είναι να συµπληρωθούν τα κενά µε µηδενικά. Στην πρόσθεση δύο vector µε διαφορετικό µέγεθος, το αποτέλεσµα της πρόσθεσης των στοιχείων του µεγαλύτερου vector µε τα µηδενικά του άλλου, αφήνει τα πρώτα αναλλοίωτα. Στον πολλαπλασιασµό όµως µηδενίζονται. Μια άλλη προσέγγιση είναι να συµπληρώσουµε τα επιπλέον στοιχεία µε µια ακατάλληλη τιµή, όπως για παράδειγµα την IEEE NaN (Not a Number). Το αποτέλεσµα οποιασδήποτε εντολής µε όρισµα ένα τέτοιο στοιχείο είναι επίσης ένα NaN. 6 Αρχιτεκτονικές Vector Memory-Memory και Vector-Register Υπάρχουν δύο βασικές φιλοσοφίες στην vector αρχιτεκτονική, ανάλογα µε τη θέση των vector operands. Οι αρχιτεκτονικές memory-memory, όπως ο CDC STAR 100, διαθέτουν εντολές που εκτελούνται σε vectors που βρίσκονται στην κύρια 9
µνήµη, διαβάζουν τα αρχικά δεδοµένα και γράφουν τα αποτελέσµατα σε αυτήν. Oι αρχιτεκτονικές Vector-register, όπως η σειρά Cray και όλοι οι υπερυπολογιστές που σχεδιάστηκαν στην Ιαπωνία, κάνουν την ίδια δουλειά χρησιµοποιώντας vector καταχωρητές. Ξεχωριστές εντολές load και store αναλαµβάνουν την µεταφορά δεδοµένων µεταξύ κύριας µνήµης και καταχωρητών. Οι vector register αρχιτεκτονικές έχουν πολλά πλεονεκτήµατα σε σύγκριση µε τις memory-memory. Οι memory-memory αρχιτεκτονικές πρέπει να γράψουν όλα τα ενδιάµεσα αποτελέσµατα στην κύρια µνήµη και µετά να τα ανακτήσουν εκ νέου από αυτήν. Η vector register αρχιτεκτονική µπορεί να κρατήσει τα ενδιάµεσα αποτελέσµατα στους καταχωρητές, κοντά στις vector functional units, περιορίζοντας απαιτήσεις σε προσωρινή αποθήκευση, bandwidth µνήµης και ελαττώνοντας την καθυστέρηση µεταξύ των εντολών (inter instruction latency). Αν πολλές vector εντολές χρειάζονται ένα vector αποτέλεσµα, στην memory-memory αρχιτεκτονική αυτό πρέπει να φορτωθεί ισάριθµες φορές από τη µνήµη, ενώ στην vector register αρχιτεκτονική γίνεται κλήση στον καταχωρητή που το περιέχει, αποφεύγοντας τις πολλαπλές προσπελάσεις της µνήµης. Για τους παραπάνω λόγους οι vector register µηχανές αποδείχτηκαν αποδοτικότερες από τις memory-memory µηχανές. 7 Εκτέλεση vector εντολών Ο κυριότερος περιορισµός στην απόδοση των vector µηχανών είναι το bandwidth της µνήµης. Για να διατηρήσουµε υψηλό το bandwidth της µνήµης πρέπει να εξασφαλίσουµε µια συνεχή ροή από κλήσεις προς τη µνήµη. Οι vector µικροϋπολογιστές υποστηρίζονται συνήθως από κοινές DRAM µνήµες, οι οποίες έχουν µεγαλύτερο latency από τις SRAM µνήµες, που χρησιµοποιούν οι vector υπερυπολογιστές. Latencies της τάξης των 100 κύκλων είναι τυπικές για γρήγορους µικροϋπολογιστές που συνοδεύονται από off-chip DRAM µνήµες. Για να πετύχουµε υψηλό bandwidth µνήµης µε αυτά τα latencies πρέπει να δηµιουργήσουµε πολλές ανεξάρτητες κλήσεις προς την κύρια µνήµη. Τέσσερις είναι οι βασικές τεχνικές που χρησιµοποιούνται για την αντιµετώπιση των µεγάλων latencies της κύριας µνήµης. o Στατικός χρονοπρογραµµατισµός (static scheduling). Έχει τις λιγότερες απαιτήσεις από πλευράς υλικού. Το πρόγραµµα παρεµβάλλει ανεξάρτητες εντολές ανάµεσα στο φόρτωµα δεδοµένων και στην εκτέλεση εντολών που χρησιµοποιούν τα δεδοµένα αυτά. Με αυτόν τον τρόπο η µηχανή µπορεί να εκτελέσει ανεξάρτητες εντολές την ώρα που γίνεται ανάκληση δεδοµένων από την κύρια µνήµη. Οι vector εντολές είναι µια µορφή στατικού χρονοπρογραµµατισµού, αφού µια εντολή πραγµατοποιεί πολλές ανεξάρτητες λειτουργίες στα δεδοµένα ενός vector. o Prefetching. Μπορεί να υλοποιηθεί τόσο µέσω του υλικού όσο και του λογισµικού. Και στις δυο περιπτώσεις τα απαιτούµενα δεδοµένα ανακαλούνται από την κύρια µνήµη πριν εκτελεστεί η εντολή load, πράγµα που µειώνει την ορατή από τον χρήστη latency. Σχήµατα που χρησιµοποιούν prefetching χρειάζονται καταχωρητές στους οποίους αποθηκεύονται τα δεδοµένα πριν αυτά ζητηθούν από την εντολή load. Το prefetchng µέσω software δεν εµπλέκει το υλικό της µηχανής. Το πρόγραµµα εκτελεί τις αντίστοιχες εντολές και αποθηκεύει τα δεδοµένα στην λανθάνουσα µνήµη. Οι 10
τεχνικές prefetching µέσω hardware επιχειρούν να προβλέψουν µελλοντικές κλήσεις βασιζόµενες σε προηγούµενα patterns. o υναµικός χρονοπρογραµµατισµός (Dynamic scheduling). Υλοποιείται µε πολλές τεχνικές µέσω hardware οι οποίες εκτελούν εντολές out of order. Αντί να µπλοκάρεται η κατάσταση της µηχανής σε µια εντολή όταν οι τελεστές της δεν είναι ακόµη διαθέσιµοι, γίνεται αποθήκευσή της σε έναν καταχωρητή µέχρι να βρεθούν τα απαραίτητα δεδοµένα. Έτσι η µηχανή είναι σε θέση να εκτελέσει άλλες ανεξάρτητες εντολές που βρίσκονται πιο µπροστά στο instruction stream. o Multithreading. Εκτελεί παράλληλα περισσότερα από ένα instruction streams. 7.1 Vector εκτέλεση vs scalar εκτέλεση εντολών Ας υποθέσουµε ότι έχουµε έναν scalar αριθµό a, ο οποίος πολλαπλασιάζεται µε ένα vector Χ και το αποτέλεσµα του πολλαπλασιασµού προστίθεται σε ένα άλλο vector Υ. Το αποτέλεσµα αποθηκεύεται στο vector Υ. Θεωρούµε ότι το µήκος των vectors είναι 64. Στη συνέχεια θα δούµε πως υλοποιούνται τα παραπάνω σε έναν scalar και σε έναν vector επεξεργαστή: o Scalar επεξεργαστής: Οι εντολές που θα πρέπει να εκτελεσθούν είναι οι εξής: LD F0,a ADDI R4,Rx,#512 Loop: LD F2,0(Rx) MULTD F2,F0,F2 LD F4,0(Ry) ADDD F4,F2,F4 SD F4,0(Ry) ADDI Rx,Rx,#8 ADDI Ry,Ry,#8 SUB R20,R4,Rx BNZ R20,loop Με την πρώτη εντολή φορτώνεται στον καταχωρητή F0 η τιµή του αριθµού a. Στη συνέχεια ανατίθεται στον R4 η τελευταία διεύθυνση της µνήµης στην οποία υπάρχουν χρήσιµα δεδοµένα προς επεξεργασία (ουσιαστικά µας δίνει τη διεύθυνση στην οποία µπορούµε να βρούµε το τελευταίο στοιχείο του Υ). Αφού δόθηκαν οι αρχικές συνθήκες το πρόγραµµα µπαίνει σε έναν βρόχο όπου φορτώνεται το ν-οστό στοιχείο του Χ, πολλαπλασιάζεται µε τον αριθµό a, φορτώνεται το ν-οστό στοιχείο του Υ και προστίθεται στο αντίστοιχο αποτέλεσµα. Το αποτέλεσµα αντικαθιστά το ν- στο στοιχείο του Υ. Οι επόµενες δύο εντολές (ADDI) προσδιορίζουν σε ποιο σηµείο της µνήµης θα βρεθούν τα επόµενα (ν+1) στοιχεία του Χ και Υ αντίστοιχα. Τέλος, το τελευταίο ζευγάρι εντολών δεν κάνουν τίποτε άλλο από το να ελέγχουν αν έχουν προσπελαστεί όλα τα στοιχεία των Χ και Υ. Αν πολλαπλασιάσουµε το 64 που είναι 11
το µήκος των vector µε το 8 (που είναι το stride), το αποτέλεσµα θα µας δώσει την τελική διεύθυνση 512. o Vector επεξεργαστής: Στην περίπτωση αυτή οι εντολές που θα πρέπει να εκτελεστούν είναι οι εξής: LD LV MULTS LV ADDV SV F0,a V1,Rx V2,F0,V1 V3,Ry V4,V2,V3 Ry,V4 Εδώ, µε την πρώτη εντολή φορτώνεται ο scalar a. Στη συνέχεια φορτώνεται ο vector Χ, πολλαπλασιάζεται µε τον a και το αποτέλεσµα αποθηκεύεται σε ένα νέο vector V2. Αφού φορτωθεί και ο Y στην µνήµη θα προστεθεί στον V2 και το αποτέλεσµα θα αντικαταστήσει τον αρχικό Υ vector. Ο συνολικός αριθµός των operations που εκτελεί ο scalar επεξεργαστής είναι 578. ηλαδή 64 (τόσες φορές εκτελείται ο βρόγχος)*9 (ο αριθµός των εντολών που βρίσκονται µέσα στο βρόγχο)+2(οι εντολές που βρίσκονται εκτός βρόγχου και εκτελούνται µόνο µια φορά)=578. Από την άλλη στον vector επεξεργαστή ο αριθµός των operations είναι: 1(η φόρτωση του scalar a) +5(ο αριθµός των vector εντολών)*64(το µήκος των vector)=321. Ο λόγος των δύο µεγεθών αυτών φανερώνει µια αύξηση στην ταχύτητα εκτέλεσης κατά έναν συντελεστή περίπου 1,8. 8 Παράγοντες που αποτρέπουν το vectorization Από το παραπάνω παράδειγµα φαίνεται καθαρά ότι οι βρόγχοι είναι ιδανικοί για την υλοποίηση του vectorization. Στη πραγµατικότητα τα πράγµατα είναι αρκετά πιο περίπλοκα. Το vectorization µπορεί να υλοποιηθεί µόνο σε έναν Do βρόγχο και µάλιστα, στον πιο εσωτερικό. Έτσι λοιπόν είναι απαραίτητο ο αριθµός των επαναλήψεων να είναι αρκετά µεγάλος έτσι ώστε να αντισταθµίζεται η καθυστέρηση λόγω της διαδικασίας αρχικοποίησης και του overhead. O προγραµµατιστής θα πρέπει κατά τη συγγραφή του κώδικα να εξασφαλίζει τµήµατα του προγράµµατος που µπορούν να ανυσµατοποιηθούν έτσι ώστε να αυξάνονται οι πιθανότητες παράλληλης εκτέλεσης. Αν ο κώδικας είναι πολύπλοκος ο µεταγλωτιστής δεν θα είναι σε θέση να αποδώσει. Η ύπαρξη εποµένως do βρόγχων δεν είναι ικανή και απαραίτητη συνθήκη για να εξασφαλιστεί το vectorization. Υπάρχει µια σειρά από παράγοντες που αναστέλλουν την ανυσµατοποποίηση και ονοµάζονται vectorization inhibitors. Ο προγραµµατιστής πρέπει να αποφεύγει τις περιπτώσεις αυτές και να αντικαθιστά το ύποπτο κοµµάτι του κώδικα µε άλλο κατάλληλο για ανυσµατοποίηση. Οι προαναφερθέντες παράγοντες είναι οι εξής: 12
o Κλήσεις ρουτινών: Οι ρουτίνες διακόπτουν το πρόγραµµα από την κανονική του ροή. Στο σύγχρονο όµως προγραµµατισµό θεωρούνται πολύτιµα εργαλεία τα οποία δεν µπορούµε να εγκαταλείψουµε για χάρη των vector επεξεργαστών. Για αυτό το λόγο προτάθηκε η λύση να ενσωµατώνονται οι ρουτίνες στον κώδικά της εφαρµογής. Γλώσσες προγραµµατισµού όπως η C++ διαθέτουν compilers οι οποίοι είναι σε θέση να εκτελέσουν αυτόµατα αυτήν την λειτουργία (subroutine inline). Ο ίδιος ο µεταγλωττιστής αναλαµβάνει να αντιµετωπίσει πιθανές συγκρούσεις ονοµάτων µεταβλητών κλπ. Αφού γίνει αυτό, το vectorization µπορεί να επιτευχθεί µέσω του κανονικού compilation. Για παράδειγµα στο παρακάτω πρόγραµµα inline double radius( double x, double y, double z ) { return sqrt( x*x + y*y + z*z ); }... int main() {.. for( int i=1; i<=n; ++i ) { r[i] = radius( x[i], y[i], z[i] ); }.. } δίνεται εντολή στον compiler να ενσωµατώσει την ρουτίνα radius όπου αυτό απαιτείται στο κυρίως πρόγραµµα. Αυτό συµβαίνει στον βρόγχο for εντός του οποίου βλέπουµε ότι γίνεται κλήση στην εν λόγω ρουτίνα. O compiler ουσιαστικά θα αντικαταστήσει την radius(x[i],y[i],z[i]) του βρόγχου µε το sqrt(x[i]*x[i]+y[i]*y[i]+z[i]*z[i]). o Εντολές εισόδου εξόδου (I/O statements): Πραγµατοποιούνται ασύγχρονα χωρίς να υπάρχει κάποιο pattern. o εδοµένα-χαρακτήρες: εµποδίζουν και αυτοί µε τη σειρά τους το vectorization για τον απλό λόγο ότι δεν έχουν την µορφή 64 bit floating point. o Οι µη δοµηµένοι βρόγχοι: όταν γίνεται άλµα από το κυρίως πρόγραµµα µέσα σε έναν βρόγχο ή το αντίθετο δεν µπορούν µε κανέναν τρόπο να τροποποιηθούν ώστε να συµβαδίσουν µε το vectorization. Πρέπει απλά να αποφεύγονται. o Εξάρτηση δεδοµένων: Χαρακτηριστικό παράδειγµα είναι η αναδροµή σε έναν βρόγχο. Το vectorization αποτυγχάνει επειδή χρησιµοποιούνται δεδοµένα που υπολογίστηκαν από προηγούµενη επανάληψη. o Πολύπλοκος προγραµµατισµός: Κλείνοντας µπορούµε µε ασφάλεια να υποστηρίξουµε ότι ο πολύπλοκος προγραµµατισµός είναι το α και το ω στην αποτροπή του vectorization. Όσο πιο δαιδαλώδης είναι ένας βρόγχος τόσο 13
πιο δύσκολα διανυσµατοποιείται. Σύνθετες εκφράσεις και πολλά goto συνθέτουν ένα δύσκολο σενάριο στο οποίο ένας compiler δύσκολα θα ανταποκριθεί. Για αυτό το λόγο η συγγραφή κώδικα πρέπει πάντα να γίνεται λαµβάνοντας υπόψη τις δυνατότητες για vectorization. 9 Αύξηση της ταχύτητας Ακόµη και όταν µια εφαρµογή είναι vectorizable, ένα σηµαντικό θέµα είναι το πώς θα πετύχουµε το µέγιστη αύξηση της απόδοσης της vector µηχανής. Ένα σηµαντικό µάθηµα που πήρε η επιστηµονική κοινότητα ήταν ότι οι υπάρχοντες κώδικες δεν µπορούσαν να χρησιµοποιηθούν αυτούσιοι. Παλιά προγράµµατα χρειάστηκαν προσθήκες, τροποποιήσεις και πολλές φορές πλήρη επανασύνταξη. Μέσω αυτής της διαδικασίας προέκυψαν βασικοί κανόνες που επιτρέπουν την καλύτερη προσαρµογή της εφαρµογής στις δυνατότητες των vector επεξεργαστών µε αποτέλεσµα την άµεση αύξηση της απόδοσης. Πέρα από την αναδιοργάνωση του κώδικα µπορούν να ληφθούν υπόψη οι ιδιοµορφίες των δοµών δεδοµένων που χρησιµοποιούνται ευρέως σε επιστηµονικές εφαρµογές, όπως λόγου χάρη sparse matrices. Η δυνατότητα του υλικού να µεταπηδά από συνεπτυγµένες µορφές (χωρίς δηλαδή τα µηδενικά) στις πλήρης διατυπώσεις των ανωτέρω πινάκων επιφέρει άµεση αύξηση στην ταχύτητα της µηχανής. Μια εξίσου σηµαντική τεχνική είναι η chaining, η οποία στοχεύει στην ελαχιστοποίηση της memory latency. Η φιλοσοφία είναι η εξής: εν είναι απαραίτητο να ολοκληρωθεί η εκτέλεση µιας vector εντολής προτού αρχίσει η επόµενη. Με άλλα λόγια µπορούµε να έχουµε αλληλοεπικάλυψη εντολών. Ας υποθέσουµε ότι έχουµε δυο vector εντολές. MULTV ADDV V1, V2, V3 V4, V1, V5 Στην πρώτη πολλαπλασιάζονται τα V2 και V3 και το αποτέλεσµα αποθηκεύεται στο V1. Αυτό στη συνέχεια προστίθεται στο V5 και το τελικό αποτέλεσµα αποθηκεύεται στο V4. Παρατηρούµε ότι τα προϊόντα της πρώτης εντολής είναι ταυτόχρονα και είσοδος της δεύτερης. Αν το µήκος των vector είναι ίσο µε 64 τότε η πρώτη εντολή θα διοχετεύσει 64 ζευγάρια από στοιχεία σε έναν Pipelined πολλαπλασιαστή. Σε κάποια φάση της εκτέλεσης της εντολής η µηχανή θα βρίσκεται σε µια ενδιαφέρουσα κατάσταση. Τα πρώτα στοιχεία του V1 θα περιέχουν τα σωστά υπολογισµένα δεδοµένα, ένα µέρος των επόµενων στοιχείων που θα συνθέσουν το τελικό V1 βρίσκονται στον Pipelined πολλαπλασιαστή και τα υπόλοιπα είναι υπό τη µορφή τελεστών V2 και V3. Τα στοιχεία όµως που βρίσκονται ήδη στον V1 µπορούν να διοχετευθούν σε έναν pipelined adder, όπου µαζί µε τα στοιχεία του V5 θα δώσουν το τελικό αποτέλεσµα, δηλαδή τον vector V4. Αφότου υπολογιστεί το πρώτο στοιχείο του V2, ξεκινά η αρχικοποίηση της πρόσθεσης. Μέχρι να ολοκληρωθεί αυτή είναι ήδη διαθέσιµα τα πρώτα στοιχεία του V1, τα οποία έχουν διοχετευθεί στον adder. Συνεπώς στον αµέσως επόµενο κύκλο ρολογιού µπορεί να παραχθεί το πρώτο αποτέλεσµα της πρόσθεσης, παράλληλα µε αυτό του πολλαπλασιασµού. Με αυτήν την τεχνική επιτυγχάνεται η εκτέλεση της πρόσθεσης πριν ολοκληρωθεί ο πολλαπλασιασµός του παραδείγµατος. Αν υποθέσουµε ότι έχουµε µια µηχανή που δεν ενσωµατώνει chaining και ότι για την αρχικοποίηση των 14
πράξεων πρόσθεσης και πολλαπλασιασµού απαιτούνται 6 και 7 κύκλοι αντίστοιχα, τότε χρειάζονται: o 7 κύκλοι για την αρχικοποίηση της πράξης του πολλαπλασιασµού o 64 κύκλοι για τον υπολογισµό του γινοµένου των ισάριθµων ζευγαριών o 6 κύκλοι για την αρχικοποίηση της πρόσθεσης o 64 κύκλοι για το άθροισµα των στοιχείων Συνολικά έχουµε λοιπόν 141 κύκλους ρολογιού. Αν εξετάσουµε στη συνέχεια µια µηχανή στην οποία υλοποιείται η τεχνική chaining ο αριθµός των κύκλων διαµορφώνεται ως εξής: o 7 κύκλοι για την αρχικοποίηση του πολλαπλασιασµού o 64 κύκλοι για την ολοκλήρωση του αθροίσµατος Σύνολο 77 κύκλοι ρολογιού. Είναι φανερό από τα παραπάνω ότι η τεχνική chaining αυξάνει την ταχύτητα της vector µηχανής. Σχήµα 5: ιαφορά στον χρόνο εκτέλεσης Chained και Unchained εκτέλεση εντολών 10 Εφαρµογές Οι vector επεξεργαστές προορίζονταν για αυστηρά επιστηµονικές εφαρµογές. Στην πορεία όµως κατάφεραν να ανταγωνιστούν τους scalar επεξεργαστές σε µια ευρεία γκάµα εφαρµογών. Χαρακτηριστικά παραδείγµατα είναι: o Γραµµική άλγεβρα: Εντολές γραµµικής άλγεβρας είναι πολύ σηµαντικά στοιχεία της πλειοψηφίας των εφαρµογών, όπως για παράδειγµα multimedia, αλληλεπίδραση ανθρώπου-µηχανής και επιστηµονικοί αλγόριθµοι. Η επιστηµονική κοινότητα έχει θεσπίσει µια συλλογή από βασικές ρουτίνες γραµµικής άλγεβρας (BLAS Basic Linear Algebra Subroutines) και οι περισσότεροι κατασκευαστές προσφέρουν για αυτόν τον σκοπό βελτιστοποιηµένες βιβλιοθήκες. Όλες οι BLAS ρουτίνες είναι vectorizable και το 15
µέγεθος του vector εξαρτάται από το πρόγραµµα που καλεί την βιβλιοθήκη. Αντιπροσωπευτικά παραδείγµατα των BLAS είναι ο πολλαπλασιασµός πίνακα -vector και πίνακα-πίνακα. o o o o o Επεξεργασία εικόνας: Μια συνηθισµένη εργασία στην επεξεργασία σήµατος είναι η convolution η οποία εκτελείται πολύ αποδοτικά σε vector υπολογιστές. Σύνθεση ήχου: Κατά καιρούς έχουν προταθεί αλγόριθµοι που για τη σύνθεση ήχου απαιτούν τη δηµιουργία πολλαπλών τµηµατικών ταλαντωτών σε όλο το φάσµα των συχνοτήτων, οι παράµεροι των οποίων αλλάζουν συνεχώς σε εφαρµογές πραγµατικού χρόνου. Για την αύξηση της ταχύτητας επεξεργασίας εφαρµόζεται το vectorization σε αυτά τα ανεξάρτητα τµήµατα, ο αριθµός των οποίων ισούται µε το µήκος του διανύσµατος. Μια απλή αύξηση του µεγέθους του vector µπορεί να επιφέρει λεπτοµερέστερη σύνθεση και αναπαραγωγή και κατά συνέπεια µεγαλύτερη απόδοση. Συµπίεση δεδοµένων Κρυπτογραφία: Ο IDEA (International Data Encryption Algorithm) εργάζεται ουσιαστικά µε σετ από πίνακες, πράγµα που είναι ιδανικό για vector επεξεργαστές Αναγνώριση φωνής: Vector υπολογιστές όπως ο Spert II αποδείχτηκαν αποτελεσµατικότεροι από κοινά workstations στην εκπαίδευση νευρωνικών δικτύων που χρησιµοποιούνται για αναγνώριση φωνής. Οι απαιτητικοί αλγόριθµοι που χρησιµοποιούνται σε τέτοιες εφαρµογές υφίστανται σε µεγάλο βαθµό vectorization µε αποτέλεσµα την κατακόρυφη αύξηση της ταχύτητας. 16
Πηγές [1] K. Asanovic, J. Beck, B. Irissou, B. Kingsbury, and J. Wawrzynek. T0: A single-chip vector microprocessor with reconfigurable pipelines. In H. Grunbacher, editor, Proc. 22nd European Solid-State Circuits Conf., pages 344 347, Neuchatel, Switzerland, September 1996. Editions Frontieres. [2] M. Awaga and H. Takahashi. The µvp 64-bit vector coprocessor: A new implementation of high-performance numerical computation. IEEE Micro, 13(5):24 36, October 1993. [3] W. Buchholz. The IBM System/370 vector architecture. IBM Systems Journal, 25(1):51 62,1986. [4] DEC. Method and apparatus for executing instructions for a vector processing system. U.S. Patent 4,949,250, August 1990. [5] R. Espasa. Advanced Vector Architectures. PhD thesis, Universitat Polit`ecnica de Catalunya, February 1997. [6] R. Espasa and M. Valero. Decoupled vector architectures. In Proc. 2nd High Performance Computer Architecture Conf., pages 281 290. IEEE Computer Society Press, Feb 1996. [7] J. L. Hennessy and D. A. Patterson. Computer Architecture A Quantitative Approach, Second Edition. Morgan Kaufmann, 1996. [8] IBM. Vector processing unit. U.S. Patent 4,791,555,March 1987. [9] W. Schoenauer. Scientific Computjng on Vector Supercomputers. Elsevier Science Publishers B.V., P.O. Box 1991, 1000 BZ Amsterdam, The Netherlands, 1987. 17