Appunti di Calcolatori Elettronici A.A.

Dimensione: px
Iniziare la visualizzazioe della pagina:

Download "Appunti di Calcolatori Elettronici A.A."

Transcript

1

2 APPUNTI DI Appunti e dispense con esercizi redatti da Nicola Pietroleonardo e Fabio Stroppa in base alle lezioni del corso di Calcolatori Elettronici del Prof. Ing. Francescomaria Marino al Politecnico di Bari dell anno accademico. Parte teorica a cura di Nicola Pietroleonardo. Esercizi ed approfondimenti a cura di Fabio Stroppa. Pagina 2

3 INDICE GENERALE PARTE PRIMA... 7 SET DI ISTRUZIONI... 8 ISTRUZIONI DI TRASFERIMENTO DEI DATI... 8 ISTRUZIONI DI TIPO M (MOV) ISTRUZIONI DI CALCOLO ISTRUZIONI DI CONTROLLO TABELLA SOTTOINSIEME ISTRUZIONI DI MIPS ESECUZIONE DELLE ISTRUZIONI ALL INTERNO DEL PROCESSORE STRUTTURA DEL PROCESSORE FORMATO DELLE ISTRUZIONI CODIFICA DELL ISTRUZIONE PER UN PROCESSORE NO-PIPELINE STRUTTURA DEL PROCESSORE NO-PIPELINE DESCRIZIONE DETTAGLIATA DI OGNI PASSAGGIO ^ FASE IF INSTRUCTION FETCH ^ FASE ID INSTRUCTION DECODE ^ FASE EX EXECUTION ^ FASE MEM MEMORY ACCESS ^ FASE WB WRITE BACK RIEPILOGO TECNICA PIPELINE TEMPO DI ESECUZIONE DI UN PROGRAMA STRUTTURA DEL PROCESSORE PIPELINE EVENTI DI CIASCUNO STADIO DELLA PIPELINE DI MIPS BREVE CENNO SULLE MEMORIE DEL PROCESSORE (CACHE DI 1 LIVELLO) ACCESSO ALLA MEMORIA ALEE STRUTTURALI ALEE DI DATO ALEE STRUTTURALE ALEE DI DATO ISTRUZIONI ALU ISTRUZIONI LOAD ISTRUZIONE BRANCH MIPS PIPELINE OTTIMIZZATO DELAY SLOT TECNICA STATICA TECNICA SPECULATIVA TECNICA DINAMICA Pagina 3

4 SROTOLAMENTO DEL LOOP PIPELINE DA PROGRAMMA ESERCIZI DI RIEPILOGO ESERCIZIO ESERCIZIO ESERCIZIO ESERCIZIO ESERCIZIO PARTE SECONDA GERARCHIA DI MEMORIA MECCANISMO A FINESTRA DEI REGISTRI PRINCIPI FONDAMENTALI DELLA GERARCHIA DI MEMORIA TRASPERENZA DEI LIVELLI PRINCIPI DI LOCALITA LOCALITA SPAZIALE LOCALITA TEMPORALE QUATTRO DOMANDE PER LA CLASSIFICAZIONE DELLE GERARCHIE DI MEMORIE MEMORIE CACHE UN PO DI STORIA E CURIOSITÀ STRATEGIE DI ALLOCAZIONE DEI BLOCCHI CACHE COMPLETAMENTE ASSOCIATIVA CACHE AD INDIRIZZAMENTO DIRETTO CACHE SET ASSOCIATIVA STRATEGIE DI RICERCA E IDENTIFICAZIONE STRATEGIE DI SOSTITUZIONE (FALLIMENTI DI ACCESSO) METODO RANDOM METODO LRU (LAST RECENTLY USED) METODO FIFO (FIRST IN FIRST OUT) FALLIMENTI DI ACCESSO ALLA CACHE LEGGE DELLE TRE C STRATEGIE DI SCRITTURA NELLA CACHE WRITE THROUGH WRITE BACK ELETTRONICA DELLE MEMORIE Pagina 4

5 SRAM DRAM VALUTAZIONE DELLE PRESTAZIONI DELLA MEMORIA CACHE FUNZIONAMENTO LOGICO DI UNA MEMORIA CACHE CACHE POWERPC CACHE MOTOROLA INTERAZIONE DELLE MEMORIE CACHE IN UN SISTEMA COMPLESSO PROBLEMATICHE RELATIVE ALL I/O PROBLEMATICHE RELATIVE AI SISTEMI MULTICORE MIGLIORAMENTO DELLE PRESTAZIONI DELLA BANDA PASSANTE DI UNA MEMORIA BANCHI MULTIPLI DI MEMORIA PARALLELI BANCHI MULTIPLI DI MEMORIA INTERLACCIATI ORGANIZZAZIONE DELLE MEMORIE A SEMICONDUTTORE ESERCIZI DI RIEPILOGO ESERCIZIO ESERCIZIO PARTE TERZA PROCESSORE FLOATING POINT SCHEDULING DELLE ISTRUZIONI FLOATING POINT ALGORITMO DI TOMASULO APPLICAZIONE ALGORITMO DI TOMASULO - ESEMPIO VANTAGGI PARTE QUARTA PROCESSORI VLIW PROCESSORI SUPERSCALARI PROCESSORI VETTORIALI TABELLA SET ISTRUZIONI VETTORIALI OPERAZIONI DI LOAD E STORE L ISTRUZIONE LVWS I REGISTRI VLR E MVLR PRESTAZIONI ANALISI REALE DELL ARCHITETTURA DI UNA CPU VETTORIALE CRAY-1 (1976) Pagina 5

6 SCHEMA LOGICO IDEE ALLA BASE DELLA ORGANIZZAZIONE VETTORIALE CODICE VETTORIALE ESECUZIONE ARITMETICA DELLE ISTRUZIONI SISTEMA DI MEMORIZZAZIONE DI DATI VETTORIALI NEI REGISTRI VETTORIALI ESECUZIONE ISTRUZIONI VETTORIALI STRUTTURA DELLE UNITA VETTORIALI DIFFERENZA FRA ARCHITETTURA MEMORIA-MEMORIA E ARCHITETTURA A REGISTRI VETTORIALI VETTORIZZAZIONE AUTOMATICA DEL CODICE GESTIONE DI VETTORI CON DIMENSIONE SUPERIORE A MVLR VECTOR STRIPMINING PARALLELISMO DELLE ISTRUZIONI VETTORIALI PENALITA DI AVVIO DELLE CPU VETTORIALI GESTIONE DELLE CONDIZIONI USO DEL REGISTRO V.MASK ISTRUZIONI MASCHERATE RIDUZIONE A OPERAZIONI SCALARI ESERCIZIO ARCHITETTURA MULTICORE PARALLELISMO A LIVELLO DI THREAD, MULTI-THREAD SIMULTANEOUS MULTI-THREADING FINE-GRAINED MULTI-THREADING COARSE-GRAINED MULTI-THREAD MEMORIA CONDIVISA E MEMORIA DISTRIBUITA IN SISTEMI MULTICORE INDICE ANALITICO BIBLIOGRAFIA ESERCIZI SVOLTI Pagina 6

7 PARTE PRIMA PARTE PRIMA PROCESSORE SCALARE ARCHITETTURA INTERA Pagina 7

8 SET DI ISTRUZIONI (processore di riferimento: MIPS64 ) Con una pluralità di dati che si possono trattare, si va a definire un SET DI ISTRUZIONI per un processore che usa questi dati. TIPI DI DATI: Floating point: sia in SINGLE PRECISION che DOUBLE PRECISION, trattandosi di dati a 32 bit e a 64 bit; Interi: in profondità di 8, 16, 32, 64, bit e per questi numeri varrà la possibilità di averli o senza segno (UNSIGNED) oppure con segno (SIGNED); Quindi definiti i tipi di dati con cui il processore deve lavorare, vediamo quali sono le istruzioni che su questi dati userà il processore. Si è deciso che il processore deve lavorare su questi dati perché, dopo aver fatto un po di conti dei transistor a disposizione in un chip, è possibile integrare un certo numero di unità di calcolo floating point a 32 o 64 bit e un ALU a che lavora con dati a 64 bit (essendo l ALU capace di lavorare con dati a 64 bit può anche lavorare con dati a profondità più bassa, opportunamente riempiendo i bit mancanti). Il processore di riferimento di questo corso è il MIPS64. Tutte le istruzioni che esegue il MIPS64 appartengono ad uno di questi gruppi: Istruzioni di calcolo; Istruzioni di accesso alla memoria; Istruzioni di controllo; Le istruzioni di calcolo si separano in due famiglie se il calcolo è intero (userò l ALU) oppure se il calcolo è floating point (userò le unità di calcolo floating point). ISTRUZIONI DI TRASFERIMENTO DEI DATI 1ª LETTERA: indica il tipo di operazione L indica un operazione di tipo load, MEMORIA PROCESSORE; S indica un operazione di tipo store, PROCESSORE MEMORIA. 2 ª LETTERA: indica il dato che viene trattato dall istruzione, quanti bit verranno trattati B indica byte, quindi una parola di 8 bit; H indica half (mezzo), quindi mezza parola ossia 16 bit (una parola è di 32 bit); W indica word, quindi una parola intera ossia 32 bit; D indica double, quindi una doppia parola ossia 64 bit. 3 ª LETTERA: indica se l operazione riguarda un dato UNSIGNED (NON È SEMPRE PRESENTE) U indica unsigned, quindi un operazione che riguarda un dato senza segno. Si osservi che nell operazione di STORE non è presente, per nessun dato da trattare, la lettera U, questo perché effettivamente l operazione è identica per entrambi i tipi di dati. Invece è necessaria specificarla nell operazione di LOAD (ma non in tutte). La necessità di specificare la terza lettera risale al momento della carica del dato; se questo è un dato binario o un dato con segno la carica deve essere fatta in maniera diversa. Pagina 8

9 Esempio - LOAD DI UN BYTE Questo processore ha i registri interi di 64 bit, quindi quando viene effettuata la LOAD di un byte dalla memoria sarà letta una parola di 8 bit che verrà scritta in un registro (che come detto è di 64 bit); quegli 8 bit verranno messi nella parte meno significativa del registro bit + 8bit = 64 bit I restanti 56 bit dovranno essere riempiti opportunamente; si è portati a pensare che questi 56 bit potranno essere riempiti con una sequenza di 0, però questo non è sempre vero. Si suppone che il numero letto è il numero -5; i numeri negativi vengono scritti utilizzando il complemento a 2, quindi: Complemento a Il numero ottenuto è -5 in binario (complemento a 2). Se invece fosse un numero assoluto, ossia senza segno, sarebbe = 251. Quindi gli stessi bit possono significare cose diverse a seconda che si consideri un numero binario con o senza segno. Non a caso se sommo 251 a 5 ottengo 256, cioè se lo leggo come numero intero o lo leggo in complemento a 2 quando poi vado a fare la somma del numero intero letto più il valore assoluto del numero in complemento a 2 ottengo sempre 256. Quindi nel momento della load bisogna sapere se il byte che si sta leggendo è con o senza segno, perché se è senza segno allora riempio i 56 bit con degli 0, altrimenti se è un numero che è scritto in complemento a 2 bisognerà riempirli non sempre con degli 0 ma con quello che è il bit di segno del numero stesso, quindi se è un numero con segno gli 8 bit saranno riempiti con il numero binario in complemento a 2 mentre i restanti 56 bit con la replica del bit di segno, quindi 1 nel caso esso sia negativo bit + 8bit = 64 bit Questa differenza fa si che le istruzioni per caricare un byte in un registro siano diverse. Identico discorso vale nel momento in cui vengono effettuate load di HALF WORD (16 bit) o di un WORD (32 bit). Nel caso della load di una DOUBLE WORD non vi è nessun problema poiché essa è già di 64 bit. Pagina 9

10 Esempio - STORE DI UN BYTE Quello che sta scritto negli altri 56 bit del registro non viene preso in considerazione; quindi vengono presi gli 8 bit meno significativi e vengono scritti in memoria. Per questo non è presenta la lettera U nell istruzioni di store. Identico discorso vale per le store di HALF WORD o di WORD. ALTRE ISTRUZIONI DI TRASFERIMENTO DEI DATI L.S indica un operazione di tipo load FLOATING POINT a SINGLE PRECISION (32 bit) L.D indica un operazione di tipo load FLOATING POINT a DOUBLE PRECISION (64 bit) La differenza è che una volta letti questi bit devono copiarsi non nei registri GPR (General Purpose) ma nei registri floating point, che sono simili elettronicamente ai GPR ma non sono collegati (in hardware) all ALU, che fa i calcoli in aritmetica intera, bensì alle unità di calcolo floating point. REGISTRI GPR ALU REGISTRI FLOATING POINT UNITA DI CALCOLO FLOATING POINT I vecchi processori a 32 bit utilizzavano registri GPR e flaoting point a 32 bit trattando questi ultimi nel seguente modo: essendo a 32 bit non creano nessun problema nelle istruzioni L.S, però quando si trovano ad operare con dati floating point double devono lavorare in coppia, cioè una parte del dato andrà in un registro e l altra in un altro, i quali devono essere adiacenti considerando come primo registro uno che abbia un numero pari; quindi un esempio di adiacenza è F0 F1 oppure F2 F3. Questo perché il dato floating point double sarà trattato in maniera tale che il primo registro associato terrà i bit che riguardano l esponente e una parte della mantissa, mentre l altro conterrà i restanti bit della mantissa; in particolare, nell istruzione, sarà necessario solamente indicare il registro pari in cui salvare il dato floating point double, poiché è sottointeso che verrà utilizzato anche il registro successivo. In questo corso considereremo però il MIPS64 che ha registri e bus a 64 bit. ISTRUZIONI DI TIPO M (MOV) Sono istruzioni che lavorano su dati che sono già all interno del processore. MFC0 indica un operazione di tipo copia dati dal registro GPR a un registro speciale; MTC0 indica un operazione di tipo copia dati da un registro speciale ad uno GPR; MOV.S indica un operazione di tipo copia dati da un registro in virgola mobile a singola precisione in un altro dello stesso tipo; MOV.D indica un operazione di tipo copia dati da un registro in virgola mobile a doppia precisione in un altro dello stesso tipo; Pagina 10

11 MFC1 indica un operazione di tipo copia dati da un registro GPR a un registro FLOATING POINT; MTC1 indica un operazione di tipo copia dati da un registro FLOATING POINT a un registro GPR. L utilità di queste ultime due istruzioni sta nel fatto che se durante l esecuzione i dati hanno riempito tutti i registri GPR e serve un registro per caricare un altro dato sarà possibile prendere un dato da un registro GPR e copiarlo in un registro floating point, in modo tale da far posto al nuovo dato. Attenzione il dato che andrà nel registro floating point non sarà assolutamente elaborato dall unità di elaborazione floating point, perché sarà un dato che non avrà nessun significato. ISTRUZIONI DI CALCOLO Queste istruzioni iniziano tutte con la lettera D a significare il trattamento di dati DOUBLE. Questo perché l ALU è progettata a 64 bit. Le altre tre lettere indicano il tipo di operazioni che si vuole fare; la lettera U indica che l operazione deve essere svolta su dati UNSIGNED, operazione che risulta diversa nei dati senza segno, ad esempio si considerino i casi di overflow, i quali sono segnalati da una parte del processore chiamata PSW (Process Status Word) che ha un bit che segnala l overflow. La lettera I indica che uno degli operandi è un IMMEDIATO, ossia un dato già noto nel momento in cui il compilatore scrive il programma eseguibile; si deduce che non è necessario salvare questo operando in un registro, ad esempio si considerino le istruzioni per implementare un ciclo for le quali hanno la variabile indice salvata in un registro a cui verrà sommato ogni volta un altro valore che però non è necessario salvare in un registro (il compilatore sa già che quel valore è 1). L immediato occupa 16 bit nell istruzione. Si noti che è assente la sottrazione con un immediato, questo è ovvio perché è possibile fare la somma con un immediato con segno meno. Vediamo un istruzione particolare: MADD indica un operazione di moltiplicazione somma, cioè è possibile in un'unica istruzione effettuare una moltiplicazione e una somma (ad esempio: x y + z). Chiaramente questa istruzione deve avere un unità dell ALU che operi direttamente su questa istruzione e che quindi cominci a fare la somma appena i bit del prodotto cominciano ad essere calcolati. Quindi l unità di calcolo che fa la MADD non esegue prima la moltiplicazione e poi la somma, perché altrimenti si avrebbe un ALU lenta quanto il tempo per fare una moltiplicazione e poi una somma. Poi ci sono le istruzioni per effettuare le operazioni logiche; in particolare istruzioni di AND si usano quando si vogliono fare operazioni di mascheramento, cioè quando si vogliono vedere solo alcuni bit di una parola; l operazione di mascheramento si ottiene creando una maschera da mettere in AND con la parola da mascherare, questa maschera permetterà di vedere solo alcuni bit del numero. Osserviamo ora la seguente istruzione: LUI indica un operazione che permette di caricare nella parte alta di un registro il valore di un immediato. La lettera U questa volta non indica unsigned ma sta per UPPER (superiore). Pagina 11

12 Infine analizziamo le istruzioni di scorrimento (shift) e le istruzioni d impostazione (set). ISTRUZIONI SHIFT Composte dalle lettere DS e poi da altre due lettere; lo shift può essere fatto a sinistra o a destra, troviamo per questo una L (left) o una R (right). Inoltre lo shift si caratterizza dal fatto che può essere sia di tipo logico sia di tipo aritmetico, indicando rispettivamente con le lettere L e A. Lo shift logico fa scorrere i bit in un verso e fa entrare degli zeri; lo shift aritmetico viene usato per fare calcoli aritmetici. In particolare per lo shift a destra è bene notare che esiste sia quello di tipo logico che quello di tipo aritmetico: lo shift logico sposta i bit della parola e fa entrare degli zeri, mentre lo shift aritmetico sposta la parola ed estende il bit di segno; per lo shift a sinistra, invece, si considera solo lo shift logico in quanto non essendoci estensione di segno entrano solo degli zeri. Infine può essere presente la lettera V la quale indica che lo shift avviene di un numero di posizioni variabile. ISTRUZIONI SET Sono istruzioni che vanno ad impostare un registro ad un valore minore di un certo altro valore; la prima lettera S sta per set, la seconda lettera L sta per less, la terza lettera T sta per than, infine potrebbero essere presenti altre lettere tra cui la I (immediate) e la U (unsigned). ISTRUZIONI DI CONTROLLO Sono istruzioni che consentono al programma di eseguire un flusso d istruzioni diverso da quello sequenziale, questo perché si potrebbe aver bisogno di dover saltare ad un altra istruzione. Si distinguono così due tipi di salti d istruzione: SALTO CONDIZIONATO: è un tipo di salto che viene effettuato nell esecuzione di un programma se la condizione da verificare è vera, altrimenti si prosegue con il normale svolgimento sequenziale del programma. Questo tipo di salto viene chiamato Branch, da qui l utilizzo della lettera B come prima lettera dell istruzione. SALTO INCONDIZIONATO: è un tipo di salto che viene effettuato nell esecuzione di un programma il quale deve andare ad eseguire un altra istruzione, la quale non è quella successiva, a prescindere da tutto. Questo tipo di salto viene chiamato Jump, da qui l utilizzo della lettera J come prima lettera dell istruzione. Pagina 12

13 Di seguito è riportata la tabella con un riepilogo di alcune le istruzioni qui sopra presentate più altre che costituiscono il sottoinsieme di istruzioni di MIPS64. Tipo di istruzione/codice Significato dell istruzione operativo Trasferimento di dati: trasferisce dati tra i registri e la memoria, oppure tra registri (di tipo intero, virgola mobile o speciale); l unica modalità di indirizzamento della memoria è quella con scostamento a 16 bit, cui sommare il contenuto di un GPR Logico/aritmetiche: operazioni su numeri interi o su dati di tipo logico contenuti in un GPR; gli overflow di operazioni aritmetiche su numeri con segno vengono segnalati Controllo: Salti condizionati e non condizionati; relativi al PC o usando un registro LB, LBU, SB LH, LHU, SH LW, LWU, SW LD, SD L.S, L.D, S.S, S.D MFC0, MTC0 MOV.S, MOV.D MFC1, MTC1 DADD, DADDI, DADDU, DADDIU DSUB, DSUBU DMUL, DMULU, DDIV, DDIVU, MADD AND, ANDI OR, ORI, XOR, XORI LUI DSSL, DSRL, DSRA, DSLLV, DSRLV, DSRAV SLT, SLTI, SLTU, SLTIU BEQZ, BNEZ BEQ,BNE BGTZ, BLTZ BGEZ, BLEZ BC1T,BC1F MOVN, MOVZ J, JR TRAP ERET Carica un byte, carica un byte senza segno, memorizza un byte (da/in registri per interi) Carica mezza parola, carica mezza parola senza segno, memorizza mezza parola (da/in registri per interi) Carica una parola, carica una parola senza segno, memorizza una parola (da/in registri per interi) Carica una doppia parola, memorizza una doppia parola (da/in registri per interi) Carica un SP, carica un DP, memorizza un SP, memorizza un DP Copia da/a un GPR a/da un registro speciale Copia da un registro in virgola mobile a singola o doppia precisione a un altro registro dello stesso tipo Copia da 32 bit in/da registri in virgola mobile da/in registri interi Addiziona, addiziona un valore immediato (tutti i valori immediati sono a 16 bit); con segno e senza segno Sottrai; con segno e senza segno Moltiplica e dividi; con segno e senza segno; moltiplica-e-addiziona; tutte le operazioni richiedono e producono valori a 64 bit Esegui AND, esegui AND con un dato immediato Esegui OR, esegui OR con un dato immediato; esegui OR esclusivo, esegui or esclusivo con un dato immediato Carica nella parte alta un valore immediato, cioè scrivi un valore immediato nei bit da 32 a 47 di un registro, poi estendi il segno Scorri; sia in modo immediato (DS ) sia in forma variabile (DS V); gli scorrimenti sono logico verso sinistra, logico verso destra, aritmetico verso destra Imposta un valore inferiore a, omposta un valore inferiore ad un valore immediato; con segno e senza segno Salta se un GPR è/non-è uguale a zero; scostamento di 16 bit da PC+4 Salta se i GPR sono/non-sono uguali; scostamento di 16 bit da PC+4 Salta se un GPR è maggiore/minore a zero; scostamento di 16 bit da PC+4 Salta se un GPR è maggiore/minore o uguale a zero; scostamento di 16 bit da PC+4 Verifica il bit di confronto nel registro di stato per le operazioni in virgola mobile e salta; scostamento di 16 bit da PC+4 Copia un GPR in un altro GPR se il terzo GPR è negativo, se è zero Salta incondizionatamente; scostamento di 26 bit da PC+4 (J) oppure destinazione in un registro (JR) Trasferisce il controllo al sistema operativo a un indirizzo vettorizzato Torna al codice utente da un gestore di eccezione; ripristina la modalità utente Il SET-ISTRUZIONI completo del MIPS64 è disponibile al seguente link: Pagina 13

14 ESECUZIONE DELLE ISTRUZIONI ALL INTERNO DEL PROCESSORE STRUTTURA DEL PROCESSORE FORMATO DELLE ISTRUZIONI Come già detto c è la possibilità di avere un formato di istruzioni a lunghezza variabile e un formato a lunghezza costante. Il caso che interessa è quello a formato di istruzioni a lunghezza costante e quelle che operano in virgola fissa; le istruzioni di questo tipo sono tutte quelle mancanti del punto e sono tutte codificate in un formato a 32 bit. 6 bit dedicati al codice operativo; un numero preciso di bit che riguardano l istruzione e quindi dipendono dal suo tipo: o Istruzione di tipo R, cioè quell istruzione che richiede operandi che sono dei registri e quindi sono istruzioni che codificano operazioni ALU in cui sia il primo sorgente che il secondo sorgente ed il destinazione sono un registro; in questo caso dovendo specificare tre registri, ciascuno di questi richiede un numero di bit pari a log 2 n dove n è il numero dei registri che il processore possiede (in questo caso sono 32 e quindi ogni registro richiede 5 bit); segue che dopo i 6 bit del c.o. ci sono tre campi ciascuno da 5 bit; ci sono dei campi aggiuntivi che vengono usati per estensioni del tipo di operazione da fare. o Istruzione di tipo I, cioè quell istruzione che richiede un immediato e quindi non è necessario l utilizzo di un registro per la memorizzazione del valore dell immediato (è noto dentro l istruzione); sia avrà: un registro sorgente, un registro destinazione e un immediato di 16 bit; quando poi verrà effettuato il calcolo fra il registro sorgente e l immediato, quest ultimo verrà esteso a 32 bit (i 16 bit verranno copiati dall istruzione e verranno messi in ingresso all ALU solo dopo averlo espanso a 32 bit, aggiungendo per 16 volte il bit di segno). Questo tipo di istruzione viene utilizzata anche per quelle di tipo BRANCH, la quale richiede un immediato per effettuare un salto condizionato, il quale si verifica indicando l indirizzo dove saltare. Sappiamo però che l indirizzo è di 32 bit e quindi non posso avere un indirizzo nell istruzione, per cui si avrà un salto che sarà sempre relativo al program counter (PC) e quindi si avrà un registro che indicherà la condizione e il valore, che una volta esteso a 32 bit dovrà sommarsi al PC. o Istruzione di tipo Jump, cioè quell istruzione che richiede un immediato per effettuare un salto incondizionato, ma non richiede di specificare la condizione; in questo caso l istruzione, non dovendo specificare nessun operando, ha a disposizione tutti i restanti 26 bit per indicare dove saltare, questi bit sempre relativi al PC. Quando il processore carica un istruzione non sa che tipo di istruzione è e quindi cosa contiene, per cui vedremo che una volta caricata l istruzione, andando a leggere i 6 bit del codice operativo, la control unit saprà come interpretare i restanti 26 bit. Pagina 14

15 CODIFICA DELL ISTRUZIONE PER UN PROCESSORE NO-PIPELINE Qualsiasi istruzione inizia la sua esecuzione nello stesso modo, perché è chiaro che il processore nell eseguire un istruzione non conoscendone ancora il tipo deve comportarsi con tutte allo stesso modo. Quindi le prime operazioni non dipenderanno dal tipo dell istruzione; successivamente una volta che il processore avrà compreso quella che è la particolarità dell istruzione che sta processando, eseguirà delle operazioni a seconda che l istruzione è di tipo ALU, LOAD/STORE oppure di DIRAMAZIONE. Il processore ogni volta che esegue un istruzione lo fa eseguendo un programma, definito come microprogramma; questo microprogramma è costituito da una serie di microistruzioni. Il microprogramma è scritto in una micro memoria; in questa micro memoria sono quindi scritte tutti i passi del microprogramma se la control unit, la quale si preoccupa di comandare la parte di calcolo del processore, è stata realizzata con tecnologia MICROPROGRAMMATA. Possiamo immaginare la control unit come un dispositivo che colpo di clock dopo colpo di clock produce delle uscite che servono ad esempio all ALU, al banco dei registri o alla memoria per fargli compiere delle operazioni. La control unit è realizzabile utilizzando due diverse tecnologie: MICROPROGRAMMATA: ha al suo interno una struttura analoga al processore che esegue dei microprogrammi. Lo svantaggio di questa tecnologia è che è lenta perché deve accedere ogni volta alla memoria; il vantaggio è che aggiungendo funzionalità al processore non bisognerà sostituire la control unit, ma bisognerà soltanto aggiungere altre microistruzioni alla micro memoria. CABLATA: costituita da un circuito digitale, pensata come una macchina a stati, cioè un circuito sequenziale, costituito da flip-flop e porte logiche, con memoria che produce le uscite non solo come funzione degli ingressi ma anche come funzione delle uscite agli istanti precedenti. Il vantaggio di questa tecnologia è che la control unit è più veloce rispetto ad unità di controllo basata su microprogrammi; lo svantaggio è che se si va a modificare il processore, ad esempio in caso di upgrade, bisognerà cambiare completamente la control unit e riprogettarla per adattarla al nuovo processore. Pagina 15

16 STRUTTURA DEL PROCESSORE NO-PIPELINE Vediamo ora come un istruzione viene eseguita all interno di un processore NO-PIPELINE. Di seguito è riportato lo schema del processore. Nelle pagine successive verranno analizzati i singoli passaggi per i seguenti tipi di istruzioni: Memory Reference (LOAD/STORE); Register-Register ALU operation; Register-Immediate ALU operation; Branch. COMPONENTI DEL PROCESSORE REGISTRI - PC: Program Counter, registro speciale che contiene l indirizzo della memoria in cui il processore troverà l istruzione da eseguire; - IR: Istruction Register, registro contenente l istruzione correntemente in esecuzione; - REGISTERS - GPR: General Purpose, registri generali indicati con una numerazione progressiva (R0, R1, ), usati per contenere gli operandi e i risultati parziali durante l esecuzione delle istruzioni; - A e B: registri temporanei - IMM: Immediate, registro temporaneo per memorizzare l immediato esteso di segno; - ALU OUTPUT: registro di output dell ALU; - LMD: acronimo di Load Memory Data, registro in cui si memorizza il dato in uscita dalla Data Memory; - COND: registro flag di 1 bit per verificare il risultato della condizione. MEMORIE (CACHE DI 1 LIVELLO) - INSTRUCTION MEMORY: memoria contenente le istruzioni da eseguire; - DATA MEMORY: memoria contenente i dati su cui verranno effettuate le operazioni. Pagina 16

17 ALTRI COMPONENTI - ALU: Arithmetic Logic Unit, si occupa di eseguire le operazioni di tipo aritmetico/logico. - MUX: Multiplexer, dispositivo capace di selezionare un singolo segnale elettrico fra diversi segnali d ingresso in base ad un valore specifico determinato dal segnale di controllo. - SIGN EXT: modulo di estensione del segno. - ADD: modulo sommatore. DESCRIZIONE DETTAGLIATA DI OGNI PASSAGGIO 1^ FASE IF INSTRUCTION FETCH Dopo aver dato all Instruction Memory il contenuto di PC, questa scarica l istruzione generata nell Instruction Register (IR). Contemporaneamente il PC va in ingresso al modulo sommatore (ADD) che riceve come altro ingresso un valore costante pari a 4 (4 byte 32 bit istruzione successiva); il risultato salvato in NPC (New PC) sarà il nuovo valore del PC. Tutto questo vale se nell Instruction Memory è presente l istruzione, altrimenti si va in stallo (in attesa). In sintesi: IR MEM[PC] NPC PC + 4 2^ FASE ID INSTRUCTION DECODE Ora che l istruzione è nell IR, quindi è all interno del processore, viene effettuata la sua decodifica e in contemporanea il processore esegue la precarica dei coefficienti, ossia il prelievo dei bit dall istruzioni che si potrebbero riferire agli operandi e il salvataggio di essi nei GPR; i registri che possibilmente contengono gli operandi saranno messi in registri temporanei A e B, pronti per essere processati dall ALU, mentre l operando che potrebbe indicare il registro destinazione verrà esteso in segno (portato a 32 bit) e conservato nel registro temporaneo IMM (trattarlo come un immediato non comporta nessun problema). Al termine della decodifica il processore saprà il tipo dell istruzione da eseguire e quindi sapere se i 16 bit si riferivano ad un registro destinazione o ad un immediato e se i registri A e B contengono gli operandi o semplici indirizzi. In sintesi: A Regs[IR ] B Regs[IR ] Imm ((IR 16 ) 16 ##IR ) Pagina 17

18 3^ FASE EX EXECUTION L ALU opererà su tutti gli operandi preparati nella fase di decode, effettuando una delle quattro funzioni a seconda del tipo d istruzione: Memory Reference (LOAD/STORE) I MUX passano all ALU il valore del registro A e il valore del registro IMM; l ALU li somma per formare l indirizzo effettivo della memoria. Il risultato viene inserito nel registro ALU OUTPUT; In sintesi: ALUOUTPUT A + IMM Register-Register ALU instruction I MUX passano all ALU il valore del registro A e il valore del registro B; l ALU esegue l operazione specificata dal codice operativo. Il risultato viene inserito nel registro ALU OUTPUT; In sintesi: ALUOUTPUT A op B Register-Immediate ALU instruction I MUX passano all ALU il valore del registro A e il valore del registro IMM; l ALU esegue l operazione specificata dal codice operativo. Il risultato viene inserito nel registro ALU OUTPUT. In sintesi: ALUOUTPUT A op IMM Pagina 18

19 Branch I MUX passano all ALU il valore dell NPC e il valore del registro IMM; l ALU li somma per calcolare l indirizzo della destinazione del salto. Il risultato viene inserito nel registro ALU OUTPUT. Il valore di A viene utilizzato per determinare se il salto viene effettuato; l operazione di confronto dipende dal codice operativo dell istruzione di branch (ad esempio può essere l istruzione di BEQZ). In sintesi: ALUOUTPUT NPC + IMM Cond ( A op 0 ) 4^ FASE MEM MEMORY ACCESS Le uniche istruzioni attive in questa fase sono quelle LOAD, STORE e BRANCH Memory Reference (LOAD) Con l indirizzo calcolato durante la fase precedente e memorizzato nel registro ALUOUTPUT, si accede alla DATA MEMORY. La Data Memory restituisce il dato richiesto che si memorizza nel registro LMD. In sintesi: LMD Mem[ALUOUTPUT] Memory Reference (STORE) Con l indirizzo calcolato durante la fase precedente e memorizzato nel registro ALUOUTPUT, si accede alla DATA MEMORY. Il dato del registro B viene scritto nella Data Memory a quell indirizzo. In sintesi: Mem[ALUOUTPUT] B Pagina 19

20 Branch Se la condizione è verificata, il segnale proveniente dal registro flag COND fa da controllo, allora il PC viene aggiornato con il valore calcolato nella fase precedente e memorizzato nel registro ALUOUTPUT. In caso contrario il PC verrà aggiornato con il valore del registro NPC. In sintesi: if (cond) PC ALUOutput else PC NPC 5^ FASE WB WRITE BACK Register-Register/Immediate ALU instruction Il MUX passerà al banco dei registri GPR il valore del registro ALUOUTPUT. Questo valore andrà a salvarsi nel registro identificato dal terzo operando. Lo stesso discorso vale per le istruzioni Register Immediate. Load instruction Il MUX passerà al banco dei registri GPR il valore del registro LMD. Questo valore andrà a salvarsi nel registro identificato dall operando. Pagina 20

21 Tutto quanto spiegato funziona nell ipotesi che il processore esegue un istruzione per volta (NO-PIPELINE); si noti che durante l esecuzione dell istruzione si attraversa il processore a fette, come se fosse un tubo, tralasciando le operazioni effettuate e che quindi non servono più. Quindi l idea è quella di immaginare il processore come un tubo diviso in stadi, da qui PIPELINE; quando un istruzione entra, esegue le sue operazioni nel primo stadio e poi passa al secondo, posso far entrare una nuova istruzione. Questo significa eseguire un istruzione in un tempo approssimativamente più piccolo; quindi è necessario modificare il processore avendo fra uno stadio ed un altro una serie di banchi che eseguiranno delle specifiche operazioni. Per concludere viene riportato uno schema per ogni tipo d istruzione. Riepilogo ISTRUZIONE LOAD ISTRUZIONE ALU GPR op GPR Pagina 21

22 ISTRUZIONE ALU GPR op IMM ISTRUZIONE STORE ISTRUZIONE BRANCH Pagina 22

23 TECNICA PIPELINE TEMPO DI ESECUZIONE DI UN PROGRAMA La PIPELINE sfrutta la seguente osservazione: quando un istruzione viene eseguita, attraversando il processore a fette, lasciando alle sue spalle parti di esso che l ha elaborata; per cui si potrebbero usare queste parti per eseguire un altra istruzione. Prima di entrare nello specifico della PIPELINE vediamo se effettivamente questa struttura è conveniente; supponiamo che un istruzione per essere eseguita da un processore richieda un tempo T, definito tempo medio. Se un programma ha N istruzioni la sua esecuzione richiederà un tempo pari a N T, dove N non è un numero di istruzioni statico (cioè quelle che compongono il listato) ma bensì dinamico, cioè quelle che effettivamente vengono eseguite. Potendo implementare una struttura a pipeline possiamo far sì che la seconda istruzione inizi la sua esecuzione quando la prima istruzione libera la prima parte di processore. Si osservi il seguente grafico: La prima istruzione dura 5 colpi di clock (CC) T = 5 CC; la seconda istruzione invece di partire al colpo di clock 6, quando è terminata la prima istruzione, inizia al colpo di clock 2, questo è possibile perché al CC 2 la prima istruzione ha liberato la parte di processore che accede alla IM (Instruction Memory). Anche la seconda durerà 5 CC. Invece di durare un tempo pari a N T, il programma durerà: T + N 1 t T: tempo di esecuzione della prima istruzione (in questo caso 5 CC) t: tempo di una fase singola (in questo caso 1 CC), contare per N-1 volte. In generale vale: t = T oppure T nl pp nl: numero di livelli pipeline (in questo caso 5 livelli). pp: profondità della pipeline, per profondità si intende il numero d istruzione contemporaneamente dentro alla pipeline. Queste ultime due grandezze coincidono, ma concettualmente sono due cose diverse. Pagina 23

24 Quindi: T + N 1 T nl NT = T + nl T nlt + NT T = = NT nl 1 T + nl nl nl nl con nl 1 T nl parametro trascurabile; Sul termine NT è possibile fare dei ragionamenti: nl si è partiti dal presupposto che t = T, il quale potrebbe essere vero soltanto se il tempo di esecuzione di nl un istruzione fosse diviso in nl parti di durata uguale (in questo caso la pipeline si dice perfettamente bilanciata), ma non è sempre possibile; si deduce che non è possibile imporre a piacere il valore di t. Quindi il grafico presentato funzionerebbe correttamente se ciascuna fase durasse il tempo della fase più lenta, che denominiamo T C ; in realtà si dovrà considerare che nella struttura del processore pipeline fra ogni passo c è un blocco (latch - grigio nel disegno della pagina seguente) necessario se il processore lavora su più istruzioni contemporaneamente, quindi bisogna considerare, oltre al tempo di lavoro netto per effettuare il preciso passo, il tempo di lettura e scrittura dei latch; quindi il tempo di una fase diventerà: t = T L + T C + T S T L : tempo di lettura del latch T C : tempo di calcolo della fase più lenta T S : tempo di scrittura del latch Generalmente si pensa la pipeline costituita da 5,6 o 7 stadi, ma è possibile pensare la pipeline in altri due modi: UNDER-PIPELINE: numero di stadi ridotto, inferiore a 5; t diventa più grande comportando la realizzazione di una CU più semplice. SUPER-PIPELINE: numero di stadi alto, maggiore di 7; t diventa più piccolo comportando la realizzazione di una CU più complessa. Ovviamente tutto questo detto fino ad ora si può considerare in una idealizzazione del funzionamento della pipeline; infatti bisogna considerare le situazioni in cui si perdono dei colpi di clock per effettuare determinate istruzioni. Si pensi alle istruzioni di branch: al primo CC arriva questo tipo di istruzione; al secondo CC per caricare l istruzione successiva bisogna conoscere qual è questa istruzione da eseguire. La prima istruzione deve calcolare l indirizzo per effettuare il salto e salvarlo nel PC, ma questo verrà effettuato in fasi successive quando l ALU effettuerà le sue operazioni. Per cui partiranno altre istruzioni, ma solamente nel momento in cui verrà aggiornato il PC verrà eseguita la giusta istruzione; le istruzioni partite saranno bloccate con conseguente perdita di tempo. Per cui bisognerà aggiungere al calcolo del tempo i colpi di clock sprecati. Pagina 24

25 ESEMPIO La prima è un istruzione di tipo R di somma fra i registri R2 e R3 con registro destinazione R1; Regs R1 Regs[R2] + Regs[R3] La seconda istruzione richiede di usare il registro R1 con il registro R5 per fare una differenza e scrivere il risultato nel registro destinazione R4; Regs R4 Regs R1 Regs[R5] È evidente che R1 non è ancora disponibile o meglio sono solo presenti dei bit che non hanno significato; quindi la CU dovrà in qualche modo bloccare l istruzione per poi farla ripartire quando R1 sarà disponibile. Questo comporta una perdita di colpi di clock. In seguito vedremo opportune soluzioni per risolvere questi problemi. L obiettivo per cui è stato mostrato questo esempio è quello di far comprendere che il tempo per eseguire un programma dipende quindi da molti fattori. Pagina 25

26 STRUTTURA DEL PROCESSORE PIPELINE Di seguito è riportato lo schema del processore. Fondamentalmente rispetto al processore NO-PIPELINE ci sono delle grosse differenze: nel processore NO-PIPELINE sono presenti vari registri temporanei come i registri IR, A, B, IMM, ALUOUTPUT, ecc; mentre nel processore PIPELINE questi registri sono stati inseriti nei latch (blocchi grigi). Questa scelta è dovuto al fatto che questo processore esegue più istruzioni per volta; se per esempio un istruzione si trova nell ultima fase quella di WB, il MUX vedendo il codice operativo dell IR sa quale dato far andare nel banco dei registri. Nel caso di un processore no-pipeline non vi erano problemi perché l IR manteneva l informazione per tutta la durata dell esecuzione dell istruzione; nel processore pipeline ogni latch contiene il valore del registro IR che ogni colpo di clock si copia nel latch successivo, questo perché con l arrivo di una nuova istruzione l IR viene modificato, per cui si avrebbe una perdita di dati. Quindi tornado all esempio, in cui l istruzione si trova nella fase di WB, il MUX preleverà il valore del registro IR dal latch che lo precede. Si noti inoltre il MUX che si trova dopo l ADD tra il PC e 4. Rispetto al no-pipeline si trova avanti perché è importante che il PC sia aggiornato mentre l istruzione termina la prima fase, per far si che si possa prelevare la prossima istruzione. Quindi ci sono alcuni registri che sono propagati latch per latch, chiamati sempre allo stesso modo del nopipeline, però per effettuare l accesso bisogna specificare a quale latch ci si riferisce; ad esempio IF/ID.IR per indicare il registro IR che si trova nel latch IF/ID. Pagina 26

27 Di seguito sono riportati gli eventi di ciascuno stadio della pipeline di MIPS. IF/ID.NPC PC+4; IF/ID.PC (if ((EX/MEM.opcode == branch) (EX/MEM.opcode == jump) & EX/MEM.cond) {EX/MEM.ALUOutput} else {PC+4}); Se l istruzione è una BEQZ allora: EX/MEM.cond (if (ID/EX.A == 0) {1}); Se l istruzione è una BNEZ allora: EX/MEM.cond (if (ID/EX.A!= 0) {1}); Bisogna considerare anche i casi in cui l istruzione è una BNQ o una BNE; Vediamo quali azioni dei vari stadi sono caratteristiche dell organizzazione della pipeline. Nello stadio IF, oltre a reperire l istruzione e calcolare il nuovo valore di PC, memorizziamo tale nuovo valore sia in PC sia in un registro di pipeline (NPC) per poterlo usare eventualmente in seguito per il calcolo dell indirizzo di destinazione di un salto. Nello stadio ID reperiamo i registri, estendiamo il segno dei 16 bit meno significativi di IR e trasferiamo allo stadio successivo i valori di IR e NPC. Nello stadio EX eseguiamo un operazione nella ALU oppure calcoliamo un indirizzo, trasferendo allo stadio successivo il contenuto dei registri IR e B (se si tratta di un istruzione store); inoltre, se l istruzione è una diramazione e il salto viene effettuato, poniamo uguale a 1 il valore di cond. Nello stadio MEM eseguiamo le azioni riguardanti la memoria, se richiesto scriviamo il registro PC e trasferiamo allo stadio finale i valori che sono ad esso necessari. Infine, nello stadio WB aggiorniamo l opportuno registro, in base al valore calcolato dalla ALU o letto dall istruzione load. Per semplicità trasferiamo sempre l intero IR da uno stadio all altro, anche se, al procedere dell istruzione all interno della pipeline, è necessaria una porzione sempre più piccola di tale informazione. Bisogna tener sempre presente che ogni stadio è sempre operativo per un istruzione diversa, per cui le operazioni avvengono in contemporanea, però c è una tempistica che evita la sovrascrittura dei registri. Pagina 27

28 Ricapitolando, si è visto come questo processore così strutturato può eseguire più istruzioni contemporaneamente e come, quindi, alcune risorse devono essere replicate; idealmente si avrà l esecuzione di un istruzione in un numero di fasi costante ma in realtà questo non sarà vero perché alcune istruzioni o saranno avviate inutilmente oppure dovranno essere bloccate in attesa di un informazione che deve essere prodotta dalle istruzioni precedenti. Si parla quindi di ALEE del processore che possono essere: ALEE DI DATO: un istruzione viene bloccata perché aspetta la disponibilità di un dato. ALEE STRUTTURALI: un istruzione viene bloccata perché aspetta la disponibilità dei componenti del processore. ALEE DI CONTROLLO: un istruzione viene bloccata perché aspetta la modifica del PC, in casi diramazione o salti Pagina 28

29 BREVE CENNO SULLE MEMORIE DEL PROCESSORE (CACHE DI 1 LIVELLO) ACCESSO ALLA MEMORIA Nel processore ci sono due memorie cache di 1 livello distinte perché si ha bisogno di un unità su cui scrivere e leggere le istruzioni e un unità su cui scrivere e leggere i dati; devono essere distinte per evitare un alea strutturale gravissima, che comporterebbe uno spreco di colpi di clock. Questo idea di organizzazione è definita come architettura Harvard. Successivamente affronteremo la trattazione della memoria; ora ci soffermiamo su un singolo aspetto che è quello dell ACCESSO ALLA MEMORIA. La memoria è pensata in questa maniera: PORTA INDIRIZZO PORTA DATI PORTA D INGRESSO PORTA DI USCITA LOAD: Viene inviato un indirizzo alla porta indirizzo fatto da un certo numero di bit e all interno individuerò una parola, fra 2 n parole, che uscirà fuori dalla porta dati. STORE: Viene inviato un indirizzo e un dato alla porta d ingresso, l indirizzo individuerà la locazione su cui andrà a scrivere il dato. Un requisito della memoria è la profondità di parola: cioè la parola in uscita avrà una certa quantità di byte che sarà un potenza di 2 (per esempio 32 o 64 bit). Supponiamo che i dati siano di 4 byte (32 bit), focalizziamo l attenzione sul seguente tipo di accesso alla memoria: ACCESSO ALLINEATO: i 4 byte verranno scritti/letti in posizioni che sono rigidamente fisse, in questa maniera: Se si vuole leggere una parola che parte ad esempio dal byte 2 al byte 5 non è possibile farlo. Quindi l indirizzo che la memoria riceve e che poi conterrà il dato che manderà in uscita è multiplo dell unità su cui è allineata la memoria. Ad esempio se è allineata a 4 byte l indirizzo sarà multiplo di 4. Quindi non è possibile accedere in maniera casuale. Questo tipo di accesso semplifica notevolmente la gestione del lavoro e della circuiteria interna della memoria. Si parla di allineamento 4 byte intendendo che un indirizzo avrà gli ultimi due bit nulli: 16 bit punteranno ad una riga altri 16 ad una colonna; la cella di memoria corrispondente potrà andare in uscita o ricevere un dato. Bisogna comunque garantire che se per errore si dovesse accedere ad un dato che non è allineato, in qualche modo bisognerà saperlo leggere. Pagina 29

30 Ad esempio si supponga la seguente situazione di LOAD: L O C U 4 byte 4 byte La parola LOCU non potrà essere letta perché l indirizzo non avrà gli ultimi due bit uguali a zero, ma solo l ultimo. Per leggere la parola devo: 1. LOAD dei primi 4 byte; 2. LOAD dei successivi 4 byte; 3. SHIFT di 16 bit dei primi 4 byte; 4. SHIFT di 16 bit dei successivi 4 byte; 5. operazione di OR per ottenere la parola LOCU. Si supponga ora la seguente situazione di STORE: Si vuole scrivere la parola LOCU a partire dall indirizzo 15; non si deve però andare a modificare il contenuto degli altri indirizzi e R p L O C U h 4 byte 4 byte Per scrivere devo: 1. LOAD dei primi 4 byte, quindi a partire dall indirizzo 12; 2. LOAD dei successivi 4 byte, quindi a partire dall indirizzo 16; 3. STORE a partire dall indirizzo 12, dei 4 byte modificati; 4. STORE a partire dall indirizzo 16, dei successivi 4 byte modificati. Pagina 30

31 ALEE STRUTTURALI ALEE DI DATO Abbiamo visto, con il concetto di ALEE STRUTTURALI e ALEE DI DATO, che in realtà il processore stesso ha comportamenti che lo allontanano da quelli ideali. ALEE STRUTTURALE: un istruzione viene bloccata perché aspetta la disponibilità dei componenti del processore. Si osservi la figura qui accanto; nel caso il processore non abbia una memoria separata per le istruzioni e per i dati si incorre in un blocco strutturale poiché l istruzione 3 non può utilizzare il componente memoria; quindi questa istruzione, così come tutte quelle seguenti, verrà ritardata di un colpo di clock. La soluzione a questo tipo di problema è l utilizzo di un architettura Harvard. ALEE DI DATO: un istruzione viene bloccata perché aspetta la disponibilità di un dato. Esistono conflitti di dati che teoricamente possono essere di quattro tipi: 1. READ AFTER WRITE (RAW): generato da dipendenze di dato tra istruzioni sequenziali vicine, cioè un istruzione tenta di leggere un registro prima che sia stato scritto; nel processore intero, grazie alla corto circuitazione dell ALU questo problema non esiste a meno del caso delle istruzioni di load. Nell aritmetica floating point questo conflitto è molto rilevante. DADD R0, R1, R2; DSUB R2, R0, R3; // Write R0 // Read R0 2. WRITE AFTER WRITE (WAW): si ha quando il valore di un registro viene aggiornato prima dall'istruzione più recente e poi da quella meno recente. Quindi, la seconda scrittura va persa. In un processore di tipo intero questo problema non esiste perché quando un istruzione è nella fase di WB tutte le istruzioni precedenti sono terminate, ed essendo terminate hanno già fatto la fase di WB. Nell aritmetica floating point questo conflitto è molto rilevante. DADD R1, R0, R2;... DSUB R1, R2, R3; // Write R1 // Write R1 3. WRITE AFTER READ (WAR): un istruzione tenta di scrivere un registro prima che sia stato letto; nel processore intero questo problema non esiste perché quando l istruzione è nella fase di WB tutte le altre saranno terminate e quindi tutto procederà correttamente. Nell aritmetica floating point questo conflitto è molto rilevante. DADD R0, R1, R2; DSUB R1, R2, R3 // Read R1 // Write R1 Pagina 31

32 4. READ AFTER READ (RAR): non è una dipendenza. È possibile anche invertire l ordine di esecuzione. Di seguito sono riportati tre casi in base alle istruzioni schedulate. 1. ISTRUZIONI ALU: si osservi la figura qui accanto; il registro destinazione (R1) della prima istruzione (DADD) è un registro sorgente per la seconda istruzione (DSUB) ma anche per la terza istruzione (AND). R1 ospiterà effettivamente la somma fra R2 e R3 nel quinto colpo di clock; essendo il programma eseguito in pipeline, la seconda istruzione porterà nel quarto colpo di clock in ingresso all ALU dei bit che non avranno nessun significato. Lo stesso vale per le altre istruzioni; solo l ultima istruzione effettuerà regolarmente la sua operazione, poiché sarà stata effettuata la Write Back. Verrà analizzata ora una tecnica per evitare questo tipo di blocco: si consideri la quarta istruzione che parte tre colpi di clock dopo la prima istruzione: R1 viene scritto nel quinto colpo di clock (fase di WB). In questa fase per l istruzione OR, R1 verrà preso è messo nel registro A; bisognerà capire se R1 che andrò a scrivere in A è quello che è stato scritto dalla fase di WB. Poiché prima avvengono le letture e poi le scritture, in realtà non avrò l effettivo valore di R1. Si esamini la profondità della pipeline al quinto colpo di clock, e le fasi che la costituiscono: tutte le fasi dureranno quanto la fase più lenta, che è quella di accesso alla memoria. La fase di WB è estremamente veloce (legge ALUOutput oppure LMD e scrive in un registro); bisognerà comunque eseguire WB in un tempo che è comunque legato alla durata della fase più lenta: per cui se viene garantita una tempistica che esegue la fase WB nella prima metà del colpo di clock e la fase di carica dei coefficienti A e B nella seconda metà, l istruzione non darà nessun problema di esecuzione. Pagina 32

33 Risolta l alea con la quarta istruzione schedulata, vediamo come risolvere il problema legato alle istruzioni schedulate nel secondo e terzo colpo di clock. In realtà per la seconda istruzione non serve che il risultato della somma fra R2 e R3 venga letto direttamente dal registro R1, cioè interessa sottrarre a R5 la somma precedente che sarà possibile trovare in EX/MEM.ALUOutput. Stesso discorso vale per la terza istruzione: il valore della somma lo troverà in MEM/WB.ALUOutput. Utilizzando questo metodo il processore cambia la sua struttura, dove in ingresso ai MUX, che decidono quale segnale mandare all ALU, non si hanno soltanto i registri A e B oppure IMM ma si ha la possibilità di ricevere EX/MEM.ALUOutput oppure anche MEM/WB.ALUOutput. In questo modo non si avranno perdite di colpi di clock e quindi nessun blocco d istruzioni. La Control Unit sarà un po più complessa perché dovrà controllare i MUX e questo viene fatto attraverso una logica che si basa sui comparatori, il cui compito è quello di confrontare i registri. Sono presenti due comparatori per ogni MUX. Nel caso l istruzione è a un colpo di clock dopo, all ingresso del comparatore si ha: 1. il campo *rs+ dell IR dell istruzione che sta in fase di EX; 2. il campo *rd+ dell IR dell istruzione che sta in fase di MEM. Quindi il MUX, all ingresso dell ALU, farà passare EX/MEM.ALUOutput se sono uguali i valori ed è verificato il codice operativo. Pagina 33

34 Nel caso l istruzione è a due colpi di clock dopo, all ingresso del comparatore si ha: 1. il campo *rs+ dell IR dell istruzione che sta in fase di EX; 2. il campo *rd+ dell IR dell istruzione che sta in fase di WB. Quindi il MUX, all ingresso dell ALU, farà passare MEM/WB.ALUOutput se sono uguali i valori ed è verificato il codice operativo. Identico discorso vale per il secondo MUX a patto che si consideri il campo rt dell IR e non rs. Se entrambi i comparatori verificano l uguaglianza dovrà essere dato in ingresso all ALU il risultato della seconda operazione, cioè quella che è ancora fra EX/MEM e quindi il primo caso. All interno di questa logica vi è anche una rete combinatoria che effettua il test sul codice operativo; questo perché il risultato della comparazione è interessante solo se si sta considerando un istruzione ALU in cui i bit che si riferiscono al campo rd sono proprio i bit destinatari del risultato dell operazione ALU. L uscita di questa rete combinatoria di test è in AND con il comparatore per verificare se considerare o meno il risultato del comparatore. Pagina 34

35 2. ISTRUZIONI LOAD: si osservi ora il caso in cui un registro è destinazione di un operazione di tipo LOAD. LD R1,0(R2) DSUB R4,R1,R5 AND R6,R1,R7 Essendo R1 risultato di un operazione di LOAD il valore (che andrà in R1) sarà noto solo dopo la fase di MEM è quindi sarà presente nel latch MEM/WB.LMD; dal punto di vista temporale questa operazione avviene successivamente rispetto a quando la seconda istruzione si trova nella fase di EX; in questo caso il processore andrà in stallo fermando così tutte le istruzioni successive che richiederanno quel dato. (ved. fig. sotto). Invece se l istruzione è schedulata due colpi di clock dopo, e in ingresso all ALU si vuole il valore di R1, si andrà a prendere questo valore da MEM/WB.LMD; questo è il terzo ingresso retro azionato che arriva al MUX. Occorrerà un altro comparatore (per ogni MUX) che prenderà il registro sorgente dell istruzione corrente ID/EX.IR[rs] e lo confronterà con il registro destinazione dell istruzione due colpi di clock prima MEM/WB.IR*rd+. Il risultato sarà messo in AND con il segnale d uscita del circuito combinatorio che effettuerà il test su MEM/WB.IR*opcode+. Se si verificano i controlli in ingresso all ALU andrà MEM/WB.LMD. È possibile evitare lo stallo organizzando, a livello del compilatore, il codice del programma in maniera tale da non avere mai dopo una load un istruzione che vuole come sorgente il destinazione dell istruzione di load. Questa è altre tecniche software aiutano il compilatore; dal punto di vista hardware non ci sono soluzioni. Pagina 35

36 3. ISTRUZIONE BRANCH: se la condizione di salto si verifica (al termine della fase EX) le istruzioni che erano state avviate, poiché successive a quella di salto, devono essere abortite per poter proseguire con l istruzione ove si è saltati. Questo significa che si perderanno dei colpi di clock non per situazioni di stallo ma per aver eseguito istruzioni inutilmente; bisognerà cercare di ridurre al minimo questi colpi di clock sprecati. Solo alla quarta istruzione si conoscerà il valore del salto da effettuare e quindi può essere effettuata la fase di IF con il PC corretto. Questo significa che saranno stati persi tre colpi di clock, cioè un istruzione di salto è come se durasse quattro istruzioni. È possibile con una tecnica hardware ridurre i colpi di clock persi; l operazione di calcolo dell indirizzo in cui saltare è effettuato nella fase di EX poiché li è presente l ALU. Però si può accelerare questa operazione pensando di effettuare questo calcolo nella fase ID, perché in fondo per il calcolo serve lo spiazzamento e il PC, dati che in questa fase sono noti. Per effettuare il calcolo non bisogna dimenticare che è necessaria l ALU, la quale è utilizzata da un altra istruzione; però effettivamente non è necessaria un altra ALU ma un semplice sommatore. Quindi si inserisce un sommatore aggiuntivo nella fase ID che prende l immediato esteso in segno, prende il PC e li somma; se la condizione è verificata IF/ID.PC verrà aggiornato al valore calcolato. Il processore sarà così modificato in questi termini: Con questa tecnica si avrà la perdita di un colpo di clock invece di due (non considerando l istruzione di branch). Pagina 36

37 MIPS PIPELINE OTTIMIZZATO Pagina 37

38 DELAY SLOT TECNICA STATICA Si è visto come è possibile, aggiungendo un sommatore nella fase ID, conoscere se è dove saltare già alla seconda fase dell esecuzione dell istruzione di salto; quindi nel momento in cui l istruzione di salto si trova nella terza fase verrà caricata nella fase IF l istruzione con il PC aggiornato, questo significa che dal momento in cui è stata caricata l istruzione di salto al momento in cui viene caricata l istruzione a cui si è saltati, è stata caricata un istruzione puntata da PC+4 (quindi non l istruzione a cui si doveva saltare); questo significa aver perso un colpo di clock, definito DELAY SLOT; il delay slot è quindi il ritardo che si compie nell esecuzione di un programma, ritardo sotto forma di stalli e quindi colpi di clock persi. Questo ritardo deve essere ottimizzato nel modo migliore; le tecniche usate sono le seguenti: PRIMO CASO Si osservi questa situazione: vi è un istruzione di salto che controlla l uguaglianza a zero di R2 ed effettua un salto ad una certa istruzione. Per ottimizzare il clock perso il compilatore prende un istruzione indipendente proveniente dalla parte di codice precedente il salto e la mette subito dopo l istruzione di salto. Quindi viene schedulata un istruzione che va comunque eseguita (DADD R1,R2,R3); il compilatore codifica con un particolare codice operativo l istruzione schedulata per far si che anche se la condizione di salto si dovesse verificare deve essere comunque portata a termine. SECONDO CASO Si osservi questa situazione: vi è un istruzione di salto che controlla l uguaglianza a zero di R1 che è destinazione dell istruzione precedente. Questa situazione rende impossibile lo spostamento dell istruzione DADD R1,R2,R3 nel delay slot; quindi questo viene riempito con l istruzione destinazione del salto. Si noti che l istruzione deve essere copiata e non spostata per rendere possibile la prima iterazione; se il salto si verifica, l istruzione, che adesso si trova immediatamente dopo quella di salto, deve essere portata a termine. Questa strategia è usata quando il salto ha una probabilità di venire eseguito, come nel salto all interno di un ciclo. Se la condizione non si verifica l istruzione immediatamente dopo il salto deve essere abortita con conseguente perdita di un colpo di clock. Pagina 38

39 TERZO CASO Si osservi questa situazione in cui il salto non si verifica spesso, ad esempio il caso del confronto; il codice viene riorganizzato utilizzando istruzioni provenienti dalla sequenza relativa al caso di non esecuzione del salto. Perché l ottimizzazione mostrata sia accettabile bisogna che si possa eseguire l istruzione OR R7,R8,R9 quando il salto si comporta nel modo non previsto. Per accettabile si intende che il lavoro fatto divenga sì inutile, ma che il programma sia eseguito correttamente. Questo succede, ad esempio, se R7 è un registro temporaneo non utilizzato quando il salto si comporta nel modo non previsto. Se la condizione si verifica l istruzione immediatamente dopo il salto deve essere abortita. TECNICA SPECULATIVA TECNICA DINAMICA Vediamo ora una tecnica speculativa, definita previsione speculativa di salto, che cerca di indovinare mentre si effettua il fetch di un istruzione di salto qual è l istruzione da eseguire immediatamente dopo, al successivo colpo di clock, senza avere stalli e quindi sprechi di colpi di clock. Essendo una tecnica speculativa la control unit deve basarsi solamente su informazioni che conosce nella fase IF, cioè solo il Program Counter. Con questo PC la CU va a leggere la seguente tabella: essa contiene, in una data riga (idealmente corrispondente al valore del PC), il valore dell indirizzo destinazione dell istruzione di salto, che in precedenza si era andati ad eseguire, altrimenti se è la prima volta che si accede alla tabella con un dato PC, questa verrà aggiornata e quindi non sarà possibile effettuare la predizione. La CU quindi invece di far aggiornare il PC con il valore PC+4, scriverà in PC il valore corrispondente alla colonna Predicted PC, cioè il valore dell indirizzo destinazione dell istruzione di salto, cioè l indirizzo a cui si era saltati l ultima volta che si era trovata l istruzione di salto. Per fare questo però non è possibile avere una tabella che contenga tante righe quanti sono i valori possibili del PC; per cui questa tabella è costituita da un numero predefinito di righe che sono indirizzate dai 7 bit meno significativi del PC. Per evitare errori di accesso a PC errati questa tabella contiene, nella colonna Look up, i 25 bit più significativi che costituiscono il PC (l ultimo che ha fatto accesso alla tabella); in questa maniera è possibile verificare se l informazione cercata si riferisce al PC che ne fa richiesta. Se i PC coincidono si dovrebbe prelevare il Predicted PC corrispondente e andarlo a mettere in PC; però prima ancora di effettuare il prelievo bisogna controllare l ultima colonna che contiene un bit di controllo, il quali conferma se l ultima volta si è effettuato il salto oppure no. Pagina 39

40 PRESTAZIONI: caso di un loop nel quale si ha un certo numero di istruzioni e un istruzione di salto; la prima volta che si trova l istruzione di salto non si ha a disposizione nessuna statistica nella tabella. Quindi nel momento in cui si verifica la condizione verrà aggiornata la tabella con l indirizzo destinazione del salto e verrà modificato il bit di controllo (posto a 1). La prima volta sarà stato eseguito il fetch di un istruzione successiva a quella di salto, che poi sarà abortita nel caso il salto si dovesse verificare. Il resto del loop procede correttamente, poiché ora la tabella è aggiornata e quindi non vi è perdita di nessun colpo di clock per attendere il calcolo della destinazione del salto; al momento dell ultima iterazione, quando il salto non si verifica, la tabella darà ancora in uscita l indirizzo destinazione del salto e quindi nel PC verrà caricato automaticamente il Predicted PC; poi però l istruzione verrà abortita perché non si verificherà la condizione, per cui vi è una perdita di un colpo di clock. Quindi con questa tecnica si ha, con N iterazioni, un errore alla prima iterazione, N-1 iterazioni corrette e un altro errore all ultima iterazione. Nel caso si ritorni allo stesso loop, accedendo alla tabella si avrà il bit a zero nell ultima colonna e quindi si scommetterà che il salto non si dovrà effettuare commettendo così un errore mandando in fetch un istruzione che poi dovrà essere abortita; la tabella dovrà essere aggiornata commettendo così sempre l errore all ultima iterazione; quindi in totale in questa situazione si perdono comunque due colpi di clock. Questa situazione può essere descritta dal seguente diagramma a stati: NON ESEGUITO ESEGUITO 0 1 NON ESEGUITO ESEGUITO STATO 0: salto non verificato STATO 1: salto verificato Quando si è nello stato 0 vorrà dire che il salto non dovrà essere effettuato; se effettivamente la condizione non si verifica si rimane nello stato 0, altrimenti si passa nello stato 1, in cui vale in maniera duale lo stesso discorso. È possibile migliorare questa tecnica se si considera anche la storia passata e non solo quello che è successo l ultima volta; in questa maniera è possibile costruire una macchina a quattro stati, cioè questo significa avere nell ultima colonna della tabella due bit di controllo anziché uno. La seguente figura mostra la macchina a stati che permette di considerare la storia passata. STATO 00: certezza assoluta di salto non verificato STATO 01: predizione di salto non verificato STATO 10: predizione di salto verificato STATO 11: certezza assoluta di salto verificato Quando si è nello stato 11 vorrà dire che il salto dovrà essere effettuato; se effettivamente il salto si verifica si rimane sempre nello stesso stato, altrimenti si va nello stato 10, in cui si predice comunque la verifica del salto in base al fatto che le ultime volte il salto si era verificato; quando si è in questo stato se effettivamente il salto non si verifica bisognerà passare nello stato 00, altrimenti si ritorna nello stato 11. Quando si è nello stato 00 vorrà dire che il salto non dovrà essere effettuato, e vale in maniera duale lo stesso discorso. Pagina 40

41 Quindi utilizzando due bit anziché uno, un salto condizionato che privilegia la sua esecuzione o la sua nonesecuzione (come accade molto frequentemente) sarà soggetto di una previsione errata solamente una volta. I due bit saranno utilizzati per codificare i quattro stati del sistema. Vediamo come a livello del compilatore è possibile migliorare l esecuzione dei programmi. Esistono due tecniche di ottimizzazione: srotolamento del loop e pipeline da programma. SROTOLAMENTO DEL LOOP Questa tecnica punta a ridurre le istruzioni non indispensabili durante l esecuzione del loop in modo da rendere il programma più veloce. Prima di vedere dettagliatamente come funziona questa tecnica, per comprenderla meglio si consideri il seguente codice che implementa un loop per sommare gli elementi di due vettori: DADDI R6,R0,N LD R4,R1(0) LD R5,R2(0) DADD R4,R4,R5 SD R3(0),R4 DADDI R1,R1,#8 DADDI R2,R2,#8 DADDI R3,R3,#8 DADDI R6,R6,#-1 BNEZ R6,-9 stallo stallo stallo Istruzioni necessarie Istruzioni di gestione R1 punta al vettore A R2 punta al vettore B C[i] = A[i] + B[i] R3 punta al vettore C Questo programma dovrebbe durare (9 N) + 1 colpi di clock; ma poiché ci sono colpi di clock persi a causa di alcuni stalli provocati da: istruzione di load che ha come destinazione R5 che è sorgente dell istruzione successiva; istruzione di controllo su R6 che non è ancora disponibile; istruzione BNEZ; il programma dura (12 N) + 1 colpi di clock. Per eliminare i colpi di clock persi è possibile spostare istruzioni indipendenti nelle zone del codice che comportano degli stalli, ottenendo così il seguente codice con (9 N) + 1 colpi di clock: DADDI R6,R0,N LD R4,R1(0) LD R5,R2(0) DADD R4,R4,R5 SD R3(0),R4 DADDI R1,R1,#8 DADDI R2,R2,#8 DADDI R3,R3,#8 DADDI R6,R6,#-1 BNEZ R6,-9 stallo stallo stallo DIVENTA DADDI R6,R0,N LD R4,R1(0) LD R5,R2(0) DADDI R1,R1,#8 DADD R4,R4,R5 SD R3(0),R4 DADDI R6,R6,#-1 DADDI R2,R2,#8 BNEZ R6,-8 DADDI R3,R3,#8 Pagina 41

42 Si noti, comunque, che oltre alle quattro istruzioni necessarie se ne trovano sempre cinque per gestire il loop; allora bisogna cercare di semplificare il loop eliminando quelle istruzioni non indispensabili. È possibile pensare di codificare l indirizzi degli elementi di A, B e C in maniera tale che siano espressi in una forma caratterizzata da un certo immediato e un certo registro (che farà da spiazzamento). Si noti che le due load e la store sono legate tra di loro dal fatto che tutte e tre le operazioni punteranno sempre ad un identico elemento del vettore (ad esempio: salvo nel quarto di C la somma fra il quarto di A con il quarto di B); quindi è possibile pensare di avere un unico registro che permetterà di indirizzare il generico i-esimo elemento di un vettore. Quindi l indirizzo delle load e della store è espresso in questi termini: l immediato sarà l indirizzo del primo elemento del rispettivo vettore, mentre il registro farà da indice per gli elementi. Gestendo gli indirizzi in questo modo, da tre comandi per gestire l accesso ai tre dati se ne avrà soltanto uno, bisognerà lavorare solo su di un registro. Per cui supponendo per esempio che il primo valore di A è all indirizzo 1000, il primo di B è all indirizzo 2000 e il primo di C è all indirizzo 3000 è possibile avere il seguente codice: DADDI R1,R0,N DADDI R1,R1,#-1 DMULI R1,R1,#8 LD R2,R1(1000) LD R3,R1(2000) DADDI R1,R1,#-8 DADD R2,R2,R3 BNEZ R1,-6 SD (3008)R1,R2 //3008 perché R1 è stato decrementato In questa maniera ho per fare quattro istruzioni di calcolo, necessarie, due di gestione; per cui un overhead del 50%. A questo punto per diminuire questo overhead si può utilizzare la tecnica dello srotolamento del loop. Questa tecnica attua due stratagemmi per raggiungere il suo obiettivo: 1. Ridurre le istruzione di gestione del loop; 2. Mettere a disposizione un numero maggiore d istruzioni effettive di calcolo per avere più opportunità di trovare le istruzioni da inserire al posto degli stalli. Srotolare il loop significa prendere il codice e ricopiarlo per ottenere un altra iterazione; in realtà non si ricopia interamente il loop ma solamente le istruzioni necessarie, quelle di calcolo e utilizzando altri registri per effettuare le operazioni di load e di add. Quindi il loop dell esempio precedente srotolato e ottimizzato è il seguente: LD R2,R1(1000) LD R3,R1(2000) LD R5,R1(992) LD R6,R1(1992) DADD R2,R2,R3 DADD R5,R5,R6 SD (3000)R1,R2 SD (2992)R1,R5 DADDI R1,R1,#-16 BNEZ R1,-10 //utilizzo un altro registro //utilizzo un altro registro Pagina 42

43 Srotolato il loop ci si ritrova parecchio codice, che può essere riorganizzato in maniera tale da gestire gli eventuali stalli che si vengono a creare. Come si può notare questa tecnica ha lo svantaggio di incrementare l uso dei registri e del codice. È intuibile considerare un numero di registri che sia un sottomultiplo della dimensione del vettore, in modo tale da srotolare il loop senza lasciare residui del vettore. Se non si fa questa considerazione, è facile notare che alla fine del loop si processeranno indirizzi di memoria che non sono parte del vettore. PIPELINE DA PROGRAMMA Consideriamo sempre l esempio precedente, la somma tra vettori, però con dati floating point; si consideri per vera questa sintassi: L.D A(i) L.D B(i) ADD.D C(i),A(i),B(i) S.D C(i) La pipeline da programma parte dalla seguente osservazione: poiché non è possibile effettuare subito ADD.D (non si ha ancora a disposizione i dati sorgenti), e poi S.D, allora si effettua la somma dei dati di cui si è fatta la load all iterazione precedente; quindi saranno passati diversi colpi di clock, tanti quanti ne sono necessari per avere a disposizioni i valori nei registri. Stesso discorso per la store, andando a salvare il risultato dell iterazione ancora precedente a quella che ADD sta gestendo. In questa maniera evito lo spreco dei colpi di clock. Chiarita l idea di funzionamento, vediamo ora come la si implementa modificando il codice in questa maniera: L.D A(i+2) L.D B(i+2) ADD.D C(i+1),A(i+1),B(i+1) S.D C(i) Il codice è modificato in maniera tale che quando si sta facendo la store dell iterazione i-esima si sta memorizzando in memoria il risultato che ADD.D aveva calcolato all iterazione precedente, quindi all iterazione i-1 ADD.D calcola A(i)+B(i) e all iterazione i-esima C(i) viene scritto in memoria. Per chiarire meglio vediamo un esempio: iterazione i = 9; L.D A(9+2=11); L.D B(9+2=11); iterazione i = 10; ADD.D C(10+1=11),A(10+1=11),B(10+1=11); con A e B dati che sono stati caricati nell iterazione precedente i = 9; iterazione i = 11; S.D C(11); calcolato nell iterazione precedente i = 10; Quindi un loop dovrà essere fatto per N-2 iterazioni (0 N-3). Vediamo ora cosa succede alla prima e all ultima iterazione del loop: PRIMA ITERAZIONE: al momento della store si scriverà in memoria qualcosa che non sarà stato ancora calcolato; Pagina 43

44 ULTIMA ITERAZIONE: al momento delle load si caricheranno dati che non verranno mai processati. Allora è necessario strutturare questa pipeline con un transitorio di riempimento e un transitorio di svuotamento; cioè il programma è visto come un tubo in cui entrano le istruzioni di iterazioni differenti, in cui vi è un transitorio di caricamento nel quale si ha: L.D A(0) L.D B(0) L.D A(1) L.D B(1) ADD.D C(0),A(0),B(0) Dopo questo transitorio parte il loop effettivo dove i vale zero e quindi: L.D A(2) L.D B(2) ADD.D C(1),A(1),B(1) S.D C(0) Quando si arriva a N-3 sarà stata fatta l ultima store C(N-3), sarà stata calcolata C(N-2) e saranno fatte le ultime load A(N-1) e B(N-1); per cui dopo il loop si dovrà fare un transitorio di svuotamento nel quale si ha: ADD.D C(N-1),A(N-1),B(N-1) S.D C(N-2) S.D C(N-1) Dove questo transitorio di svuotamento completa il transitorio di caricamento. In tutto vengono fatte le operazioni legate a due cicli, quelli che da 0 a N-3 cicli del loop + due dei transitori portano effettivamente ad aver lavorato da 0 a N-1, cioè per N elementi del vettore. Con la pipeline da programma si risolve il problema degli stalli tra un istruzione ed un'altra. Il vantaggio di questa tecnica è che continua a tenere impegnati quei registri che si avevano nel caso di loop normale, mentre lo svantaggio rispetto alla srotolamento è che non diminuiscono le istruzioni di controllo. Il compilatore utilizzerà la tecnica dello srotolamento quando il codice contiene un numero d istruzioni di controllo che è proporzionalmente rilevante, altrimenti utilizzerà la tecnica del pipeline da programma; per cui la scelta della tecnica risulta forzata e dipendente dal numero di istruzioni che costituiscono il codice, o meglio dal numero di istruzioni di calcolo e di controllo che costituiscono il programma. Pagina 44

45 ESERCIZIO 1 Scrivere le microfasi della seguente istruzione: ESERCIZI DI RIEPILOGO S.D 1200(R3), F4 per un MIPS ad architettura pipeline con bus a 32 bit; In pratica questo esercizio richiede come può essere effettuato il trasferimento di 64 bit (store di un double), con il minor numero di stalli, in cui vi è il vincolo della memoria con un bus a 32 bit. È chiaro che se si vuole scrivere in memoria 64 bit, mentre ne posso scrivere soltanto 32 bit alla volta, bisognerà pensare un istruzione che avrà al suo interno due fasi MEM. L istruzione S.D 1200(R3),F4 equivale all istruzione: F4##F5 64 M[1200+R3] Cioè: F4 M[1200+R3] F5 M[1204+R3] Le fasi IF e ID sono le seguenti: FASE IF IF/ID.IR Mem[PC] IF/ID.NPC PC + 4 FASE ID ID/EX.A Regs[IF/ID.IR[rs]] ID/EX.B Regs[IF/ID.IR[rt]] ID/EX.IR IF/ID.IR ID/EX.NPC IF/ID.NPC ID/EX.Imm sign-extend(if/id.ir[immediate field]) µpc MM[IF/ID.IR[opcode]] L ultima istruzione permette di effettuare la decodifica dell istruzione; vengono letti i bit del codice operativo come un indirizzo per accedere alla MAPPING MEMORY (MM), nella quale per quel particolare codice operativo si troverà un nuovo indirizzo di una micro memoria che è alla base dell esecuzione della logica supervisionata dalla control unit. Fin qui non ci sono problemi, poiché queste due fasi sono sempre condotte alla stessa maniera per tutte le istruzioni; al termine del decode si conosce l istruzione e quindi si intraprendono le operazioni specifiche da eseguire. Vediamo due soluzioni: la prima effettua due fasi EX e due fasi MEM per eseguire l istruzione, quindi la si può ipotizzare come due istruzioni di store distinte, mentre la seconda soluzione cerca di avere una fase EX e due fasi MEM, di cui una incorpora una fase EX per il calcolo dell indirizzo successivo. Pagina 45

46 PRIMA SOLUZIONE FASE EXE1 EX/MEM.ALUOUTPUT ID/EX.A + ID/EX.Imm EX/MEM.B ID/EX.B FASE MEM1 Mem[EX/MEM.ALUOUTPUT] EX/MEM.B FASE EXE2 EX/MEM.ALUOUTPUT EX/MEM.ALUOUTPUT + 4 EX/MEM.B ID/EX.IR[rt+1] FASE MEM2 Mem[EX/MEM.ALUOUTPUT] EX/MEM.B //con rt + 1 accedo a F5 (a livello concettuale) Si noti che questo microprogramma, prevedendo 6 fasi, non presenta alcun vantaggio, in termini di prestazioni, rispetto all'esecuzione di 2 distinte istruzioni di store. Senza dire che la fase EXE2 e MEM2 potrebbero causare stalli alle istruzioni successive che nella pipeline competerebbero con questa per l'uso dell ALU e della Memoria. SECONDA SOLUZIONE Volendo migliorare le prestazioni, si può prevedere una duplicazione del EX/MEM.ALUOUTPUT (un secondo registro EX/MEM.ALUOUTPUT2 per referenziare la seconda metà della doppia parola) ed una sua strutturazione auto incrementante per svincolare l'alu. Quindi si può pensare che la fase EXE2 può avvenire contemporaneamente alla fase MEM1; questo è possibile perché in un primo istante si legge EX/MEM.ALUOUTPUT e poi in un secondo istante, dopo che l accesso a memoria è stato eseguito, lo si aggiorna. Lo stesso per EX/MEM.B, il quale viene in un primo momento trasferito in memoria e poi riceve ID/EX.IR[rt+1] In tal caso si avrebbe: FASE EXE1 EX/MEM.ALUOUTPUT ID/EX.A + ID/EX.Imm EX/MEM.B ID/EX.B FASE MEM1 (comprende anche la fase EXE2) Mem[EX/MEM.ALUOUTPUT] EX/MEM.B EX/MEM.ALUOUTPUT2 EX/MEM.ALUOUTPUT + 4 EX/MEM.B ID/EX.IR[rt+1] 1* SEMICICLO 2* SEMICICLO FASE MEM2 Mem[EX/MEM.ALUOUTPUT2] EX/MEM.B Pagina 46

47 Con questa scrittura, questa istruzione prevedrebbe 5 fasi, sebbene la presenza di MEM2 causerebbe uno stallo alle istruzioni successive, qualora l'istruzione I immediatamente seguente ad essa faccia effettivamente riferimento a memoria durante la sua fase MEM: (SD): IF ID EX MEM1 MEM2 (I): IF ID EXE Stallo MEM WB Quindi se l istruzione I è una istruzione di load o di store ci sarà uno stallo al momento della sua fase MEM. Si noti però che nel primo semiciclo della fase MEM1 oltre ad accedere alla memoria, si sta utilizzando l ALU per calcolare il nuovo indirizzo; per cui l istruzione I avrebbe anche la sua fase EXE in stallo. Per cui lo stallo andrebbe messo prima della fase EXE, quindi non si avrà poi lo stallo per la fase MEM, cioè la situazione diventerebbe la seguente: (SD): IF ID EX MEM1 MEM2 (I): IF ID Stallo EXE MEM WB Nel secondo caso lo stallo si avrebbe sempre e comunque, perché tutte le istruzioni fanno uso dell ALU; mentre nel primo caso, con un opportuna modifica, lo stallo si avrebbe solo se l istruzione I effettivamente fa riferimento alla memoria. Per risolvere il conflitto fra MEM1 e la fase EXE dell istruzione I bisogna pensare di modificare parte dell hardware del processore; poiché MEM1, oltre all accesso alla memoria, non fa altro che una somma per il calcolo dell indirizzo successivo, allora è possibile aggiungere un sommatore nella fase MEM, il quale ha il compito di determinare il nuovo indirizzo in modo tale che non venga occupata e utilizzata l ALU. Il processore eseguirà così in parallelo la fase MEM1 e la fase EXE2; la modifica da apportare e quindi la seguente: EX/MEM.ALUOUTPUT va in ingresso alla Data memory e ad un sommatore predisposto per calcolare il secondo indirizzo; quest ultimo dovrà essere scritto in EX/MEM.ALUOUTPUT2 e non in EX/MEM.ALUOUTPUT perché è usato dall istruzione che in quel momento è nella fase EX e che quindi sta usando l ALU e il suo risultato andrà in EX/MEM.ALUOUTPUT. Pagina 47

48 Con questa tecnica viene evitato il conflitto fra MEM1 e la EXE dell istruzione I nel caso questa non è una load o una store; altrimenti si avrà solo uno stallo. Con queste migliorie bisognerà leggermente modificare la C.U. e l hardware per gestire il sommatore e il nuovo registro; è una soluzione utile nel caso il processore esegue spesso istruzioni di store. ESERCIZIO 2 Relativamente ad una architettura RISC con 5 stadi di pipeline si progetti la circuiteria aggiuntiva da provvedere alla CPU per gestire in una singola istruzione operazioni di accesso ad uno stack di memoria, definendo le micro operazioni da compiere nei 5 stadi della pipeline relativamente all istruzione: POP Rb (Rb registro ricevente il dato prelevato dallo stack). Si preveda il controllo di stack overflow e stack underflow. Bisogna fare delle ipotesi: bisogna considerare se lo stack lavoro con indirizzi crescenti o decrescenti; l indirizzo, che punta all area di memoria in cui si vuole scrivere o leggere i dati, considerarlo puntatore al primo vuoto oppure all ultimo pieno. Innanzitutto bisogna gestire l ultima richiesta, cioè bisogna controllare le situazioni di overflow e underflow dello stack. Si consideri il seguente modello di stack in cui si hanno tre registri, uno contente l indirizzo di TOP (TS) dello stack, uno contenente l indirizzo di BOTTOM (BS) dello stack e uno contente l indirizzo dello STACK POINTER (SP). Si prevedano inoltre due comparatori che in uscita hanno rispettivamente le seguenti condizioni: Ipotizzando che SP punti alla prima cella vuota dello stack il quale si riempie per indirizzi crescenti si ha: COND1 che è 1 nel caso in cui SP sia maggiore di TS ad indicare l overflow; COND2 che è 1 nel caso in cui SP sia uguale a BS ad indicare l underflow In queste ipotesi il microcodice di un operazione POP potrebbe essere il seguente: (l operazione POP non è una semplice una operazione di load, ma bisogna anche modificare il valore di SP) FASE IF IF/ID.IR Mem[PC]; IF/ID.NPC PC + 4; FASE ID ID/EX.A IF/ID.IR[rs]; ID/EX.B IF/ID.IR[rt]; ID/EX.IR IF/ID.IR; ID/EX.NPC IF/ID.NPC; µpc MM[IF/ID.IR[opcode]]; Pagina 48

49 FASE EXE (if (COND2) µpc MM[gestione interrupt stack underflow]); EX/MEM.SP ID/EX.SP - 4; FASE MEM MEM/WB.LMD Mem[EX/MEM.SP]; FASE WB Regs[MEM/WB.IR[Rb] MEM/WB.LMD; // con Rb registro ricevente il dato prelevato dallo stack In una pipeline vista a 5 stadi sembra quindi che il miglior modo di operare con uno stack e quello con SP puntatore al primo vuoto. Questo esercizio richiedeva di analizzare il caso di un istruzione POP; vediamo ora come si complicano le cose nel caso d istruzione PUSH. Se SP è sempre puntatore al primo vuoto l operazione da effettuare per prima è quella di scrittura nello Stack e poi di aggiornamento con incremento di SP; questo significa utilizzare l ALU dopo la fase MEM e di conseguenza un peggioramento di prestazioni. Allora può sembrare non conveniente avere SP puntatore al primo vuoto, ma meglio averlo puntatore all ultimo pieno, in maniera tale da incrementare SP e poi accedere alla memoria per scrivere. Per cui bisogna decidere una tecnica che vada bene per un caso e trovare una soluzione per evitare stalli nell altro caso; questo è possibile inserendo, come nell esercizio precedente, un sommatore nella fase MEM che effettui l aggiornamento di SP. Bisogna però prestare attenzione, poiché stiamo considerando comunque un architettura pipeline, ai casi in cui si presentano più istruzioni PUSH o POP contemporaneamente, ad esempio: 1 CASO: istruzione POP seguita da un istruzione POP prima istr: POP IF ID EX MEM WB seconda istr: POP IF ID EX MEM WB Questa situazione non presenta alcun tipo di problema poiché nel momento in cui la seconda istruzione effettua la sua fase EX il valore SP sarà già stato aggiornato per cui tutto procede senza problemi. 2 CASO: istruzione PUSH seguita da un istruzione PUSH prima istr: PUSH IF ID EX MEM WB seconda istr: PUSH IF ID EX MEM WB Questa situazione non presenta alcun tipo di problema poiché nel momento in cui la seconda istruzione effettua la sua fase EX il valore SP sarà già stato aggiornato dal sommatore, presente nella fase MEM della prima istruzione, per cui tutto procede senza problemi. 3 CASO: istruzione POP seguita da un istruzione PUSH prima istr: POP IF ID EX MEM WB seconda istr: PUSH IF ID EX MEM WB Pagina 49

50 Questa situazione non presenta alcun tipo di problema poiché nel momento in cui la seconda istruzione effettua la sua fase EX il valore SP sarà già stato aggiornato per cui tutto procede senza problemi. 4 CASO: istruzione PUSH seguita da un istruzione POP prima istr: PUSH IF ID EX MEM WB seconda istr: POP IF ID stallo EX MEM WB Questa situazione presenta un stallo della fase EX dell istruzione POP; questo problema è dovuto al fatto che soltanto al termine della fase MEM dell istruzione PUSH il sommatore aggiornerà SP, per cui non potrà essere eseguita contemporaneamente la fase EX dell istruzione POP poiché SP non è ancora aggiornato. Per evitare questo stallo è possibile pensare di eseguire l aggiornamento di SP direttamente nella fase EX dell istruzione PUSH; vediamo in dettaglio cosa si dovrebbe fare: Nella fase EX passiamo SP al latch EX/MEM e tramite l ALU (quindi non serve più il sommatore) l aggiorniamo e lo passiamo al latch ID/EX; per cui in microcodice si ha: FASE EXE EX/MEM.SP ID/EX.SP ID/EX.SP ID/EX.SP + 4 In questo modo al termine della fase EXE il valore di SP risulterà aggiornato, per cui l istruzione POP successiva non dovrà più stallare poiché ora il dato sarà disponibile. prima istr: PUSH IF ID EX MEM WB seconda istr: POP IF ID EX MEM WB Pagina 50

51 ESERCIZIO 3 Considerando di voler aggiungere al set di istruzioni del MIPS le istruzioni ADDL e SUBL (la L sta per long, inteso come doppia word intera ) scrivere in RTL i microprogrammi utili ad interpretarle, indicando le più opportune modifiche architetturali. (bisogna supporre che l ALU del MIPS possa operare con soli dati da 32 bit e che quindi anche i registri sono a 32 bit). Nel caso non sia possibile compattare l istruzione in 5 fasi di pipeline, giustificarne il perché. Verosimilmente l operazione da effettuare sarà ad esempio: ADD R10,R4,R6 ADD R11,R5,R7 Quindi dividiamo l operazione in due; ma bisogna prestare attenzione al bit di carry prodotto dalla prima istruzione; per cui la seconda istruzione dovrà considerare l eventuale bit di carry che si sarà propagato e conservato nella PSW (Process Status Word), un registro ausiliario del processore che contiene una serie di flag che tengono traccia di quello che è appena successo nell ALU. Poiché l istruzione ADDL sommerà operandi in doppia lunghezza è utile fare delle considerazioni sui registri: rs e rt rappresentano i registri che contengono i 32 bit meno significativi; rs' e rt' rappresentano i registri che contengono i 32 bit più significativi; con l accortezza che rs' e rt' non siano scritti da nessuna parte, cioè l istruzione conterrà, considerando l esempio, solo il codice 4 e 6, il sistema poi saprà che si sta facendo riferimento a dei dati in doppia parola e che la seconda parte della parola è nei registri adiacenti. Lo stesso vale per il registro destinazione: rd (rd') rappresenta il registro destinazione che conterrà i 32 bit meno significativi (più significativi) del risultato. Le fasi IF e ID sono le seguenti: FASE IF IF/ID.IR Mem[PC] IF/ID.NPC PC + 4 FASE ID ID/EX.A Regs[IF/ID.IR[rs]] ID/EX.B Regs[IF/ID.IR[rt]] ID/EX.IR IF/ID.IR ID/EX.NPC IF/ID.NPC ID/EX.Imm sign-extend(if/id.ir[immediate field]) µpc MM[IF/ID.IR[opcode]] FASE EXE1 (occorre memorizzare il carry nel bit c della PSW) EX/MEM.IR ID/EX.IR EX/MEM.ALUOUTPUT ID/EX.A + ID/EX.B ID/EX.A Regs[IF/ID.IR[rs']] ID/EX.B Regs[IF/ID.IR[rt']] PSW[c] carry Sfruttando una suddivisione in semicicli, ID/EX.A e ID/EX.B sono letti nel primo semiciclo e scritti nel secondo. Pagina 51

52 FASE EXE2 (comprende la fase MEM1) MEM/WB.IR EX/MEM.IR MEM/WB.ALUOUTPUT EX/MEM.ALUOUTPUT EX/MEM.ALUOUTPUT ID/EX.A + ID/EX.B + PSW[c] Sfruttando una suddivisione in semicicli, EX/MEM.ALUOUTPUT è letta nel primo semiciclo, scritta nel secondo. FASE WB1 (comprende la fase MEM2) Regs[MEM/WB.IR[rd]] MEM/WB.ALUOUTPUT MEM/WB.ALUOUTPUT EX/MEM.ALUOUTPUT Sfruttando una suddivisione in semicicli, MEM/WB.ALUOUTPUT è letta nel primo semiciclo, scritta nel secondo. FASE WB2 Regs[MEM/WB.IR[rd']] MEM/WB.ALUOUTPUT µpc 0 Pensata così l istruzione termina in sei fasi; analizziamo ora i conflitti che potrebbe generare: prima istr: ADDL IF ID EX1 EX2 WB1 WB2 seconda istr: qualsiasi IF ID EX MEM WB per la seconda istruzione vi è uno stallo nel momento in cui vi è la fase EX (avviene in contemporanea con la EX2) e nel momento della fase ID poiché provoca incoerenza in quanto EX1 sta scrivendo nei registri A e B e a lo stesso sta facendo ID. Per cui inserendo lo stallo prima della fase ID si ottiene: prima istr: ADDL IF ID EX1 EX2 WB1(MEM1) WB2(MEM2) seconda istr: qualsiasi IF stallo ID EX MEM WB È possibile migliorare la situazione considerando che se le operazioni in doppia precisione fossero molto frequenti, potremmo pensare di utilizzare dei latch A, B, ALUOUTPUT capaci di contenere 64 bit, invece di 32, evitando la seconda fase di prelievo degli operandi (nella fase EX1) che obbligano di fatto ad uno stallo l'istruzione successiva, in quanto ne impediscono l'id. Comunque l ALU continuerebbe a processare gli operandi in due tempi ciascuno da 32 bit: avremmo comunque la necessità di avere due fasi di EXE (e conseguente stallo delle istruzioni successive in conflitto strutturale sull'alu, risolvibile inserendo un sommatore nella fase EX2 in modo tale da non usare l ALU). In questo modo bisognerà potenziare la C.U. e aggiungere hardware; non si ottiene quindi nessun miglioramento per cui conviene avere un ALU a 64 bit. In maniera analoga a quanto appena visto vale per l ipotetica istruzione SUBL, considerando il bit di borrow (riporto) della PSW invece del bit di carry. Pagina 52

53 ESERCIZIO 4 Scrivere in RTL i microprogrammi utili ad interpretare l istruzione: LW R1,(#1000,R2) per una architettura MIPS con bus dati a 32 bit, considerando eventuali conflitti che si verrebbero a creare con le istruzioni ad essa successive nell'implementazione pipeline. Per LW R1, (#1000, R2) si intende: R1 Mem[Mem[ R2]] Cioè verosimilmente si dovrebbero effettuare, per esempio, queste due istruzioni: LW R6,1000(r2) LW R1,0(R6) Le fasi per svolgere queste due istruzioni dovrebbero essere le seguenti: prima istr: LW R6,1000(R2) IF ID EX MEM WB seconda istr: LW R1,0(R6) IF ID EX MEM WB Ci sarà bisogno di uno stallo poiché la seconda LW deve calcolare R6 + 0 per avere l indirizzo, e quindi la EX della seconda istruzione deve stallare; ma poiché essendo zero il secondo addendo della somma, allora con una corto-circuitazione della memoria, in cui l uscita della memoria va alla porta indirizzo della memoria stessa, si evita lo stallo. Questa operazione vale solamente in questo caso, poiché la seconda load deve effettuare una somma con zero. Quindi bisognerà modificare la C.U. Per cui con questi accorgimenti non si hanno stalli e l istruzione successiva terminerebbe al colpo di clock 6. Quindi per ottimizzare il microcodice di questa istruzione, che prevede un doppio accesso a memoria, supponiamo nella architettura MIPS, un collegamento dall'uscita dati della memoria al registro EX/MEM.ALUOUTPUT. In tal caso, il microcodice, potrebbe essere: FASE IF IF/ID.IR Mem[PC] IF/ID.NPC PC + 4 FASE ID ID/EX.A Regs[IF/ID.IR[rs]] ID/EX.B Regs[IF/ID.IR[rt]] ID/EX.IR IF/ID.IR ID/EX.NPC IF/ID.NPC ID/EX.Imm sign-extend(if/id.ir[immediate field]) µpc MM[IF/ID.IR[opcode]] FASE EX EX/MEM.ALUOUTPUT ID/EX.A + ID/EX.Imm EX/MEM.IR ID/EX.IR FASE MEM1 EX/MEM.ALUOUTPUT Mem[EX/MEM.ALUOUTPUT] MEM/WB.IR EX/MEM.IR FASE MEM2 Pagina 53

54 MEM/WB.LMD Mem[EX/MEM.ALUOUTPUT] FASE WB Regs[MEM/WB.IR[rd]] MEM/WB.LMD Pensata così l istruzione termina in sei fasi; analizziamo ora i conflitti che potrebbe generare: prima istr: LW IF ID EX MEM1 MEM2 WB seconda istr: qualsiasi IF ID EX MEM WB La fase di MEM2 della prima istruzione provoca un problema con la fase MEM della seconda istruzione solo se quest ultima è un istruzione di load o di store, altrimenti la fase MEM è una sola fase di passaggio. Per cui si potrebbe far precedere l istruzione LW solo da istruzioni che non effettuano load o store. Il vero problema sorge nel momento in cui la seconda istruzione entra in fase di WB; questo problema è semplicemente risolvibile potenziando il canale che porta i dati nei registri. Pagina 54

55 ESERCIZIO 5 Progettare un microprogramma in linguaggio RTL da associare ad una istruzione: RTI (return from interrupt) per una macchina MIPS nei due casi: - salvataggio del PC in un registro IAR (Interrupt address return) - salvataggio del PC in uno stack, facendo ipotesi su come è gestito lo stack. Per semplicità si trascuri il ripristino dei registri e della parola di stato. L istruzione RTI permette di ritornare alla normale esecuzione di un programma dopo che è stata servita l interruzione. Il microprogramma ad essa associato può essere: FASE IF IF/ID.IR Mem[PC] IF/ID.NPC PC + 4 FASE ID ID/EX.A Regs[IF/ID.IR[rs]] ID/EX.B Regs[IF/ID.IR[rt]] ID/EX.IR IF/ID.IR ID/EX.NPC IF/ID.NPC ID/EX.Imm sign-extend(if/id.ir[immediate field]) µpc MM[IF/ID.IR[opcode]] Consideriamo prima il caso in cui il PC sia stato salvato nell IAR, quindi nei casi di interrupt mascherati, cioè nei casi in cui l interrupt non viene interrotto, in maniera tale da non perdere il PC. FASE EXE EX/MEM.ALUOUTPUT IAR FASE MEM MEM/WB.ALUOUTPUT EX/MEM.ALUOUTPUT FASE WB PC MEM/WB.ALUOUTPUT µpc 0 L IAR viene caricato nel PC per ripristinare il valore del PC quando c è stata l interruzione e viene resettato il µpc a 0 per fare il fetch della successiva istruzione. Anche se l istruzione porta via cinque fasi provocherebbe comunque degli stalli per le prossime istruzioni, perché il fetch non potrà essere effettuato in quanto il PC sarà disponibile solo dopo la fase di WB. Per cui se si gestisce così l istruzione si avrebbe una situazione del genere: prima istr: RTI IF ID EX MEM WB seconda istr: (istr. con PC corretto) IF stallo stallo stallo IF ID EX MEM WB Pagina 55

56 Per cui è necessario effettuare il WB il prima possibile; questo si può ottenere cortocircuitando direttamente IAR con il PC consentendo di ridurre ad uno solo gli stalli (nella fase di EXE si avrebbe direttamente PC IAR). Per cui si ottiene: prima istr: RTI IF ID EX MEM WB seconda istr: (istr. con PC corretto) IF stallo IF ID EX MEM WB Un ulteriore miglioramento potrebbe essere ottenuto a livello di scheduling, inserendo dopo l'istruzione RTI le ultime due istruzioni di procedura di gestione dell interrupt, in maniera tale da non sprecare colpi di clock; si ottiene così questa situazione: prima istr: RTI IF ID EX MEM WB seconda istr: istr N-2 IF ID EX MEM WB terza istr: istr N-1 IF ID EX MEM WB quarta istr: (istr. con PC corretto) IF ID EX MEM WB dove: N-2 è la terz ultima istruzione di gestione dell interrupt; N-1 è la penultima istruzione di gestione dell interrupt Vediamo ora il caso in cui il PC venga salvato nello STACK, quindi nei casi di interrupt non mascherabili, cioè nei casi in cui l interrupt può essere interrotto, e il valore del PC non viene perso poiché viene salvato nello stack; al momento del termine delle procedure di gestione degli interrupt, si procede con il prelievo dallo stack dei rispettivi PC. Si suppone che lo STACK risieda in memoria per indirizzi crescenti e che lo Stack Pointer punti all ultima locazione piena. Pagina 56

57 FASE EXE EX/MEM.ALUOUTPUT SP SP SP - 4 FASE MEM MEM/WB.LMD Mem[EX/MEM.ALUOUTPUT] FASE WB PC MEM/WB.LMD µpc 0 Nella fase di EXE avviene il caricamento nel EX/MEM.ALUOUTPUT dello SP e il contemporaneo decremento dello SP per puntare all elemento successivo. Come nel primo caso si ottengono degli stalli che portano l istruzione con il PC corretto a cominciare al sesto colpo di clock. Con uno opportuno scheduling dell istruzioni, simile al precedente caso, è possibile anche in questo caso evitare i colpi di clock persi. Pagina 57

58 ESERCIZIO 6 Disegnare la CPU di una architettura ad accumulatore e commentarne le caratteristiche. Inoltre, progettarne il ciclo di esecuzione delle istruzioni, descrivendo in RTL il funzionamento del programma: specificando anche qual è il suo scopo. LD 1200 ADD 1204 ST 1200 L architettura ad accumulatore si differenzia perché non ha tutti i registri, ma soltanto un registro, chiamato registro accumulatore (ACC); questo registro contiene l operando sorgente e riceve l operando risultato. Il funzionamento dell architettura è il seguente; 1. Al registro ACC vengono passati: a) Codice operativo; b) Un operando, che è un indirizzo di memoria; 2. Il contenuto del registro ACC diventa il primo operando; 3. Viene letta la memoria è il valore viene usato come secondo operando; 4. Calcolo del risultato; 5. Scrittura nel registro ACC. Il programma da descrivere richiede: 1. Caricare il contenuto che si trova in memoria all indirizzo 1200 nel registro ACC; ACC M[1200] 2. Sommare il contenuto di ACC con il valore contenuto in memoria all indirizzo 1204 (il risultato andrà in ACC); ACC ACC + M[1204] 3. Salvare il risultato, ovvero il contenuto di ACC, all indirizzo di memoria M[1200] ACC Come è facile notare questa architettura non permette una gestione in pipeline dell istruzioni. Pagina 58

59 Un esempio di processore ad Accumulatore può essere il seguente: In cui: 1. L'Accumulatore sostituisce il banco di registri General Purpose. 2. Esso è vincolato ad uno dei due ingressi dell'alu (l'ingresso In1; questo consente all'architettura di avere un solo bus sorgente in ingresso all'alu) e funge inoltre da EX/MEM.A 3. L'Accumulatore è anche una destinazione privilegiata per l'uscita dell'alu (il demux, dal punto di vista funzionale non ha alcuna utilità potendo direttamente connettere sul bus D l'uscita dell'alu in scrittura e l'acc in lettura come tutti gli altri registri, ma la sua presenza evidenzia didatticamente il fatto che l'accumulatore è il ricettore privilegiato dei dati in uscita dall'alu). 4. Il registro speciale SAR (Subroutine Address Return) serve per una gestione semplificata delle procedure e memorizza l'indirizzo di rientro (non sono consentiti annidamenti di procedure). 5. Il registro speciale IAR (Interrupt Address Return) serve per una gestione semplificata degli interrupt e memorizza l'indirizzo di rientro (sono consentiti solo interrupt esterni e a loro volta non interrompibili). Queste caratteristiche determinano anche una semplificazione importante sul formato istruzione della macchina che richiede solo la specifica di un indirizzo di memoria come operando sorgente, essendo l'altro operando sorgente ed il destinazione costituiti di default dall'accumulatore. Si può quindi supporre un formato istruzione: 4 bit for opcode 28 bit for immediate field (assumendo che solo 4 bit di CO siano sufficienti per codificare le operazioni ammesse). Pagina 59

60 Per il ciclo di esecuzione delle istruzioni di questa macchina si possono supporre le seguenti fasi: Instruction Fetch, in cui si preleva l'istruzione e si incrementa il PC: IR Mem[PC] PC PC+4 L ultima istruzione sarebbe l insieme di queste tre operazioni: S PC D In0+4 PC D Addressing e Instruction Decode in cui viene preparato l'indirizzamento alla memoria e decodificata l'istruzione: MAR IR AND #0FFFFFFF µpc MM[IR[opcode]] La prima istruzione sarebbe l insieme di queste tre operazioni, in cui viene effettuato il mascheramento del codice operativo: S IR D In0 AND #0FFFFFFF MAR D Poi a seconda del tipo di operazione si ha: FASE MEM: LMDR Mem[MAR] FASE EXE/WB: ACC LMDR+0 µpc 0 LOAD ALU STORE BCOND FASE MEM: LMDR Mem[MAR] FASE EXE/WB: ACC LMDR op ACC µpc 0 FASE MEM: Mem[MAR] ACC µpc 0 FASE SETPC: if COND: PC MAR (via ALU) µpc 0 INT (da sistema) RTI JSUB RET (from subroutine) FASE STPC: IAR PC FASE SETPC: PC MAR (via ALU) µpc 0 FASE SETPC: PC IAR µpc 0 FASE STPC: SAR PC FASE SETPC: PC MAR (via ALU) µpc 0 FASE SETPC: PC SAR µpc 0 Dove: MEM è la fase di accesso alla memoria; EXE/WB è la fase di calcolo effettivo e di aggiornamento dell'accumulatore; STPC (Store PC) è la fase in cui viene memorizzato il PC prima di gestire un interrupt o saltare ad una subroutine; SETPC è la fase di impostazione (o ripristino istruzioni di return) del PC. La sua codifica in RTL si ottiene banalmente trascrivendo in sequenza opportunamente le microistruzioni relative alle fasi come definito nella prima parte dell'esercizio rispettivamente per una Load, per una operazione ALU (somma) e per una Store. Pagina 60

61 Per cui si ha: FASE IF IR Mem[PC] PC PC+4 LD 1200 FASE ADD/ID MAR IR AND #0FFFFFFF µpc MM[IR[opcode]] FASE MEM LMDR Mem[MAR] (MAR == 1200) FASE EXE/WB ACC LMDR+0 µpc 0 FASE IF IR Mem[PC] PC PC+4 ADD 1204 FASE ADD/ID MAR IR AND #0FFFFFFF µpc MM[IR[opcode]] FASE MEM LMDR Mem[MAR] (MAR == 1204) FASE EXE/WB ACC LMDR op ACC (op == +) µpc 0 FASE IF IR Mem[PC] PC PC+4 ST 1200 FASE ADD/ID MAR IR AND #0FFFFFFF µpc MM[IR[opcode]] FASE MEM Mem[MAR] ACC (MAR == 1200) µpc 0 Pagina 61

62 PARTE SECONDA PARTE SECONDA MEMORIE CACHE Pagina 62

63 Costo/byte Appunti di Calcolatori Elettronici A.A. GERARCHIA DI MEMORIA Nella figura qui affianco è riportata la struttura gerarchica di un sistema di memorie. Quello che è interessante vedere è che la dimensione (capacità) dei vari blocchi di memoria aumenta con l allontanarsi dal processore; si osserva anche che allontanandosi dalla CPU diminuisce la velocità di accesso alle informazioni e il costo rapportato al byte. 1 LIVELLO 2 LIVELLO BREVE CENNO SU: MEMORIA CENTRALE MECCANISMO A FINESTRA DEI REGISTRI L ideale sarebbe avere una CPU con molti registri, veloci e convenienti; ma mettere a disposizione un numero elevato di registri all interno del processore non sarebbe conveniente, poiché in realtà questo porterebbe a reperire informazioni in maggior tempo. Infatti si riesce ad accedere in maniera diretta e veloce ai registri, proprio se questi sono in numero limitato; inoltre poiché ogni registro ha un nome identificativo univoco, nel caso in cui si vuole avere un numero molto più ampio di registri bisognerebbe puntare ad un registro specificando un numero di bit molto più grande e questo significherebbe avere un istruzione con tre operandi, ciascuno dei quali con un elevato numero di bit; quindi l istruzione avrebbe un numero troppo grande per individuare solo i registri. In seguito ci si accorgerà che quando nel processore si inserisce una memoria cache, in pratica, si riesce a implementare la logica a più registri attraverso il meccanismo a finestra; il progettista può decidere di inserire nel processore più di 32 o 64 registri, ma dando la visibilità alla CPU solo ad un numero ristretto di registri. Questo meccanismo è utile nei casi in cui vi è una chiamata alla procedura di gestione di un interrupt; la procedura potrebbe utilizzare i registri per scriverci delle informazioni necessarie all esecuzione. Il meccanismo permette di far puntare la CPU ad altri registri, in maniera tale da non far sovrascrivere i dati e inoltre questo meccanismo permette di non effettuare, o comunque limitare, il salvataggio dei registri nello stack (è richiesto solo il salvataggio di PC e del PSW e di un codice che identifica di quanto è stata spostata la finestra). PRINCIPI FONDAMENTALI DELLA GERARCHIA DI MEMORIA TRASPERENZA DEI LIVELLI: ogni livello intermedio della gerarchia è trasparente al processore e simula il processore per il livello immediatamente inferiore, mentre simula la memoria per il livello immediatamente superiore. Per comprendere meglio questo concetto, si consideri questo esempio: supponiamo che la memoria centrale chiede dei dati ai dischi; dal punto di vista dei dischi è come se fosse il processore a richiedere i dati, quindi la memoria per il livello sottostante simula il processore; la cache (livello immediatamente superiore) è vista come processore dalla memoria, ma quest ultima simula la memoria per la cache. Per cui, dal punto di vista del processore tutto ciò che sta sotto è memoria. Pagina 63

64 PRINCIPI DI LOCALITA : la CPU richiede dati seguendo due principi di località: - LOCALITA SPAZIALE: quando una cella di memoria viene referenziata, le celle vicine (ad essa contigue) hanno un alta probabilità di essere a loro volta referenziate di lì a poco; questo principio si applica bene alle istruzioni di un programma, ma anche ai vettori ed alle matrici; - LOCALITA TEMPORALE: quando una cella di memoria viene referenziata, è probabile che presto venga referenziata di nuovo; questo principio si applica bene soprattutto ai dati ed alle variabili. Questi principi suggeriscono l uso dei blocchi; un blocco è una quantità d informazione che ha la caratteristica di essere contigua in memoria, quindi la memoria sarà divisa in un numero fisso di locazioni contigue. In questo modo quando una memoria dovrà dare alla memoria di livello superiore un dato le passerà l intero blocco contenente il dato richiesto; anche se può sembrare di perdere del tempo, in questo modo vengono rispettati i principi e allo stesso tempo analizzando le prestazioni ci si accorge che questa è una scelta ottimale. Supponiamo che un i-esimo livello superiore chieda un dato che si trova ad un qualsiasi indirizzo del livello inferiore. Il tempo, affinché il livello superiore possa avere a disposizione il dato, è possibile descriverlo in questo modo: T = T Li 1 + T Si Dove: T Li 1 è il tempo di Lettura dal livello inferiore i 1 T Si è il tempo di Scrittura al livello stesso i Se si sta facendo lettura dal disco il tempo di lettura dipenderà da tre fattori, quali: tasso di trasferimento, tempo di ricerca e tempo di latenza rotazionale; di cui due sono tempi meccanici, per cui il tempo di accesso è più alto rispetto se la lettura è effettuata ad esempio in memoria centrale. Per cui al momento di una lettura di un dato, si effettua un prelievo di un blocco contenente il dato, poiché per il principio di località temporale è possibile che il secondo dato, che eventualmente sarà richiesto, sia compreso fra quelli prelevati; quindi questa scelta porta ad un minor tempo per la lettura di un insieme di dati, rispetto al tempo per leggere un singolo dato per volta. Questa filosofia è applicata alla piramide gerarchica; quando la CPU chiede un dato alla memoria cache, se questa non c è l ha, lo chiederà al livello sottostante insieme ad un blocco di dati. Lo stesso vale per gli altri livelli. Essendo ogni livello più piccolo del precedente, non si ha una corrispondenza 1 ad 1; per cui bisogna gestire quattro fondamentali problemi. QUATTRO DOMANDE PER LA CLASSIFICAZIONE DELLE GERARCHIE DI MEMORIE I problemi che si presentano quando si mettono in relazione i diversi livelli di una gerarchia di memorie sono bene evidenziati dalle seguenti quattro domande: D1) Dove è possibile mettere un blocco nel livello superiore? (allocazione del blocco) D2) Come è possibile trovare un blocco quando è nel livello superiore? (identificazione del blocco) D3) Quale blocco deve essere sostituito in caso di fallimento di accesso? (sostituzione del blocco) D4) Cosa succede nel caso di una scrittura? (strategia di scrittura) Pagina 64

65 Consideriamo ora le cache più in dettaglio esaminando le risposte alle quattro domande sulle gerarchie di memorie. MEMORIE CACHE Un po di storia e curiosità La prima cache nella storia dei calcolatori è stata descritta in un articolo di Wilkes nel 1965; l abstract dell articolo sostanzialmente cita: si discute dell utilizzo di una memoria veloce, di parole, supporto di una memoria centrale più lenta, di 1'000'000 di parole, in modo tale che il tempo di accesso effettivo sia più vicino a quello di una memoria veloce che a quello di una memoria lenta. Questa idea, al tempo innovativa, porta, solo dopo tre anni, alla realizzazione del primo calcolatore dotato di memoria cache, presso l università di Cambridge. Per fare questo occorreva una tecnologia diversa, più veloce, da quella utilizzata per la memoria centrale, infatti vennero utilizzati i DIODI TUNNEL, però essendo questa tecnologia, all epoca molto ingombrante, potevano essere realizzate memorie di piccole dimensioni. Proprio a causa delle grandi dimensioni è famoso l aneddoto sulla parola debug : Il 9 settembre del 1945 Grace Murray Hopper (ufficiale e matematico di gran valore) che prestava servizio in Virginia presso la marina militare degli Stati Uniti stava cercando di trovare l'errore che inceppava il computer basato su un sistema Harvard Mark II, quando decise di controllare lo stanzone contenente l intero sistema, trovò un insetto che girovagava allegramente (prima di morire) in mezzo ai circuiti e che era la causa del malfunzionamento, dopo aver rimosso l insetto, il tenente lo incollò sui suoi appunti e annotò: «1545. Relay #70 Pannello F (falena) nel relay. Primo vero caso di bug trovato>>. Questo registro è conservato presso lo Smithsonian National Museum of American History. Da allora il termine "bug" entrò nell'informatica per indicare un errore di programmazione. STRATEGIE DI ALLOCAZIONE DEI BLOCCHI Si suppone, per semplicità, che la memoria centrale sia costituita da 32 blocchi e la memoria cache costituita da 8 blocchi; si vuole prelevare un dato, all indirizzo x, dalla memoria centrale e caricarlo in cache. Questo dato è interno ad uno dei 32 blocchi che costituiscono la memoria centrale; ad esempio si consideri questa situazione: il blocco contenente il dato x è il numero (16) 8. Indirizzo di blocco (memoria centrale) N. bl oc co Pagina 65

66 I vincoli sulla posizione dei blocchi creano tre categorie di cache: CACHE COMPLETAMENTE ASSOCIATIVA Se un blocco può essere messo ovunque nella cache, in una qualsiasi posto chiamato linea, essa è definita completamente associativa CACHE AD INDIRIZZAMENTO DIRETTO Se ogni blocco può comparire in un'unica linea della cache, allora essa è definita a indirizzamento diretto. La linea nella cache si ottiene tramite una operazione di mascheramento ai bit che identificano il blocco; per cui essendo 16 8 = e dato che la cache è di 8 linee, bisognerà prendere 3 bit dei 6 che identificano il blocco; quindi se considero i primi 3 bit incorrerò sicuramente in sovrascritture, poiché nel momento in cui bisognerà caricare ad esempio il blocco adiacente, 17, questo andrà a scriversi comunque nel blocco 1, determinando la perdita dei dati precedentemente contenuti. Per cui si considerano gli ultimi 3 bit e quindi il blocco 16 viene caricato nella linea = 6 8. Questa operazione equivale a: indirizzo di blocco 10 MOD numero effettivo di linee nella cace Considerando l esempio si ha: 14 MOD 8 = Questo metodo di allocazione dei blocchi è il più semplice che si possa avere, ma è il meno consigliabile dal punto di vista del Principio di Località Temporale. CACHE SET ASSOCIATIVA Se un blocco può essere messo in un insieme ristretto di posizioni nella cache, essa è definita set-associativa. Un insieme o set è un gruppo di due o più blocchi della cache. Un blocco viene prima messo in corrispondenza di un insieme e poi può essere messo in precisa posizione dell insieme. Di solito, l insieme o set viene individuato dalla seguente operazione: (indirizzo di blocco) 10 MOD (numero effettivo di set nella cace) Considerando l esempio si ha: 14 MOD 4 = 2. Questa operazione equivale a leggere gli ultimi due bit dei 6 che identificano il set: Set. 0 Set. 1 Set. 2 Set. 3 Pagina 66

67 STRATEGIE DI RICERCA E IDENTIFICAZIONE Dall indirizzo di memoria proveniente dalla CPU la cache estrae l etichetta e la confronta con tutte le etichette presenti nella Tag Memory della cache, a cui corrisponde una dato nella effettiva memoria dati della cache se la sua organizzazione è completamente associativa. Se invece la cache è di tipo set-associativo, l etichetta estratta viene confrontata con tutte le Tag Memory appartenenti all unico insieme deputato a contenere il blocco ricercato. Infine, nel caso di cache a indirizzamento diretto l etichetta estratta viene confrontata con l unica possibile Tag Memory. Le memorie cache di tipo set-associativo ed ad indirizzamento diretto suddividono un indirizzo di memoria in tre campi: Etichetta Indice Spiazzamento nel blocco - Etichetta: serve per identificare il blocco ricercato; - Indice: serva a individuare il set (set-associativa) o il blocco (indirizzamento diretto); - Spiazzamento nel blocco: è utilizzato per selezionare il dato (parola) desiderato nel blocco. Le memorie cache completamente associative suddividono un indirizzo di memoria in due soli campi: Etichetta Spiazzamento nel blocco A questa conclusione si giunge considerando che, se la dimensione totale viene mantenuta, un incremento della associatività comporta un aumento del numero dei blocchi per insieme; di conseguenza diminuisce il numero degli insiemi e aumenta la dimensione dell etichetta. Cioè il confine tra l etichetta e l indice si sposta verso destra via via che si aumenta l associatività. La necessità che l accesso alla cache sia veloce richiede che i confronti tra le etichette siano fatti in parallelo. Perciò nel caso di cache completamente associative vi saranno in parallelo tanti confronti (e quindi tanti comparatori) quanti sono i blocchi in cui è suddivisa la cache stessa (nell esempio si avranno 8 comparatori); nel caso di cache set-associative vi saranno in parallelo tanti confronti (e quindi tanti comparatori) quanti sono i blocchi che costituiscono i set in cui è suddivisa la cache stessa (nell esempio si avranno 2 comparatori); infine, nel caso di una cache a indirizzamento diretto si avrà solo un confronto (e quindi un solo comparatore). Ci deve essere poi un modo per vedere se un blocco nella memoria cache non contiene informazioni valide. Il metodo più comune consiste nell aggiungere un bit di validità (Validity bit) all etichetta che indica la validità dell indirizzo contenuto nell etichetta stessa. Tale indirizzo non viene considerato se il bit non ha un valore alto. Pagina 67

68 STRATEGIE DI SOSTITUZIONE (fallimenti di accesso) La CPU chiede alla memoria cache un dato che in essa non è presente: allora la memoria deve caricare un blocco che contiene questo dato dal livello sottostante. Nel caso di organizzazione a indirizzamento diretto, lo schema è così semplice che non ci sono alternative: soltanto un blocco viene controllato quando si effettua un accesso alla memoria e solo quel blocco può essere sostituito. Nel caso di organizzazione completamente associativa e set associativa è possibile operare una scelta fra tre metodi: 1. METODO RANDOM: i blocchi candidati alla sostituzione in questo caso vengono scelti in modo casuale. Affinché il metodo sia efficace si deve avere una bassa probabilità di sostituire un blocco appena caricato, cosa che è tanto più garantita quanto maggiore è il numero dei blocchi. Questo è il motivo per cui tale metodo è indicato per le memorie cache completamente associative. Un vantaggio della scelta casuale è la semplicità della realizzazione circuitale. 2. METODO LRU (Last Recently Used): il blocco che viene sostituito quando si adotta questo metodo è quello che è rimasto inutilizzato per il periodo di tempo più lungo. Tale strategia si basa sul Principio di Località Temporale: se è probabile che le linee usate di recente siano riutilizzate, allora il miglior candidato alla sostituzione è la linea che è stata usata meno di recente. Per ridurre la possibilità di eliminare informazioni che presto saranno di nuovo necessarie, gli accessi alle linee vengono registrati. Vediamo come considerando l organizzazione set associativa (le stesse considerazioni sono valide per la completamente associativa): ogni linea all interno di un set viene dotato di un contatore di utilizzo. Ogni qualvolta si utilizza una linea si azzera il suo contatore e si incrementa di una unità il contatore delle altre linee dello stesso set; in tal modo i contatori delle linee non utilizzate avranno un valore più elevato. La linea il cui contatore presenta il valore più alto è quello non usata da più tempo. Nel caso in cui tutte le linee avessero i contatori a zero, si prenderà allora la prima linea. Questo metodo va bene quando le linee del set sono poche, perché devono essere eseguiti molti confronti. In generale, se n sono le linee del set, avremo n(n 1) confronti e quindi sarà necessaria una rete di n(n 1) comparatori. È chiaro allora che quando il numero delle linee da tenere sotto controllo cresce, la strategia LRU diventa sempre più costosa e, d altra parte, sempre più di frequente fornisce risultati approssimativi. Si consideri la seguente situazione in cui inizialmente la linea candidata LRU è la linea 0 : LINEA USATA ALL ISTANTE / LINEA CANDIDATA LRU Pagina 68

69 Non è detto che questo metodo convenga sempre; analizzando la tabella qui affianco è facile notare infatti che aumentando dimensione e associatività (linee in un set) LRU e RANDOM si uguagliano e questo (la tabella riporta il numero di fallimenti per 1000 istruzioni) avviene per due motivi: - nella scelta fra più linee, anche casualmente, è facile che ne venga selezionata qualcuna che non serve subito; - nella scelta fra più linee, il metodo LRU diventa meno preciso. 3. METODO FIFO (First In First Out): consiste nel sostituire il blocco che era stato utilizzato N accessi prima, indipendentemente dal fatto che sia stato utilizzato o meno negli ultimi N-1 accessi. In pratica il sistema funziona grazie a uno shift register, ossia un registro a scorrimento costituito da un serie di celle in cui, per ogni colpo di clock, il contenuto di una cella passa alla cella successiva; si osservi questo esempio: LINEA 3 LINEA 1 LINEA 2 LINEA 5 Linea 4 LINEA 4 LINEA 3 LINEA 1 LINEA 2 LINEA 5 Blocco che verrà sostituito È evidente che il metodo non è rigoroso dal punto di vista del Principio di Località Temporale, perché si rischia di sostituire un blocco che è stato referenziato di recente. Dal punto di vista dei costi, si può facilmente notare, che il metodo LRU richiede una complessità di realizzazione superiore al metodo FIFO. FALLIMENTI DI ACCESSO ALLA CACHE legge delle tre C Un modello intuitivo del comportamento delle memorie cache attribuisce tutti i fallimenti a una delle tre cause che seguono: 1. Obbligatorietà (Compulsory): al primo accesso un blocco non è presente nella cache e deve esservi trasferito. Tali fallimenti vengono definiti fallimenti di partenza a freddo (cold start misses) oppure fallimenti di primo accesso (first reference misses). 2. Capacità (Capacity): se la cache non può contenere tutti i blocchi necessari all esecuzione di un programma, i fallimenti causati dalla capacità sono quelli connessi ai blocchi che devono essere scartati e ripresi più tardi. 3. Conflitto (Conflict): se la strategia di piazzamento dei blocchi è set-associativa oppure a indirizzamento diretto, vi saranno dei fallimenti dovuti ai conflitti (oltre a quelli obbligatori o di capacità) causati dai blocchi che bisogna scartare e recuperare più tardi perché troppi blocchi devono essere caricati nello stesso insieme. Essi sono detti anche fallimenti per collisione (collision misses). Pagina 69

70 STRATEGIE DI SCRITTURA NELLA CACHE Innanzitutto bisogna dire che le letture dominano gli accessi alla cache. Tutti gli accessi per le istruzioni sono letture, inoltre molte istruzioni non scrivono in memoria. Sembrerebbe quindi che ottimizzando le operazioni di lettura si migliorerebbero le prestazioni della cache. Ciò è vero solo parzialmente. La legge di Amdahl stabilisce infatti che progetti mirati a ottenere alte prestazioni non possono trascurare le operazioni di scrittura. L operazione più frequente, cioè la lettura di una linea, può essere resa facilmente più veloce effettuandola contemporaneamente alle operazioni di lettura e verifica dell etichetta. Perciò la lettura della linea, può iniziare non appena il suo indirizzo è disponibile. Se l accesso riesce, allora la linea viene passata subito alla CPU. Se invece fallisce non c è alcun beneficio, ma neppure un danno. Questo non succede per le operazioni di scrittura. Il processore specifica la dimensione del dato da scrivere; solo una particolare parte della linea può essere modificata. In generale ciò significa che sulla linea viene eseguita una sequenza leggi > modifica > scrivi: viene letta la linea originale, ne viene modificata una parte e, infine, viene scritta la linea con il nuovo valore. Oltretutto, la modifica della linea non può iniziare finché l etichetta non è stata controllata per verificare la riuscita dell accesso. Poiché la valutazione dell etichetta non può avvenire in parallelo, le operazioni di scrittura richiedono più tempo di quelle di lettura. Perciò è la politica di scrittura che distingue molti progetti di memorie cache. Le strategie di scrittura più tipiche sono due: 1. WRITE THROUGH: l informazione viene scritta sia nel blocco della cache, sia nel blocco del livello inferiore della memoria. Nel caso di politica write through, lo stato in cui si trova la CPU che aspetta il termine di un operazione di scrittura prende il nome di stallo di scrittura (write stall), in effetti l operazione di scrittura avviene alla velocità della memoria centrale. Un ottimizzazione utilizzata di solito per ridurre il tempo di stallo consiste nell inserimento di un buffer di scrittura che consente al processore di proseguire mentre la memoria viene modificata. Questo buffer è costituito nella seguente maniera: essendo un buffer è organizzato da un insieme di celle in coda; vi è lo spazio non solo per contenere i dati ma anche, per ogni cella, un etichetta che indica in quale indirizzo della memoria il dato deve essere scritto. Inoltre nell etichetta vi è anche una sorta di bit di validità, il quale assicura che se nel buffer vi è un dato ripetuto ma modificato, viene invalidato quello che deve ancora uscire; in questa maniera il processo di scrittura in memoria centrale è velocizzato. Comunque, uno stallo di scrittura è possibile anche in presenza di un buffer di scrittura, poiché esso è di dimensioni limitate. CPU CACHE MEMORIA CENTRALE I/O 2. WRITE BACK: l informazione viene scritta solo nel blocco della cache. Il blocco della cache modificato viene scritto nella memoria principale solo quando viene sostituito. Definizione: Un blocco in una cache di tipo Write Back viene definito pulito (clean) o sporco (dirty) a seconda che l informazione immagazzinata nella cache sia uguale o diversa da quella presente nel livello inferiore di memoria. CPU CACHE MEMORIA CENTRALE I/O I vantaggi della strategia WT sono: semplice implementazione; cache sempre clean; il livello gerarchico inferiore dispone della copia più recente dei dati. Pagina 70

71 I vantaggi della strategia WB sono: le operazioni di scrittura avvengono alla velocità della cache; scritture multiple eseguite sullo stesso blocco richiedono una sola operazione di scrittura. Bisogna comunque considerare che l architettura di un elaboratore prevede anche la presenza dell I/O; per cui è necessario analizzare il comportamento di queste due tecniche nelle situazioni in cui vengono effettuati Input e Output di blocchi da e verso l I/O. INPUT (I/O MEM. CENTRALE): in entrambe le tecniche nel caso in cui l I/O vada a modificare un blocco della memoria centrale, in cache si avranno i dati, contenuti in quel blocco, scaduti (se quel blocco è stato precedentemente scritto in cache); OUTPUT (MEM. CENTRALE I/O): con la tecnica Write Back l I/O troverà dei dati scaduti in memoria centrale, cosa che non succede con la tecnica Write Through. Per ridurre la frequenza delle operazioni di scrittura dei blocchi quando vengono sostituiti viene comunemente utilizzato un bit di modifica (dirty bit). Definizione: Il bit di modifica (dirty bit) è un bit di stato che indica se il blocco, durante la sua permanenza nella cache, è stato modificato. Se è rimasto invariato, il blocco non viene scritto, visto che il livello inferiore di memoria contiene le stesse informazioni della cache. ELETTRONICA DELLE MEMORIE È possibile realizzare memorie utilizzando le seguenti due tecnologie: SRAM (Static RAM): il contenuto è mantenuto costante nel tempo (finché c è tensione di alimentazione), per cui non è necessario il refresh della memoria; la sua realizzazione richiede 6 transistor per ogni cella memorizzante un singolo bit. Questo tipo di realizzazione richiede un maggiore spazio fisico, ma in compenso offre maggiore velocità; è tipicamente usata nelle cache all interno dei processori. Circuito di una cella di memoria SRAM. DRAM (Dynamic RAM): il contenuto è mantenuto per un periodo che dipende dal tempo di scarica del condensatore, per cui è necessario il refresh della memoria; la sua realizzazione richiede 1 transistor e 1 condensatore per ogni cella memorizzante un singolo bit. Questo tipo di realizzazione richiede un minore spazio fisico, ma non offre elevate velocità (causa del refresh); è tipicamente usata nelle realizzazioni di memorie centrali. Circuito di una cella di memoria DRAM. Pagina 71

72 VALUTAZIONE DELLE PRESTAZIONI DELLA MEMORIA CACHE Prima di valutare le prestazioni, fondamentali per la progettazione di una memoria cache, è utile chiarire alcuni concetti fondamentali. La CPU indirizza solo la memoria principale; l indirizzo generato dalla CPU viene però intercettato dalla cache. Se la cache possiede questo indirizzo, l accesso a memoria ha avuto successo (HIT); se non vi è questo indirizzo, l accesso a memoria non ha avuto successo (MISS) e la cache invia un segnale al piedino di WAIT del processore per bloccare il clock. La cache realizza un effettivo vantaggio in velocità solo se i dati rispettano i due principi di località visti in precedenza. Infatti, all accensione di un computer, questo sarà lento, perché deve rispettare l obbligatorietà, cioè è obbligato a caricare certi dati distanti in memoria tra loro. Di seguito vengono definiti i significati di: Hit Rate, Miss Rate, Hit Time e Miss Penality. HIT RATE: percentuale di tentativi di accesso che hanno avuto successo; MISS RATE: percentuale di tentativi di accesso falliti, per cui: MR = 1 HR; HIT TIME: tempo di accesso al livello inferiore della gerarchia di memoria, che comprende anche il tempo necessario a determinare se l accesso ha successo oppure fallisce; MISS PENALITY (Penalizzazione di fallimento): tempo necessario a sostituire un blocco nel livello superiore con un blocco preso dal livello inferiore più il tempo impiegato per trasferire le informazioni al centro che li aveva richieste, la CPU. La penalizzazione di fallimento viene a sua volta suddivisa in due componenti: il tempo di accesso, ossia il tempo necessario per accedere alla prima parola del blocco richiesto dopo che è stato rilevato il fallimento, ed il tempo di trasferimento, che indica il tempo utilizzato per trasferire le altre parole del blocco. Il tempo di accesso è collegato alla latenza del livello inferiore nella gerarchia di memoria, mentre il tempo di trasferimento è collegato alla larghezza di banda del canale tra i due livelli di memoria. Vediamo ora come è possibile effettuare una misura delle prestazioni di una memoria cache considerando il tempo di CPU, il quale può essere diviso nei cicli che la CPU spende eseguendo il programma e in quelli che la CPU trascorre in attesa di risposta dal sistema di memoria. Perciò: TEMPO DI CPU = = CICLI DI CPU IN ESECUZIONE + CICLI DI STALLO IN MEMORIA TEMPO DEL CICLO DI CLOCK Per semplificare la valutazione delle alternative durante il progetto della cache spesso si adotta l ipotesi che tutti gli stalli di memoria siano dovuti alla cache. Ciò è vero per molte macchine; anche in quelle macchine che non verificano tale ipotesi, la cache è la causa principale degli stalli, benché questi non siano dovuti esclusivamente ad essa. Per chiarire il senso della formula scritta sopra bisogna stabilire se il ciclo di clock utilizzato per un accesso alla cache debba essere considerato parte dei cicli di CPU in esecuzione o parte dei cicli di stallo di memoria. Entrambe le ipotesi sono plausibili, ma la più comunemente accettata è quella secondo cui i cicli per un accesso riuscito vanno inclusi nei cicli di CPU in esecuzione. I cicli di stallo di memoria possono quindi essere definiti in termini di numero di accessi alla memoria per programma, di penalizzazione di fallimento (misurata in cicli di clock) e miss rate per operazioni di lettura e di scrittura: = CICLI DI STALLO IN MEMORIA = CICLI DI STALLO IN LETTURA + CICLI DI STALLO IN SCRITTURA = LETTURE IN MEMORIA PROGRAMMA SCRITTURE IN MEMORIA PROGRAMMA MISS RATE PER LE LETTURE PENALIZZAZIONE DI FALLIMENTO PER LE LETTURE + MISS RATE PER LE SCRITTURE PENALIZZAZIONE DI FALLIMENTO PER LE SCRITTURE Pagina 72

73 La relazione che lega la penalizzazione di fallimento alla dimensione del blocco e la relazione che lega il miss rate alla dimensione del blocco sono riportate nelle seguenti figure: Pollution Point Queste rappresentazioni si basano sull ipotesi che la dimensione del livello superiore della memoria non cambi; osservando il primo grafico si può notare che la parte della penalizzazione di fallimento correlata al tempo di accesso rimane costante al variare della dimensione del blocco; il tempo di trasferimento, invece, cresce proporzionalmente alla dimensione del blocco. Osservando il secondo grafico si nota che l incremento delle dimensioni di un blocco provoca una diminuzione del miss rate fino a quando la riduzione dei fallimenti collegati alle maggiori dimensioni dei blocchi (località spaziale) è superiore all aumento dei fallimenti collegato con la diminuzione del numero dei blocchi (località temporale). In pratica, ciò che succede è che man mano che la dimensione di un blocco cresce, la parte del blocco che non viene utilizzata è così grande da sovrapporsi a informazioni utili presenti in precedenza nella cache; a questo punto il miss rate comincia a crescere. Il punto della curva, sulla destra, in cui il miss rate inizia ad aumentare al crescere delle dimensioni del blocco viene a volte definito punto di contaminazione (pollution point). Per cui si è portati a scegliere la dimensione del blocco pari al minimo della curva; effettuando questa scelta si va a minimizzare il Miss Rate, ma l obiettivo del progettista è quello di scegliere la dimensione del blocco che permetta di avere il più piccolo possibile il tempo medio di accesso alla memoria e non del numero di fallimenti; il tempo medio di accesso alla memoria è pari a: TEMPO MEDIO DI ACCESSO ALLA MEMORIA = HIT TIME + MISS RATE PENALIZZAZIONE DI FALLIMENTO Per cui il valore da scegliere è approssimativamente il punto minimo preso sulla curva ottenuta dal prodotto dei due grafici: x Dimensione del blocco da considerare: arrotondare alla potenza di 2 più vicina Pagina 73

74 SCHEMA RIASSUNTIVO DEI VANTAGGI/SVANTAGGI DELLE TECNICHE E DEI METODI ANALIZZATI aumentando VANTAGGI SVANTAGGI ASSOCIATIVITA DIMENSIONE BLOCCHI POLITICA LRU BUFFER DI SCRITTURA - Minor numero di conflitti - Benefici in cache di medie dimensioni - Maggiori costi: ampiezza delle etichette e aggiunta di comparatori - Politica di sostituzione più costosa - Minor numero di etichette - Maggior tempo di trasferimento - Minor Miss Rate per cache a bassa associatività - Maggior costo hardware - Minor stallo di scrittura - Maggior costo hardware Pagina 74

75 FUNZIONAMENTO LOGICO DI UNA MEMORIA CACHE Per descrivere il funzionamento logico verranno presi in esame due casi reali: la memoria cache del PowerPC e quella del processore Motorola Cache PowerPC CARATTERISTICHE: - FORMATO ISTRUZIONI: 32 bit - ORGANIZZAZIONE DELLA CACHE: Cache istruzioni e dati separate; - DIMENSIONE DELLA CACHE: 16 Kbyte per ciascuna cache; - ASSOCIATIVITA DELLA CACHE: Set associativa a 4 linee; - SOSTITUZIONE: tecnica LRU; - DIMENSIONE DEI BLOCCHI: 32 Byte (8 word da 4 byte per ogni blocco); - GESTIONE DELLE OPERAZIONI DI SCRITTURA: prevalentemente Write back, ma anche Write Through. Stando a queste caratteristiche ogni set è di 128 Byte; per cui essendo la cache di 16 Kbyte si hanno 128 set, infatti: = 128. L etichetta di ogni linea oltre a comprendere l indirizzo ha 2 bit (xy) per codificare 4 stati: - 2 stati per codificare il cambio di parola e la validità della linea (CHANGE BIT & VALID BIT); - 2 stati per codificare situazioni particolari quando la cache è utilizzata nei sistemi multi processorie. L indirizzo di 32 bit inviato alla cache viene suddiviso in tre campi: 20 bit 7 bit 5 bit 32 bit - Il campo costituito dai 5 bit meno significativi dell indirizzo serve per puntare ai 32 byte interni al blocco; - Il campo costituito dai 7 bit indirizza in maniera diretta uno dei 128 set; - Il campo costituito dai 20 bit serve per effettuare il confronto con l etichette delle quattro linee del set individuato. Il confronto avverrà in parallelo: i 20 bit vengono inviati in parallelo a quattro comporatori, ciascuno dei quali riceverà come secondo operando un etichetta. Se l uguaglianza è verificata in uscita da uno dei quattro comparatori vi è un 1; poi l uscita alta del comparatore viene messa in AND con il Valid Bit per assicurare la validità della linea; se la validità è verificata il dato è quindi presente in cache (HIT). I 7 bit fungono da selettori per dei multiplexer che devono selezionare quale linea deve andare in ingresso al comparatore per il confronto dell etichetta. L uscita della AND va in ingresso a un demultiplxer il quale manderà sulla linea selezionata il risultato dell intero lavoro, ovvero il dato richiesto dalla CPU. Pagina 75

76 Di seguito è riportata un figura che implementa il funzionamento logico della cache del PowerPC. xy: codificano se la linea è valida o meno; : LINEE : LINEE : LINEE : LINEE 11 = : COMPARATORE : PORTA AND Pagina 76

77 Cache MOTOROLA CARATTERISTICHE: - FORMATO ISTRUZIONI: 32 bit - ORGANIZZAZIONE DELLA CACHE: Cache istruzioni e dati separate; - DIMENSIONE DELLA CACHE: 4 Kbyte per ciascuna cache; - ASSOCIATIVITA DELLA CACHE: Set associativa a 4 linee; - SOSTITUZIONE: tecnica RANDOM; - DIMENSIONE DEI BLOCCHI: 16 Byte (4 word da 4 byte per ogni linea); - GESTIONE DELLE OPERAZIONI DI SCRITTURA: Write back o Write Through Stando a queste caratteristiche ogni set è di 64 Byte; per cui essendo la cache di 4 Kbyte si hanno 64 set, infatti: = 64. L etichetta di ogni linea oltre a comprendere l indirizzo ha 2 bit, uno per identificare la validità (Valid Bit) e uno per identificare la modifica (Dirty Bit, questo bit è presente per ogni word); quindi avendo un bit di modifica per ogni parola, nel caso di gestione Word Through, in memoria centrale verrà sostituita la sola word interessata e non l intero blocco. L indirizzo di 32 bit inviato alla cache viene suddiviso in tre campi: 22 bit 6 bit 4 bit 32 bit - Il campo costituito dai 4 bit meno significativi dell indirizzo serve per puntare ai 16 byte interni al blocco; - Il campo costituito dai 6 bit indirizza in maniera diretta uno dei 64 set; - Il campo costituito dai 22 bit serve per effettuare il confronto con l etichette delle quattro linee del set individuato. Il confronto avverrà in parallelo: i 22 bit vengono inviati in parallelo a quattro comporatori, ciascuno dei quali riceverà come secondo operando un etichetta. Se l uguaglianza è verificata in uscita da uno dei quattro comparatori vi è un 1; poi l uscita alta del comparatore viene messa in AND con il Valid Bit per assicurare la validità della linea; se la validità è verificata il dato è quindi presente in cache (HIT). I 6 bit fungono da selettori per dei multiplexer che devono selezionare quale linea deve andare in ingresso al comparatore per il confronto dell etichetta. L uscita della AND va in ingresso a un demultiplxer il quale manderà sulla linea selezionata il risultato dell intero lavoro, ovvero il dato richiesto dalla CPU. La figura che implementa il funzionamento logico della cache del Motorola è simile a quella del PowePC con dovuti accorgimenti vista la minima differenza di funzionamento. Pagina 77

78 INTERAZIONE DELLE MEMORIE CACHE IN UN SISTEMA COMPLESSO PROBLEMATICHE RELATIVE ALL I/O Si consideri un sistema in cui la memoria cache ha una tecnica di gestione della scrittura di tipo Write Through; come già detto con questa gestione la memoria centrale riceverà sempre aggiornamenti dalla cache, per cui vi sarà sempre coerenza fra i blocchi di cache e di memoria centrale. Il problema sorge quando il modulo I/O effettua operazioni di scrittura in memoria centrale. Questa operazione comporta dei dati scaduti in memoria cache. Quindi il sistema deve essere in qualche maniera modificato per evitare questo tipo di problematica. Innanzitutto è impensabile collegare I/O e cache in modo tale da effettuare input direttamente in memoria cache; questa soluzione risolverebbe i problemi relativi ai conflitti ma porta a far diventare la cache il collo di bottiglia dell intero sistema, abbattendo le sue prestazioni. Per cui una soluzione può essere quella di far monitorare dalla cache l input da parte dell I/O in memoria centrale; questo monitoraggio può essere fatto sia cambiando il Valid Bit del blocco che eventualmente cambierà di valore, soluzione semplice, oppure, poichè il dato è ancora sul bus, è possibile prelevarlo è scriverlo all interlo del blocco interessato aggiornandolo, operando così una scelta meno dispendiosa ma forse inutile (il blocco potrebbe non essere più utilizzato). PROBLEMATICHE RELATIVE AI SISTEMI MULTICORE CPU 1 CPU 2 CPU 3 CACHE CACHE CACHE MEM. CENTRALE I/O La memoria centrale è condivisa fra più memorie cache di diverse CPU; la connessione fra una singola cache e la memoria centrale non avviene in maniera indipendente dalle altre connessioni, ma attraverso un bus che è osservato e monitorato da tutte le cache, in maniera tale che se la tecnica di gestione è Write Through ed una cache sta scrivendo in memoria centrale, le altre cache potranno eventualmente aggiornare i loro blocchi se interessati dall operazione di scrittura. Pagina 78

79 MIGLIORAMENTO DELLE PRESTAZIONI DELLA BANDA PASSANTE DI UNA MEMORIA La banda passante della memoria è quel parametro che identifica la quantità d informazione che è possibile leggere e scrivere nella data memoria in un determinato tempo: B = I byte T s Essendo un rapporto è possibile aumentare la banda passante in due modi: aumentando l informazione oppure dimunendo il tempo. Vediamo due tecniche di architettura che portano ad aumentare l informazione o a diminuire il tempo. Il primo approccio consiste nel realizzare dei Banchi multipli di memoria paralleli: Si consideri una certa tecnologia che fornisce una certa banda passante; è semplice ottenere una banda maggiore se si considera ad esempio la seguente situazione. Quattro moduli di memoria da 1Kbyte per formare un memoria di 4Kbyte (dal punto di vista esterno la memoria risulta un unico chip di 4Kbyte); ogni modulo ha una propria banda passante b. Se ad esempio una parola da 4 byte è contenuta in un singolo modulo, la si otterebbe in un determinato tempo; però se la stessa parola, la si va ad immaginare divisa in ogni modulo di memoria (1 byte per ogni modulo), si ottiene la stessa banda che è aumentata di quattro. Semplicemente ogni byte che compone la parola è scritto allo stesso indirizzo; essendo la memoria di 4K sarà indirizzata da indirizzi a 12 bit. Questo indirizzo avrà la particolarità di avere i due bit meno significativi uguali a zero, i restanti 10 bit vengono mandati alla porta indirizzi di ogni modulo da un 1K. Con questi 10 bit ogni chip individuerà un byte che andrà in uscita dal chip. Questi 8 bit che escono, da ciascun modulo, messi insieme formano i 32 bit del dato. 10 bit bit 1Kbyte 1Kbyte 1Kbyte 1Kbyte 8 bit 8 bit 8 bit 8 bit 4 Kbyte 32 bit Una tecnica meno semplice è quella dei Banchi Interlacciati: questa tecnica permette di ridurre il tempo. Consideriamo ad esempio sempre i 4 moduli distinti i quali in un certo tempo in uscita hanno 32 bit (per cui ogni modulo può essere pensato come un insieme dei banchi multipli di memoria visti in precedenza). Ogni modulo è di 1 Kbyte, per cui ricevono un indirizzo di 10 bit; dovendo tirare fuori 32 bit (parole di 4 byte) dei 10 bit che ne ricevono i due meno significativi sono uguali a zero. L indirizzo che arriva all intera memoria è un indirizzo di 12 bit, di cui i due meno significativi sono uguali a zero; i 10 bit rimanenti, a loro volto sono suddivisi in 2 bit meno significativi e 8 bit più significativi. La word non sarà suddivisa nei vari moduli, ma sarà messa per intera in un modulo. Per cui ogni modulo conterrà word intere, con questa logica: MODULO 1 MODULO 2 MODULO 3 MODULO 4 Ind. 0 WORD 0 WORD 1 WORD 2 WORD 3 Ind. 1 WORD 4 WORD 5 WORD 6 WORD 7 Ind. 2 WORD 8 WORD 9 WORD 10 WORD 11 Per cui in ingresso ad ogni modulo si hanno gli 8 bit più significativi dei 12 più 2 bit uguali a zero. Pagina 79

80 Poi i 32 bit uscenti da ogni singolo modulo vanno in un MUX che userà i 2 bit meno significativi dei 12 come selettore per decidere quale indirizzo da 32 bit deve passare. I 10 bit in ingresso ai moduli andranno a cercare la parola richiesta, la quale andrà poi in ingresso al MUX per la selezione: ad esempio se i 10 bit richiedono la word che si trova all indirizzo 2, i moduli daranno in uscita rispettivamente: MODULO 1 word 8; MODULO 2 word 9; MODULO 3 word 10; MODULO 4 word 11; Queste word andranno in ingresso al MUX che ne selezionerà una grazie ai 2 bit di selezione; la figura che riassume la tecnica dei moduli interlacciati è la seguente. 8 bit 2 bit bit 8 bit 00 8 bit 00 8 bit 00 8 bit 00 1Kbyte 1Kbyte 1Kbyte 1Kbyte 32 bit 32 bit 32 bit 32 bit 4 Kbyte 32 bit Con questa tecnica è vero che per il prelievo della prima word si impiegherà più tempo, dovuto al selettore (T + t s ), ma nel momento in cui si va a chiedere la seconda word, questa sarà subito pronta, infatti il tempo di attesa sarà solo quello del selettore (t s ). Così via per le altre word. Questa tecnica funziona sicuramente se applicata alla memoria centrale, poiché la cache chiede alla memoria centrale blocchi di word consecutive, mentre non si applica alla memoria cache perché la CPU chiede solo word, per cui si vuole realizzare una tecnica più veloce. Pagina 80

81 ORGANIZZAZIONE DELLE MEMORIE A SEMICONDUTTORE Le memorie a semiconduttore sono costituite da celle organizzate in righe e colonne che realizzano una geometria quadrata; viene effettuata questa scelta seguendo due considerazioni: 1. La prima considerazione da fare è di tipo strutturale: è chiaro che un dispositivo costituito da materiale semiconduttore ha una fragilità maggiore rispetto ad un altro materiale, per cui la forma quadrata rende difficoltosa la rottura. 2. La seconda considerazione, che è il vero motivo per cui si preferisce una geometria quadrata, è prettamente riferita al modo in cui la memoria viene indirizzata: nel momento in cui si forniscono a questo dispositivo dei bit che devono essere codificati per individuare qual è la cella interessata, è bene che questa decodifica avvenga attraverso la specifica delle rige e delle colonne, nel senso che invece di avere un sistema che riceve, ad esempio per una memoria di un 1 Kbyte, 10 bit di indirizzo e li decodifica per arrivare ad indirizzare una cella, è meglio che l operazione di input/output della cella avvenga attraverso due decodifiche simultane ciascuna delle quali prende un certo numero di bit dell indirizzo; la combinazione di queste due decodifiche permette l accesso alla cella. Essendo le decodifiche simultanee allora questo meccanismo funzionerebbe anche nel caso in cui la geometria fosse rettagolare; tuttavia se l operazioni di decodifica non avvengono parallelamente, ma in serie, prima una e poi l altra, allora risulta utile utilizzare una geometria quadrata. Questo perché i due blocchi di decodifica sono identici, ricevono lo stesso numero di bit, per cui è immediato pensare di utilizzarne solamente uno il quale prima riceve un numero di bit per individuare la riga e poi riceve i restanti bit per individuare la colonna; allora la memoria sarà costituita da un decodificatore che riceve in un primo istante, ad esempio di un indirizzo di 10 bit, solo 5 bit i quali verranno decodificati per individuare la riga. In un secondo istante riceverà i restanti 5 bit i quali verranno decodificati per individuare la colonna. La riga individuata, viene mandata su un buffer di riga; su questo buffer andrà ad operare il risultato della decodifica per individuare la colonna, e quindi infine si accede alla cella interessata. Sembrerebbe, utilizzando questo metodo, di rendere la memoria lenta e quindi di avere una perdita di prestazioni, invece, non solo si risparmia sul decodificatore e sul numero di piedini che costituiscono la memoria, ma anche sui tempi di accesso ai dati; i dati immediatamente successivi non richiederano la ricodifica della riga, la quale è già presente sul buffer, ma solo la decodifica della colonna. Per cui solo il primo dato farebbe risultare lento questo tipo di organizzazione. In questa figura è riportata una tipica struttura a matrice quadrata (8x8) di una memoria ad accesso casuale (RAM). Pagina 81

82 Appunti di Calcolatori Elettronici A.A. ESERCIZI DI RIEPILOGO ESERCIZIO 1 Dimensionare i campi (etichetta, set, spiazzamento) dell indirizzo a una memori di 4 MByte qualora essa sia associata ad una cache da 256 KB con parole di 4 Byte e blocchi da 16 Byte nel caso di indirizzamento set-associativo (set di 8 blocchi). Per indirizzare una memoria di 4 MB sono sufficienti 22 bit, da suddividere in etichetta (parte più significativa), set, spiazzamento (parte meno significativa). Il campo spiazzamento, per poter indirizzare uno fra 16 byte deve richiedere 4 bit, di cui gli ultimi 2 impostati a "00", in quanto le parole indirizzate sono di 4 byte. Essendo il numero dei set pari a 256 𝐾𝐵 8 16𝐵 = 211, 11 bit saranno necessari al campo set per selezionare in maniera diretta il set di interesse. Quindi, per differenza, i 7 (= ) bit più significativi costituiranno il campo etichetta. INDIRIZZO (22 bit) SET yyy yyyy yyyy ETICHETTA xxx xxxx SPIAZZAMENTO zz00 (x, y, z indicano dei bit di valore non specificato). ESERCIZIO 2 Dato uno spazio di indirizzi di 4 GB specificare i campi e le etichette che si strutturano per l uso di cache nei seguenti casi: 1. cache set associativa a 4 set da 16 blocchi, ciascun blocco comprendente 64 words 2. cache ad indirizzamento diretto con 128 blocchi da 32 words 3. cache completamente associativa di 16 MB con 256 blocchi. Il processore invia un indirizzo pensando di avere una memoria di 4 GB per cui l indirizzo richiede 32 bit per indirizzare una word (4 Byte). Cache set associativa a 4 set da 16 blocchi con ciascun blocco da 64 words per cui la cache sarà così costituita: SET 0 SET 1 SET 2 SET 3 Il campo indirizzo, dovendo puntare all'interno di un blocco ad una fra 64 words, utilizzerà 8 bit (di cui gli ultimi due pari a 0). Essendo 4 i set, 2 bit saranno nel campo per indirizzare il set, e i rimanenti = 22 bit più significativi comporranno l'etichetta. INDIRIZZO (32 bit) ETICHETTA SET SPIAZZAMENTO xx xxxx xxxx xxxx xxxx xxxx yy zzzz zz00 (x, y, z indicano dei bit di valore non specificato). Pagina 82

83 Cache ad indirizzamento diretto con 128 blocchi da 32 words; numero di blocchi in memoria = 4 GB 32 4 byte = 2 25 ; numero di bit necessari per indirizzare un blocco in memoria = 25 bit, di cui la parte meno significativa di log 2 (128) = 7 bit sarà utilizzata per puntare al blocco in cache e i rimanenti 25 7 = 18 bit di etichetta. INDIRIZZO (32 bit) ETICHETTA LINEA SPIAZZAMENTO xx xxxx xxxx xxxx xxxx yyy yyyy zzz zz00 (x, y, z indicano dei bit di valore non specificato). Cache completamente associativa di 16 MB con 256 blocchi Se la cache è completamente associativa allora il blocco può essere inserito in una qualsiasi posizione della cache; per questo avrà bisogno, per l etichetta, dell intero indirizzo del blocco, a meno degli N bit meno significativi utili a puntare alla specifica parola all'interno del blocco. Nella fattispecie, si ha: numero di byte di un blocco = 16 MB 256 = 2 16 byte Da cui: N = 16 bit (di cui i 2 meno significativi pari a "00" per puntar a parole di 4 byte. INDIRIZZO (32 bit) ETICHETTA SPIAZZAMENTO xxxx xxxx xxxx xxxx zzzz zzzz zzzz zz00 (x, y, z indicano dei bit di valore non specificato). Pagina 83

84 PARTE TERZA PARTE TERZA PROCESSORE SCALARE ARCHITETTURA FLOATING POINT Pagina 84

85 PROCESSORE FLOATING POINT Vediamo ora come è possibile estendere la pipeline MIPS per gestire operazioni con dati floating point. Le fasi di IF, ID, MEM e di WB sono analoghe a quelle per gestire dati interi; i gruppi di registri saranno diversi da quelli interi, ma comunque elettronicamente identici. Ciò che veramente cambia è quello che avviene nella fase EX; mentre nell aritmetica intera si ha l ALU che in un tempo più o meno simile effettua una qualsiasi operazione, nell aritmetica in virgola mobile questo non è più vero, infatti le stesse operazioni con dati floating point richiedono tempi abbastanza diversi di esecuzione. Ad esempio si pensi alle operazioni da effettuare per una addizione di due numeri floating point: Confronto degli esponenti; Shift della mantissa del numero che ha esponente minore di un numero di posti pari alla differenza degli esponenti; Somma delle due mantisse; Aggiornamento dell esponente a quello maggiore; Tutto questo, ovviamente, non può essere fatto in un tempo analogo a quello necessario per una somma di due interi. Essendo quindi la durata delle operazioni significativamente diversa, si hanno di fronte due scelte: una scelta può essere quella di ridurre la frequenza del clock del sistema andando a dilatare il tempo di una fase rendendolo pari a quella della fase più lenta, in questo modo il processore eseguirà, in pipeline, le sue operazioni sempre in 5 fasi ma con tempi molto più lunghi, però comunque ogni fase sarà sempre in contemporanea ad altre e soprattutto sempre in ordine. Alternativamente per eseguire operazioni con dati floating point è possibile pensare di far durare la fase EX non un colpo di clock sufficientemente ampio, ma un numero di colpi di clock quant è la durata del clock che si adatta meglio per misurare la singola fase all interno del processore. In questo modo le istruzioni avranno fasi che durano il minimo indispensabile; nonostante questa tecnica possa sembrare più vantaggiosa è possibile avere il caso in cui un istruzione, che potrebbe durare molto più dei soliti cinque colpi di clock, ad esempio una divisone floating point che ha la fase EX lunga circa venti colpi di clock, e quindi la fase EX verrebbe dilatata, e se successivamente quando questa è ancora in esecuzione dovesse entrare nella pipeline un altra istruzione che utilizza meno colpi di clock, questa terminerebbe prima. Per cui si ha quello che viene definita TERMINAZIONE DELLE ISTRUZIONI FUORI ORDINE, cioè un istruzione successiva ad un altra termina prima. Finché l istruzione successiva lavora con numeri interi non ci sono problemi, questo perché l istruzione floating point utilizza dati che si trovano nei registri dedicati ai dati floating point, mentre l istruzione intera utilizza dati che si trovano nei registri dedicati ai dati interi. Però se l istruzione successiva, operante anch essa con dati floating point termina prima, ad esempio è una somma, potrebbero causarsi problemi seri; per cui è molto facile il verificarsi dei tre azzardi di dato: RAW, WAR, WAW. Per far fronte a questi problemi la control unit risulterà molto più complessa, poiché dovrà monitorare attentamente le unità di calcolo che, per una scelta appropriata, non sono tutte assemblate in un unico blocco. Questa scelta è alla base per evitare il congelamento dell unità di calcolo da parte di quelle istruzioni che richiedono un fase EX molto ampia. Pagina 85

86 Di seguito è riportata una figura che riassume la logica delle unità di calcolo separata, con i tre blocchi aggiuntivi per le operazioni floating point. È evidente che se un istruzione, come ad esempio una divisione, occupa per molto tempo il divisore, una possibile istruzione successiva che richiede anch essa il divisore andrà in stallo finché l istruzione precedente non avrà rilasciato l unità di elaborazione. Per cui è possibile pensare di organizzare in pipeline anche le varie unità di calcolo, in maniera tale da poter far ricevere altri dati, non quando l istruzione precedente finisce e libera l unità ma, bensì, quando libera la parte iniziale dell unità. La seguente figura riassume la logica della pipeline applicata alle unità di calcolo. Per cui il processore nella fase EX è pensato in maniera diversa. Pagina 86

87 Qui accanto è riportata una figura in cui si vede come le unità di calcolo, non pipeline, interagiscono con il banco dei registri. È presente uno Scoreboard il quale è un meccanismo logico che regola l accesso ai registri, verificando che non vi siano conflitti precedentemente citati. La presenza di un ulteriore moltiplicatore è giustificata dal fatto che statisticamente da un punto di vista della prestazioni non è efficiente aspettare sette colpi di clock tra una moltiplicazione ed un altra. Per cui ad esempio non è conveniente aggiungere un sommatore in più. È immediato pensare allora di aggiungere un divisore in più a questa struttura, visto che un operazione di divisione porta via circa 24 colpi di clock; in realtà questo non è stato fatto sia perché statisticamente le divisioni sono operazioni meno frequenti rispetto alle moltiplicazioni e sia perché un divisore, dal punto di vista hardware, è notevolmente più complesso. Di seguito è riportata la tabella con un riepilogo di alcune le istruzioni che costituiscono il sottoinsieme di istruzioni di MIPS64. Virgola mobile: operazioni in virgola mobile in formato SP e DP Tipo di istruzione/codice operativo ADD.D, ADD.S, ADD.PS SUB.D, SUB.S, SUB.PS MUL.D, MUL.S, MUL.PS MADD.D, MADD.S, MADD.PS DIV.D, DIV.S, DIV.PS CVT._._ C..D, C..S MFC1, MTC1 Significato dell istruzione Addiziona numeri in DP, in SP e coppie di numeri in SP Sottrai numeri in DP, in SP e coppie di numeri in SP Moltiplica numeri in DP, in SP e coppie di numeri in SP Moltiplica e addiziona numeri in DP, in SP e coppie di numeri in SP Dividi numeri in DP, in SP e coppie di numeri in SP Istruzioni di conversione: CVT.x.y converte dal tipo x al tipo y, che possono essere L (interi a 64 bit), W( interi a 32 bit), D(DP) o S(SP). Entrambi gli operandi sono registri in virgola mobile. Confronti tra DP e SP; al posto di ci può essere: LT; GT, LE, GE, EQ, NE; imposta il bit opportuno nel registro di stato per la virgola mobile Copia da 32 bit in/da registri in virgola mobile da/in registri interi Pagina 87

88 SCHEDULING DELLE ISTRUZIONI FLOATING POINT Le unità di calcolo floating point hanno una latenza che non è simile indipendentemente dalle operazioni; la differenza, in termini di colpi di clock, fra una operazione ad aritmetica intera e una in floating point comincia ad essere significativa. Una scelta semplice sarebbe quella di dimensionare il clock in base all operazione che richiede più tempo, facendo sì che dilatando la latenza sia possibile effettuare tutte le operazioni; però questo determina uno spreco di tempo soprattutto nei casi in cui un programma fa uso solo ed esclusivamente dell unità in aritmetica intera, poiché queste operazioni dovranno durare quanto la più lunga operazione in floating point. Allora non si dilata il clock ma si garantisce all unità floating point un certo numero di colpi di clock per le operazioni da effettuare, consentendo di eseguire velocemente le istruzioni che non fanno uso delle unità floating point. Il problema che si viene a creare è che questi tempi portano inevitabilmente a degli stalli e conflitti precedentemente analizzati; ad esempio una operazione di divisione in aritmetica floating point seguita da una operazione di load, le quali utilizzano uno stesso registro destinazione, terminerebbe dopo quest ultima, generando evidentemente un conflitto di tipo WAW. DDIV.D F4 LOAD F4 Per cui queste tipo di problematiche portano a realizzare unità di calcolo più sofisticate in modo tale da diminuire il tempo sprecato dovuto alla dilatazione del clock. Si utilizza l'algoritmo di Tomasulo, algoritmo sviluppato dal ricercatore dell'ibm Robert Tomasulo per permettere l'esecuzione fuori ordine delle istruzioni. La sua prima implementazione si è avuta nell'unità in virgola mobile del IBM 360/91. Questo algoritmo si differenzia dallo scoreboarding per l'utilizzo della rinominazione dei registri. Mentre lo scoreboarding risolve le Write-after-Write (WAW) e le Write-after- Read (WAR) con gli stalli, l'algoritmo di Tomasulo permette l'esecuzione di altre istruzioni. Inoltre l'algoritmo di Tomasulo prevede un bus comune per fornire i valori calcolati a tutte le reservation station. L'algoritmo migliora l'esecuzione parallela delle istruzioni e fornisce prestazioni migliori dello scoreboarding. Lo scheduling delle istruzioni dovrà prevedere alcune variazioni: 1. FASE DI DECODIFICA: bisogna fare attenzione affinché non vi siano conflitti di dato effettivi, per cui la fase di decodifica viene scissa in due stadi ben distinti: 1. ISSUE: fase in cui l istruzione viene decodificata controllando che non vi siano azzardi strutturali, etichettata come istruzione floating point e inserita in una coda d istruzioni floating point, una coda flessibile la quale permette di non stallare in caso di conflitti di struttura, in cui le unità di calcolo sono occupate; le istruzioni possono essere anticipate rispetto ad altre se hanno la relativa unità di calcolo disponibile. 2. READ OPERANDI: fase che legge gli operandi, dopo aver verificato che non vi siano conflitti di dato, in maniera tale che gli operandi siano messi in ingresso alle unità senza generare conflitti. 2. FASE DI ESECUZIONE: esecuzione delle istruzioni in base allo scheduling previsto dall algoritmo di Tomasulo. 3. SCRITTURA DEI RISULTATI: i risultati, attraversi un bus comune, vengono scritti nel banco dei registri e in quelle unità di calcolo che eventualmente aspettano un risultato per svolgere la propria operazione. Pagina 88

89 ALGORITMO DI TOMASULO Questo algoritmo si basa su dei buffer, sempre interni al processore, chiamati STAZIONI DI PRENOTAZIONE. Questi buffer, presenti in ingresso per ogni elemento floating point del processore, ricevono gli operandi, quando disponibili, dal banco dei registri floating point (FP Registers) (un po come i registri A, B e Imm presenti nel latch ID/EX per il processore intero). Questi dati sono passati alle stazioni di prenotazione solo quando il secondo stadio della fase di decode ha accertato l assenza di eventuali conflitti di dato; viceversa se il registro non è ancora disponibile, poiché ad esempio è registro destinazione di una operazione ancora in fase di esecuzione, non potrà andare nella stazione di prenotazione. Quando il registro sarà disponibile sul Common Data Bus (CDB) per andare nel banco dei registri, questo verrà intercettato per andare direttamente nella stazione di prenotazione che lo attendeva. Se i dati contenuti nella stazione sono completi allora questi vanno in entrata all unità che effettuerà la relativa operazione. Analogamente si ragiona per le operazioni di lettura/scrittura della memoria; l esecuzione è gestita in maniera tale che i registri interessati siano disponibili per evitare conflitti. CAMPI DELLE STAZIONI DI PRENOTAZIONI BUSY OP Vj Vk Qj Qk 1. BUSY: campo di un bit che indica se la stazione di prenotazione è disponibile. 2. OP: campo che indica l operazione che dovrà essere eseguita. 3. Vj: campo che indica dove è contenuto il valore del primo registro sorgente. 4. Vk: campo che indica dove è contenuto il valore del secondo registro sorgente. 5. Qj: campo che indica se il primo registro sorgente è disponibile o meno; assume valore zero quando è disponibile; valori diversi da zero per indicare l unità che sta utilizzando il registro. 6. Qk: campo identico a Qj ma si riferisce al secondo registro sorgente. 7. A: campo che contiene l indirizzo sorgente/destinazione per le operazioni di load/store. È importante sottolineare che le stazioni di prenotazione per le unità di load conterranno solo i campi Busy, Op ed A, poiché il primo operando dell istruzione è un registro destinazione, il cui valore verrà eventualmente prelevato dal CDB; mentre le stazioni di prenotazione per le unità di store conterranno i campi Busy, Op, Vj, Qj, A, poiché l operando dell istruzione è un registro sorgente e va per tanto monitorato. Pagina 89

90 Quindi se si ha la possibilità di caricare una certa istruzione perché l unità di calcolo interessata è disponibile, allora si procede con la fase di licenziamento. L istruzione, che è stata prelevata e si trova nella coda di istruzioni floating point, dopo aver terminato lo stadio ISSUE, va nella stazione di prenotazione relativa all unità che dovrà usare per eseguire la sua operazione, cominciando così la fase di esecuzione. Se uno o entrambi gli operandi non sono disponibili allora bisognerà aspettare che questi lo diventano sul CDB. Infine dopo un certo numero di colpi di clock avviene la scrittura dei risultati e la stazione di prenotazione diventa libera. Pagina 90

91 Analizziamo ora un esempio di applicazione dell algorimto di Tomasulo ad un programma, considerando le seguenti caratteristiche del calcolatore: 1. Numero di colpi di clock per le varie operazioni: 1 colpi di clock per operazioni di somma e sottrazione; 10 colpi di clock per operazioni di moltiplicazione; 40 colpi di clock per operazioni di divisione. 2. Numero di unità di calcolo: 3 unità per operazioni di somma/sottrazione; 2 unità per operazioni di moltiplicazione/divisione. 3. Numero di canali per l accesso alla memoria: 3 canali; Il listato del programma è il seguente: LD LD F6, 34+, R2 F2, 45+, R3 MULTD F0, F2, F4 SUBD DIVD F8, F6, F2 F10, F0, F6 ADDD F6, F8, F2 È facile notare, come questo listato presenti una serie di conflitti di dato. La situazione iniziale si può schematizzare con la seguente figura, figura che verrà riportata più volte per spiegare passo passo lo svolgimento delle istruzioni: PARTE SUPERIORE - Sulla sinistra sono riportate le istruzioni, indicando il valore j e k. - Al centro vi è una tabella di riepilogo, nella quale sono monitorate le varie fasi di ciascuna istruzione: indicando l istante (colpo di clock) in cui l istruzione viene decodificata (Issue), completata (Comp) e istante in cui avviene la scrittura dei risultati (Result). - Sulla destra vengono monitorate le risorse per permettere le operazioni di load: disponibilità (Busy), indirizzo (Address). PARTE CENTRALE - È riportata la situazione delle Stazioni di Prenotazione (Reservation Stations) indicando il tempo per portare a termine l operazione (Time), il nome della stazione (Name), e i vari campi che caratterizzano queste stazioni. PARTE INFERIORE - È indicato il colpo di clock effettivo e lo stato dei registri. Pagina 91

92 CLOCK 1 Viene decodificata la prima istruzione e viene occupata la Load1 con l indirizzo 34+R2. Nel monitor dei registri viene segnalato che F6 è destinazione di una operazione di load, per cui non è pronto. CLOCK 2 Viene decodificata la seconda istruzione e viene occupata la Load2 con l indirizzo 45+R3. Nel monitor dei registri viene segnalato che F2 è destinazione di una operazione di load, per cui non è pronto. CLOCK 3 Viene decodifica la terza istruzione e viene occupata la Stazione Mult1 completando i campi che la caratterizzano. Busy: Yes Op: MULTD Vj: non è disponibile, bisogna attendere il termine della load, infatti il campo Qj segnala che l operando è destinazione di una load. Vk: R(F4) Qj: Load2 Per cui il moltiplicatore è occupato ma un sorgente non è ancora disponibile. Nel monitor dei registri viene segnalato che F0 è destinazione di una operazione svolta da un moltiplicatore, per cui non è pronto. Contemporaneamente è terminata la load della prima istruzione: attenzione è terminata l accesso in Pagina 92

93 memoria, ma non sono ancora disponibili i risultati, ovvero non è stato effettuato il Write Back. Per cui viene riportato l istante 3 in corrispondenza di Comp. CLOCK 4 Viene decodifica la quarta istruzione e viene occupata la Stazione Add1 completando i campi che la caratterizzano. Busy: Yes Op: SUBD Vj: M(A1) Vk: non è disponibile, bisogna attendere il termine della load, infatti il campo Qk segnala che l operando è destinazione di una load. Qk: Load2 Per cui il sommatore è occupato ma un sorgente non è ancora disponibile. Nel monitor dei registri viene segnalato che F8 è destinazione di una operazione svolta da un sommatore, per cui non è pronto. Contemporaneamente è terminata la load della seconda istruzione: identico discorso del caso precedente; per cui viene riportato l istante 4 in corrispondenza di Comp. Contemporaneamente sono disponibili i risultati della prima load; per cui viene riportato l istante 4 in corrispondenza di Result e nel monitor dei registri viene segnalato che F6 è disponibile in M(A1) per cui è pronto. CLOCK 5 Viene decodifica la quinta istruzione e viene occupata la Stazione Mult2 completando i campi che la caratterizzano. Busy: Yes Op: DIVD Vj: non è disponibile, bisogna attendere il termine della operazione svolta dal moltiplicatore, infatti il campo Qj segnala che l operando è destinazione di una operazione svolta da un moltiplicatore. Vk: M(A1) Qj: Mult1 Per cui il moltiplicatore è occupato ma un sorgente non è ancora disponibile. Nel monitor dei registri viene segnalato che F10 è destinazione di una operazione svolta da un moltiplicatore, per cui non è pronto. Contemporaneamente sono disonibili i risultati della seconda load; per cui viene riportato l istante 5 in corrispondenza di Result e nel monitor dei registri viene segnalato che F2 è disponibile in M(A2) per cui è pronto. Pagina 93

94 Tutte le stazioni (Add1 & Mult1) che erano in attesa di usare F2 possono mandare in ingresso alle rispettive unità di calcolo i sorgenti per effettuare l operazione indicata in Op. Le operazioni di calcolo potranno cominciare è i rispettivi colpi di clock mancanti alla conclusione sono riportati in corrispondenza del campo Time. CLOCK 6 Viene decodifica la sesta istruzione e viene occupata la Stazione Add2 completando i campi che la caratterizzano. Busy: Yes Op: ADDD Vj: non è disponibile, bisogna attendere il termine della operazione svolta dal sommatore, infatti il campo Qj segnala che l operando è destinazione di una operazione svolta da un sommatore. Vk: M(A2) Qj: Add1 Per cui il sommatore è occupato ma un sorgente non è ancora disponibile. Nel monitor dei registri viene segnalato che F6 è destinazione di una operazione svolta da un sommatore, per cui non è pronto. Vengono decrementati i valori presenti in corrispondenza del campo Timer. CLOCK 7 Termina l istruzione SUBD; i risultati non sono ancora disponibili, per cui viene riportato l istante 7 in corrispondenza di Comp. Vengono decrementati i valori presenti in corrispondenza del campo Timer. Pagina 94

95 CLOCK 8 Sono disponibili i risultati della SUBD; per cui viene riportato l istante 8 in corrispondenza di Result e nel monitor dei registri viene segnalato che F8 è disponibile in M-M per cui è pronto. Viene decrementato il valore presente in corrispondenza del campo Timer della Mult1. Tutte le stazioni (Add2) che erano in attesa di usare F8 possono mandare in ingresso alle rispettive unità di calcolo i sorgenti per effettuare l operazione indicata in Op. Le operazioni di calcolo potranno cominciare è i rispettivi colpi di clock mancanti alla conclusione sono riportati in corrispondenza del campo Time. CLOCK 9 La situazione resta invariata. Vengono decrementati i valori presenti in corrispondenza del campo Timer. CLOCK 10 Termina l istruzione ADDD; i risultati non sono ancora disponibili, per cui viene riportato l istante 10 in corrispondenza di Comp. Vengono decrementati i valori presenti in corrispondenza del campo Timer. Pagina 95

96 CLOCK 11 Sono disponibili i risultati della ADDD; per cui viene riportato l istante 11 in corrispondenza di Result e nel monitor dei registri viene segnalato che F6 è disponibile in M-M+M per cui è pronto. Viene decrementato il valore presente in corrispondenza del campo Timer della Mult1. CLOCK La situazione resta invariata; procede l operazione svolta da Mult1. Vengono decrementati i valori presenti in corrispondenza del campo Timer. CLOCK 15 Termina l istruzione MULTD; i risultati non sono ancora disponibili, per cui viene riportato l istante 15 in corrispondenza di Comp. Sono disponibili i risultati della MULTD; per cui viene riportato l istante 16 in corrispondenza di Result e nel monitor dei registri viene segnalato che F0 è disponibile in M*F4 per cui è pronto. Tutte le stazioni (Mult2) che erano in attesa di usare F0 possono mandare in ingresso alle rispettive unità di calcolo i sorgenti per effettuare l operazione indicata in Op. Le operazioni di calcolo potranno cominciare è i rispettivi colpi di clock mancanti alla conclusione sono riportati in corrispondenza del campo Time. CLOCK 16 Pagina 96

97 CLOCK La situazione resta invariata; procede l operazione svolta da Mult2. Vengono decrementati i valori presenti in corrispondenza del campo Timer. CLOCK 56 Termina l istruzione DIVD; i risultati non sono ancora disponibili, per cui viene riportato l istante 56 in corrispondenza di Comp. CLOCK 57 Sono disponibili i risultati della DIVD; per cui viene riportato l istante 57 in corrispondenza di Result e nel monitor dei registri viene segnalato che F10 è disponibile in Result per cui è pronto. Questo programma termina dopo 57 colpi di clock. Si può notare come il licenziamento avviene in maniera ordinata; l esecuzione e il termine delle istruzioni è del tutto imprevedibile, ossia è FUORIORDINE dal punto di vista temporale, ma comunque in ordine dal punto di vista logico. Pagina 97

98 Per concludere si possono quindi mettere in evidenza i vantaggi e gli svantaggi derivanti dall uso di questo algoritmo; VANTAGGI 1. Eliminazione degli stalli dovuti agli azzardi di tipo WAW e WAR; 2. Se più istruzioni attendono uno stesso risultato e per esempio l istruzione ha disponibile l altro operando, queste istruzioni possono accedere simultaneamente sul CDB per prelevare il risultato senza attendere la scrittura nel registro; SVANTAGGI 1. Maggiore complessità; 2. Problema legato alle memorie associative, ossia quelle memorie che vengono utilizzate in funzione del contenuto delle memorie stesse, cioè si accede alla memoria prelevando i dati fornendo alla memoria stessa informazioni sui dati e non sui loro indirizzi; queste memorie sono richieste per interfacciare le stazioni di prenotazione con il CDB; 3. Accesso multiplo al CDB, poiché esso deve servire più unità contemporaneamente, per cui questo limita le performance; 4. La gestione delle istruzioni fuoriordine complica la gestione degli interrupt. Pagina 98

99 PARTE QUARTA PARTE QUARTA ALTRI TIPI DI PROCESSORE PROCESSORI VLIW PROCESSORI SUPERSCALARI PROCESSORI VETTORIALI MULTICORE Pagina 99

100 PROCESSORI VLIW I processori VLIW, acronimo di Very Long Istruction Word, permettono di accedere alla memoria istruzioni prelevando più istruzioni in un solo colpo di clock; se queste istruzioni usano unità di calcolo distinte, allora è possibile farle partire contemporaneamente a gruppi. Ovviamente questa logica richiede una memoria tale da poter conferire in un colpo di clock un istruzione lunga per esempio 128 bit (32 bit x 4 istruzioni). Il principale vantaggio è che un istruzione così grande va a codificare istruzioni diverse, le quali richiedono unità diverse; l istruzione VLIW è scompattata in tanti campi quanti sono le unità di calcolo del processore: per cui l istruzione VLIW codifica un certo numero d istruzioni che prevedono l uso di unità funzionali distinte (è chiaro che non vi è nessun vantaggio nel prelevare più istruzioni che usano la stessa unità di calcolo). Quindi, se l istruzione VLIW è da 128 bit il compilatore codifica un istruzione molto lunga che al suo interno è spacchettata in 4 campi da 32 bit, ciascuno dei quali contiene un istruzione particolare. ISTRUZIONE VLIW DA 128 bit: 32 bit 32 bit 32 bit 32 bit In ogni campo vi sarà un istruzione da 32 bit associata ad una specifica unità di calcolo; il compilatore si preoccupa di scrivere nei campi opportuni le istruzioni. Se in un programma non ci sono istruzioni che fanno uso di una unità funzionale, nel relativo campo verrà posta la dicitura NO-OP. Quindi teoricamente con una istruzione VLIW si può avere l avvio simultaneo di N istruzioni scalari, dove N è il numero di unità presenti; però se il compilatore non riesce a gestire in maniera efficiente questa logica, sia per mancanza d istruzioni che usano unità funzionali particolari e sia perché ci sono troppe istruzioni che usano una stessa unità, allora questo processore comincia a perdere prestazioni. Il compilatore per cercare di gestire efficientemente il tutto usa tecniche particolari quali, ad esempio, la tecnica dello srotolamento del loop. Si consideri il seguente esempio: Il processore VLIW possiede le seguenti caratteristiche: 2 unità per l accesso a memoria; 2 unità per operazioni FP; 1 unità per operazioni intere e branch; Memoria con banda passante da 160 bit. UNITA 1 UNITA 2 UNITA 3 UNITA 4 Per cui essendo 5 le unità funzionali, e la banda passante da 160 bit l istruzione VLIW sarà costituita da 5 campi, ciascuno dei quali di 32 bit: 32 bit 32 bit 32 bit 32 bit 32 bit UNITA ACC. MEM. 1 UNITA ACC. MEM. 2 UNITA FP 1 UNITA FP 2 UNITA INTERA/BRANC Pagina 100

101 Il listato del programma già ottimizzato, con la tecnica dello srotolamento del loop eseguita per sette volte, è il seguente: 1 LOOP: L.D F0,0(R1) 2 L.D F6,-8(R1) 3 L.D F10,-16(R1) 4 L.D F14,-24(R1) 5 L.D F18,-32(R1) 6 L.D F22,-40(R1) 7 L.D F26,-48(R1) 8 ADD.D F4,F0,F2 9 ADD.D F8,F6,F2 10 ADD.D F12,F10,F2 11 ADD.D F16,F14,F2 12 ADD.D F20,F18,F2 13 ADD.D F24,F22,F2 14 ADD.D F28,F26,F2 15 S.D 0(R1),F4 16 S.D -8(R1),F8 17 S.D -16(R1),F12 18 S.D -24(R1),F16 19 S.D -32(R1),F20 20 S.D -40(R1),F24 21 DSUBUI R1,R1,#56 22 BNEZ R1,LOOP 23 S.D 8(R1),F28 ; 8-56 = -48 per cui S.D -48(R1),F28 Brevemente questo programma somma gli elementi di un vettore, memorizzato a partire da R1, con una costante memorizzata in F2. Riempendo i campi con logica, per ogni singolo colpo di clock, dell istruzione VLIW si ottiene la seguente situazione: Si nota come alcune VLIW hanno due o tre campi NO OP. Pagina 101

102 È possibile ottimizzare ancora di più il codice spostando la BNEZ al colpo di clock 8, evitando così lo stallo; questa ottimizzazione richiede anche la modifica logica di altre istruzioni. Nonostante in questo caso un istruzione VLIW permeterebbe di eseguire 5 istruzioni contemporaneamente, si ha solo una media di 2,5 istruzioni per colpo di clock; per cui questo processore starebbe lavorando con una efficienza del 50%, percentuale che dipende quindi dal programma e dal compilatore. Con un processore scalare che svolge le 23 istruzioni in pipeline, si sarebbero ottenuti sette risultati in 23 colpi di clock, oppure 3.3 colpi di clock per ogni iterazione; mentre con il processore VLIW che esegue le 23 istruzioni in 9 colpi di clock, si ottengono sette risultati in 9 colpi di clock, oppure 1.3 colpi di clock per ogni iterazione, quindi vi è un accelerazione di circa il 60%. Concludendo, questo tipo di processore richiede: Una Control Unit non molto complessa rispetto a quella presente nei processori scalari per gestire i floating point: è il compilatore che organizza le istruzioni; Un compilatore diverso, capace di gestire questo tipo di assemblamento delle istruzioni; Memoria con una banda maggiore, per permettere di prelevare in un unico colpo di clock un istruzione costiuita da un numero grande di bit; Incremento del codice, dovuto allo strotolamento. Pagina 102

103 PROCESSORI SUPERSCALARI Il processore SUPERSCALARE sfrutta, come il VLIW, il fatto che le varie unità funzionali del processore sono ridondanti se pensate a livello della singola istruzione; nei processori scalari se un istruzione sta usando l ALU intera non può esserci una istruzione che vada ad occupare ed ad usare l ALU FP. Nei processori superscalari questo parallelismo è possibile: MEM. ISTR. Istruzione intera Istruzione Floating point UNITA INTERA UNITA FLOATING POINT MEM. DATI Per cui vi è un potenziamento della memoria che prevede la lettura parallela di due istruzioni, una intera ed una floating point; quindi queste istruzioni vengono avviate nella pipeline in contemporanea, poiché ognuna andrà ad utilizzare l unità di cui necessità. Nel migliore delle ipotesi questo processore permette l avvio di due istruzioni in contemporanea. Il compilatore dovrà preoccuparsi di scrivere il programma in maniera tale che le istruzioni siano in coppia, una intera e una floating point, per ottenere una pipeline ideale di questo tipo: Quando vi è la fase di fetch saranno letti dalla memoria 64 bit, due istruzioni, sperando che i primi 32 siano relativi ad un istruzione intera e i restanti 32 relativi ad una istruzione floating point. Dopo il prelievo, il Program Counter dovrà essere incrementato di 8. Se la coppia d istruzioni è dello stesso tipo, allora chiaramente, solo la prima istruzione verrà processata e l altra verrà avviata al colpo di clock successivo. Però è possibile prendere l istruzione in attesa in coppia con la successiva, sfasando così tutte le successive coppie; in questo caso il PC dovrà essere incrementato di 4 e non di 8. CC 1 CC 2 CC 3 CC 4 CC 5 Concludendo, questo tipo di processore richiede: Una Control Unit non molto complessa rispetto a quella presente nei processori scalari per gestire i floating point: è il compilatore che organizza le istruzioni; Un compilatore diverso, capace di gestire questo tipo di assemblamento delle istruzioni; Memoria con una banda maggiore, per permettere di prelevare in un unico colpo di clock due istruzioni; Pagina 103

104 PROCESSORI VETTORIALI Il processore VETTORIALE nasce dall idea di codificare con un istruzione classica una grande mole di lavoro. Questo è realizzato estendendo il set delle istruzioni con istruzioni vettoriali, le quali hanno come sorgenti e destinazioni dei vettori. Nei casi di uso dei vettori, cosa che spesso capita nei programmi, invece di avere dei loop, con una sola istruzione vettoriale è possibile codificare una determinata operazione (ovviamente nell ipotesi che i vettori da trattare abbiano un numero di elementi al massimo pari al numero di elementi che i registri vettoriali possono contenere). Per cui in sinstesi le idee alla base dei processori vettoriali sono: Codifica delle istruzioni per le operazioni vettoriali; Dotare il processore di unità che operino efficientemente con i vettori, cioè, ad esempio, l unità di accesso alla memoria deve saper efficientemente prelevare i vettori dalla memoria (la memoria riceverà dall ALU solo l indirizzo del primo elemento, poi essa stessa dovrà automaticamente calcolarsi l indirizzi degli altri elementi); Registri vettoriali idonei in grado di contenere dei vettori: questi registri hanno una dimensione ben definita (decisa in fase di progettazione), per cui le dimensioni dei vettori devono rientrare in quelle dei registri. Per cui quando si devono svolgere operazioni fra vettori, attraverso una codifica molto compatta, si ha la possibilità di rendere esplicita una quantità di calcolo abbastanza ampia, che tra l altro opera su dati che non creano conflitto fra di loro. Di conseguenza si definiscono operazioni vettoriali tutte quelle operazioni che non generano conflitti di dato (somma, sottrazione, moltiplicazione, ecc.), mentre operazioni come media o determinante di una matrice non sono gestite dalla CPU come operazione vettoriale. È chiaro che accedere a dati vettoriali richiede una unità di memoria dati ottimizzata; i dati vettoriali devono essere organizzati in una determinata maniera. Il prelievo di un istruzione vettoriale è uguale al prelievo di un istruzione classica, poiché si accede alla memoria istruzioni; mentre il prelievo dalla memoria dati deve essere ottimizzato. Una esempio d istruzione vettoriale è il seguente: ADDV V1,V2,V3 L istruzione ADD è seguita dalla lettera V la quale indica che l istruzione si riferisce ad una operazione vettoriale. V1,V2,V3 sono registri vettoriali; la CPU avrà necessariamente dei registri vettoriali i quali sono costituiti da un numero fisso di registri scalari logicamente uniti, identificati con un unico nome. Per cui i registri vettoriali hanno una ampiezza definita. Bisogna però fare attenzione alle dimensioni da scegliere in fase di progettazione; aumentando/diminuendo il numero dei registri vettoriali e quindi di conseguenza diminuendo/aumentando la dimensione del singolo registro aumentano/diminuiscono i bit utili alla identificazione dei registri all interno dell istruzione. Inoltre diminuire la dimensione del singolo registro, comporterebbe dei problemi quando si devono gestire vettori con dimensioni maggiori rispetto alla lunghezza dei registri vettoriali, problema che verrà comunque gestito, come vederemo in seguito, con una scomposizione in tanti più piccoli problemi vettoriali in cui i vettori hanno dimensioni minori. Analogalmente se si aumenta la lunghezza dei singoli registri è molto probabile che parte del registro rimanga inutilizzata quando si opera con vettori di dimensioni ridotte. Per cui è chiaro che bisogna trovare Pagina 104

105 un compromesso; nel caso preso in esame, la CPU VETTORIALE ha i registri vettoriali costituti da 64 elementi. Di seguito è riportata la tabella di alcune tipiche istruzioni vettoriali. OPERAZIONI DI LOAD E STORE L operazione di caricamento in un registro vettoriale da memoria è definita con la seguente sintassi: LV [reg],[ind] [reg]: registro in cui si andrà ad ospitare il vettore; [ind]: indirizzo da cui parte il vettore in memoria; Dulamente l operazione di salvataggio in memoria del contenuto di un registro vettoriale è definita con la seguente sintassi: SV [ind],[reg] Per entrambe le operazioni è messo a disposizione un dispositivo simile al noto DMA (Direct Memory Access), il quale ricevuto l indirizzo del primo elemento del vettore calcola gli indirizzi dei restanti elementi; questo dispositivo è interno alla memoria dati. Pagina 105

106 Per cui, grazie a questo dispositivo, è possibile avere al termine della fase MEM dell istruzione LOADV il primo elemento del vettore nella corrispondente cella del registro destinazione; per ogni colpo di clock successivo si avrà a disposizione, nella specifica cella del registro destinazione, l elemento successivo del vettore. Quindi è evidente che se la memoria consente una banda passante maggiore che permette, ad esempio, la lettura di due dati in un solo colpo di clock, al termine della fase MEM saranno disponibili, nelle rispettive celle del registro vettoriale destinazione, i primi due elementi del vettore. Sfruttando la disponibilità di alcuni elementi del vettore ancor prima che questo sia completamente caricato nel registro destinazione, è possibile poter eseguire istruzioni che devono elaborare gli elementi, come questo esempio: 1cc 2cc 3cc 4cc 5cc 6cc 7cc 8cc 9cc LOADV V2, IF ID EX MEM WB LOADV V3, IF ID EX MEM WB ADDV V1,V2,V3 stallo IF ID EX MEM WB STOREV,V1 IF ID EX MEM WB (Considerando idealmente che il sommatore abbia una latenza di 1 cc) L istruzione ADDV V1,V2,V3 potrà effettuare la somma degli elementi presenti nelle celle dei registri V2,V3 senza dover attendere l intero caricamento del vettore. Lo stesso vale per la STOREV,V1 che può cominciare a memorizzare in memoria gli elementi disponibili nelle celle di V1. Attenzione, questo calcolo non viene eseguito in circa 5 colpi di clock; poiché per completare l intera operazione bisogna attendere che tutti gli elementi del vettore vengano processati. Per cui il completamento dell operazione richiesta avverrà dopo un numero di colpi di clock dipendenti dal numero di elementi che si devono processare. Tutto questo è possibile poiché, come descritto precedentemente, le unità di calcolo si basano su logica pipeline. L istruzione LVWS I vantaggi che questa CPU offre sono assicurati se gli elementi sono memorizzati in memoria centrale in maniera sequenziale; infatti in memoria i vettori sono allocati in locazioni consecutive. Questo non avviene quando ad esempio si estrae da una matrice un qualsiasi vettore colonna, essendo le matrici generalmente allocate per righe; per questo caso attraverso un unica istruzione si risolve il problema: vi è un numero che dirà al famoso modulo simile al DMA di quanto deve saltare per accedere all elemento successivo. L istruzione in esame è: LVWS (Load Vector With Stride). I registri VLR e MVLR Supponiamo che il vettore da processare sia costituito da un numero di elementi molto inferiore ai 64 che la CPU in esame mette a disposizione. Il caricamento del vettore avverrà in un unico registro vettoriale senza nessun tipo di problema, ma con conseguenti elementi inutilizzati; si nota facilmente che processare questo vettore significherebbe far lavorare la CPU anche su elementi che non hanno nessun significato. Per evitare ciò la CPU vettoriale ha un registro particolare chiamato VLR (V ector Length Register): questo registro contiene un numero che il compilatore va ad impostare, in maniera trasparente al programmatore, quando deve operare sui registri vettoriali; questo numero equivale alla dimensione del vettore da processare e al massimo può valere (in questo caso) 64. Pagina 106

107 Le varie operazioni sul vettore procederanno fino a quando si raggiungerà un numero di passi pari al contenuto di VLR. Il compilatore deve però conoscere a priori la dimensione dei registri vettoriali per poter impostare il valore di VLR. Questo è possibile attraverso il registro MVLR (Max Vector Length Register): questo registro è fondamentale per l architettura vettoriale. Contiene la dimensione massima dei registri vettoriali della CPU; per cui non è un registro impostato dal compilatore, ma impostato al momento della produzione del firmware della CPU. Prestazioni Una CPU vettoriale offre quindi ottime prestazioni, quando si processano dati che eseguono operazioni vettoriali, giocando sui diversi fattori: Riduzione drastica del collo di bottiglia provocato dalla memoria istruzioni. A livello del codice, implicitamente, si eliminano i conflitti di dato. Una Control Unit più semplice. L unico svantaggio è che non sempre si incontrano operazioni vettoriali comuni, ma operazioni che richiedono una complessità diversa per il loro processo. Pagina 107

108 ANALISI REALE DELL ARCHITETTURA DI UNA CPU VETTORIALE CRAY-1 (1976) Il primo calcolatore basato su architettura vettoriale fu il CRAY-1 (pesante 5,5 tonnelate!) progettato da Seymour Cray nel L architettura di questo calcolatore prevedeva le unità scalari più una estensione per operazioni vettoriali; per cui il Cray-1 presentava alcune caratteristiche in più rispetto a precedenti calcolatori: - Un architettura per operazioni di load/store; - Registri vettoriali; - Istruzioni vettoriali; - Un sistema di memoria INTERLEAVED che sostituisce a livello dati le memorie cache; Cray-1 (1976) SCHEMA LOGICO Di seguito è riportato lo schema logico dell architettura della CPU vettoriale Cray-1. Osserviamo alcune sue caratteristiche: - 8 registri vettoriali da 64 elementi l uno [V0 V7]; - 8 registri scalari di tipo S [S0 S7]; - 8 registri scalari di tipo A [A0 A7]; - Buffer da 4 istruzioni; - 3 unità ad aritmentica floating point; - 4 unità ad aritmetica intera; - 2 unità per le operazioni sugli indirizzi; - Registro V.Mask; - Registro V.Lenght; Si noti che in questa CPU non è presente il divisore: questo è sostituito dall unità che effettua il reciproco; tramite il moltiplicatore verrà eseguita poi l operazione: x 1 y Sono presenti inoltre due registri importanti per il corretto e efficiente funzionamento dell architettura vettoriale; questi registri sono: Registro V.Mask: serve per operazioni condizionate oppure realtive a vettori o matrici sparse, cioè quelli in cui la maggior parte dei loro dati sono degli zeri. La CPU impostando corretamente questo registro evita di operare su valori uguali a zero, in modo tale da diventare più efficiente. Per cui nel set istruzioni sono presenti particolari istruzioni con maschera che operano solo su dati significativi: ad esempio utili per gestire situazioni di overflow provocati da divisione per zero. Il registro V.MASK è un registro vettoriale, costituito da MVLR elementi. Registro V.Lenght: equivale al registro VLR. Pagina 108

109 IDEE ALLA BASE DELLA ORGANIZZAZIONE VETTORIALE REGISTRI: 16 registri scalari; 8 registri vettoriali da 64 elementi l uno; VLR indica da quanti elementi è costituito il vettore da processare. OPERAZIONI ARITMETICHE: Avere a disposizioni tante unità funzionali per processare parallelamente ogni elemento del vettore. OPERAZIONI LAOD/STORE: Accesso (load/store) in memoria tramite gli indici BASE e STRIDE, permettendo così l accesso efficiente a vettori con elementi non contigui, come ad esempio un qualsiasi vettore colonna di una matrice memorizzata in memoria per righe. CODICE VETTORIALE Di seguito è riportato un confronto fra il codice implementato per una cpu scalare e un codice implementato per la cpu vettoriale. Si noti come risulta molto più breve e semplice utilizzare istruzioni vettoriali. L esempio consiste nell eseguire una somma fra due vettori. CODICE SORGENTE, C CODICE CPU SCALARE CODICE CPU VETTORIALE for (i=0; i<64; i++) C[i] = A[i] + B[i]; LI R4, 64 loop: L.D F0, 0(R1) L.D F2, 0(R2) ADD.D F4, F2, F0 S.D F4, 0(R3) DADDIU R1, 8 DADDIU R2, 8 DADDIU R3, 8 DSUBIU R4, 1 BNEZ R4, loop LI VLR, 64 LV V1, R1 LV V2, R2 stallo ADDV.D V3, V1, V2 SV V3, R3 I vantaggi nell uso di un set con istruzioni vettoriali sono molteplici: - Compattezza: poche istruzioni per eseguire diverse operazioni; - Indipendenza implicita dei dati, per cui assenza di conflitti di dati; - Uso delle stesse unità funzionali, per cui non sono necessarie particolari unità di calcolo; - Accesso a registri disgiunti, quindi come avviene per le non vettoriali; - Accesso a blocchi di memoria contigui (stride unitario), oppure saltando (stride noto a priori); - Riduzione drastica del collo di bottiglia con la memoria. Pagina 109

110 ESECUZIONE ARITMETICA DELLE ISTRUZIONI L unità funzionale che deve eseguire una certa operazione avrà una latenza, definita in fase di progettazione, la quale permette di avere il risultato dopo un certo numero di colpi di clock. Organizzandola in maniera tale che le sue unità logiche siano strutturate in pipeline, è possibile migliorare il throughput (rendimento, cioè la frequenza con cui l oggetto è in grado di processare i dati) dell unità di calcolo. Sulla base di queste considerazioni è chiaro che è possibile migliorare di molto le prestazioni della singola unità funzionale e quindi dell intero sistema; i dati saranno disponibili molto più velocemente. La possibilità di utilizzare questa tecnica è garantita perché gli elementi di un vettore sono indipendenti. La figura affianco mostra come viene effettuato il prodotto fra due registri contenti dati vettoriali, attraverso un moltiplicatore a 6 stadi di pipeline. Supponendo una latenza di 6 colpi di clock il primo risultato lo si ottiene appunto dopo 6 cc. Il secondo risultato lo si otterrà al cc 7 e così via. SISTEMA DI MEMORIZZAZIONE DI DATI VETTORIALI NEI REGISTRI VETTORIALI La CPU del Cray-1 disponeva di una memoria a 16 banchi, il cui schema logico è riportato di seguito: L accesso ai blocchi avviene in maniera molto intuitiva; un sommatore genera l indirizzo del blocco operando sulla base e sullo stride. ESECUZIONE ISTRUZIONI VETTORIALI Si supponga di effettuare una operazione di somma fra due vettori: Si possono distinguere due casi: 1 CASO Una unità funzionale pipeline a 3 stadi ADDV C,A,B 2 CASO 4 o più unità funzionale pipeline a 3 stadi Aumenta il parallelismo, provocando un aumento del throughput del sistema; la latenza della singola unità rimane invariata. Si noti la disposizione con cui gli elementi entrano nelle unità. Pagina 110

111 STRUTTURA DELLE UNITA VETTORIALI La struttura delle unità si basa sulla creazione di CORSIE le quali sono organizzate in maniera tale da ottimizzare al meglio l operazione vettoriale da eseguire. Ogni corsia presenta due unità funzionali che operano sui registri organizzati in maniera logica, per ottenere i risultati in modo consecutivo e il più velocemente possibile. Come già detto questa organizzazione migliora il throughput del sistema. Di seguito è riportata una immagine reale della struttura del T0 Vector Microprocessor del 1995; esso è costituito da 16 unità funzionali. T0 Vector Microprocessor (1995) DIFFERENZA FRA ARCHITETTURA MEMORIA-MEMORIA E ARCHITETTURA A REGISTRI VETTORIALI I sistemi basati su architettura memoria-memoria (VMMA Vector Memory-Memory Architectures) operano fondamentalmente considerando i vettori residenti in memoria centrale; quindi il prelievo e la scrittura avviene direttamente in memoria centrale. I primi sistemi che si basavano esclusivamente su architettura memoria-memoria sono ad esempio CDC Star-100 (1973) e il TI ASC (1971); la scelta di questa tecnica era dovuta esclusivamente alla indisponibilità di spazio fisico. Per cui il codice di una macchina memoria-memoria è di questo tipo: ADDV C, A, B ;si usano direttamente gli indirizzi SUBV D, A, B Cray-1 fu il primo sistema ad utilizzare registri vettoriali; questo implica necessariamente un codice diverso, poiché bisogna effettuare le operazioni di load e store. Pagina 111

112 È possibile quindi evidenziare le differenze fra queste due tipologie di macchine vettoriali: I sistemi VMMA richiedono una banda maggiore di memoria, perché ogni operando deve essere sempre letto dalla memoria anche se precedentemente utilizzato, problema non presente con l utilizzo di registri vettoriali. Aumento del rischio di dipendenza fra dati nei sistemi VMMA. I sistemi VMMA incorrono in una maggiore latenza di avvio. VETTORIZZAZIONE AUTOMATICA DEL CODICE Si osservi adesso come un codice sorgente, per semplicità consideriamo la somma di due vettori, viene processato da una macchina con istruzioni scalari e da una con istruzioni vettoriali, e quindi i tempi di esecuzione delle singole iterazioni. ISTRUZIONI SCALARI SEQUENZIALI CODICE SORGENTE for (i=0; i < N; i++) C[i] = A[i] + B[i]; Ipotizzando la ISTRUZIONI VETTORIZZATE latenza pari a un colpo di clock per ogni singola unità. La vettorizzazione permette un parallelismo maggiore e quindi per lo stesso numero di colpi di clock una cpu vettoriale riesce a processare più dati. GESTIONE DI VETTORI CON DIMENSIONE SUPERIORE A MVLR VECTOR STRIPMINING Vediamo ora come vengono gestiti i casi in cui il vettore da processare è costituito da un numero di elementi maggiori del valore impostato in Max Vector Length Register. Questo tipo di problema viene affrontato suddividendo il vettore in un certo numero di sottovettori; ciascuno di questi sottovettori verrà considerato come un vettore di MVLR elementi o comunque di un numero minore. Il vettore viene suddiviso quindi in N sottovettori: per rendere il più efficiente possibile il sistema, N-1 sottovettori avranno la dimensione massima possibile, consentita dai registri vettoriali, quindi MVLR, mentre un vettore sarà costituito dagli eventuali elementi residui. È facile capire che se la dimensione del vettore è divisibile per MVLR non vi saranno sottovettori residui e quindi la gestione si semplifica; se la dimensione del vettore non è divisibile per MVLR, allora bisognerà gestire al meglio la presenza del vettore residuo. Pagina 112

113 Risulta opportuno che il primo sottovettore che deve essere processato sia il sottovettore residuo; in questo modo al di fuori del loop viene processato il residuo e poi dopo aver modificato VLR si procede con i restanti vettori. Questa situazione viene implementata con le seguenti istruzioni: for (i=0; i<n; i++) C[i] = A[i]+B[i]; 1 ANDI R1, N, 63 # N mod 64 2 MTC1 VLR, R1 # Do remainder 3 loop: LV V1, RA 4 DSLL R2, R1, 3 # Multiply by 8 5 DADDU RA, RA, R2 # Bump pointer 6 LV V2, RB 7 DADDU RB, RB, R2 8 ADDV.D V3, V1, V2 9 SV V3, RC 10 DADDU RC, RC, R2 11 DSUBU N, N, R1 # Subtract elements 12 LI R1, MTC1 VLR, R1 # Reset full length 14 BGTZ N, loop # Any more to do? Analizziamo ora alcune istruzioni, fondamentali per gestire la presenza del vettore Remainder. ISTRUZIONE 1: il valore del residuo viene calcolato attraverso l istruzione: ANDI R1, N, 63 Un residuo di una divisione per un divisore che è potenza di 2, come 64, si fa semplicemente andando a considerare gli ultimi n bit (2 n ). Per cui essendo 64 = 2 6 si considerano gli ultimi 6 bit della dimensione del vettore, per ottenere il resto della divisione. Per esempio N = 187: (187) 10 = ( ) 2 - Bisogna considerare gli ultimi 6 bit, quindi in AND con 63; AND = Per cui risulta: ( ) 2 = (59) 10 Quindi se la dimensione del vettore da processare è di 187 elementi, ci sarà un vettore Remainder da 59 elementi e 191 2, quindi 2 vettori da 64 elementi. 64 ISTRUZIONE 2: l impostazione di VLR, essendo un registro speciale, avviene tramite un istruzione speciale: MTC1 VLR, R1 ISTRUZIONE 4: shift logico verso sinistra di 3 posti, moltiplicando così per 8 il contenuto di R1, ossia il valore della dimensione del vettore al momento processato; DSLL R2, R1, 3 In questo modo in R2 è contenuto il valore della dimensione in memoria del sottovettore che si sta processando e di conseguenza R2 conterrà il valore del salto da effettuare per accedere al sottovettore successivo. Le istruzioni aggiorneranno i rispettivi indirizzi per accedere al successivo sottovettore. ISTRUZIONE 14: controlla se il valore di N è maggiore di zero: BGTZ N, loop Pagina 113

114 PARALLELISMO DELLE ISTRUZIONI VETTORIALI Si supponga una unità costituita 8 corsie e 32 elementi per ogni registro vettoriale, e si ipotizzi idealmente che ogni unità abbia una latenza di 1 colpo di clock; è possibile sovrapporre l esecuzione di più istruzioni vettoriali in questo modo: (considerando l esecuzione su un singolo vettore) Essendo disponibili 8 corsie verranno caricate nel registro vettoriale i primi 8 elementi del vettore; inoltre essendo le unità pipeline, al colpo di clock successivo (2) si potranno caricare altri 8 elementi e in parallelo eseguire con il moltiplicatore, come in questo esempio, l istruzione successiva che processerà i dati caricati al colpo di clock 1: Per cui al colpo di clock successivo (3) saranno caricati altri 8 elementi, e in parallelo oltre al moltiplicatore, si potranno processare, con ad esempio un sommatore, i dati del colpo di clock precedente (2); per cui si ottiene la seguente situazione: In questo caso si sta eseguendo in parallelo, load-mul-add; Essendo i registri costituiti da 32 elementi, e le corsie disponibili sono 8, la prima istruzione di load terminerà al 4 colpo di clock; per cui al 5 cc l unità che effettua operazioni di load/store sarà disponibile per eventuali altre load/store; quindi è possibile in questo modo avere istruzioni parallele: la seguente figura evidenzia il parallelismo che si ottiene. In questo modo si completano 6 istruzioni in soli 10 colpi di clock. Ogni istruzione si completa in 4 colpi di clock. Quindi nei casi in cui si ha il massimo parallelismo, cioè tutte le unità stanno operando, si eseguono 24 operazioni (8 load 8 mul 8 add). Per cui sono evidenti i vantaggi che porta questo tipo di soluzione. Pagina 114

115 PENALITA DI AVVIO DELLE CPU VETTORIALI Le componenti che incidono sulla penalità di avvio nelle cpu vettoriali sono essenzialmente due: 1. Latenza delle unità funzionali, e quindi il tempo che trascorre per ottenere un risultato; 2. Tempo morto o tempo di recupero, ossia il tempo che trascorre prima che un altro vettore possa utilizzare l unità funzionale, se questa è unica e occupata. Per chiarire il concetto di tempo morto si consideri la seguente figura: Un ipotetica unità funzionale è occupata nel processore da un certo vettore (e potrà essere impegnata da un altro vettore solo quando avrà terminato di processato il primo vettore); essendo questa unità organizzata in pipeline solamente dopo un certo numero di colpi di clock, pari alla sua latenza, darà in uscita il primo risultato e successivamente tutti gli altri risultati, per ogni colpo di clock successivo. Essendo questa unità unica nel sistema, se un secondo vettore deve essere processato, questo deve attendere che il primo vettore completi l intera operazione e che liberi quindi l unità funzionale. Il tempo che intercorre si definisce tempo morto (Dead Time). Per cui questo tempo morto dipende da due fattori: 1. La dimensione del vettore. 2. Il numero di unità funzionali presenti e quindi il numero di corsie. GESTIONE DELLE CONDIZIONI USO DEL REGISTRO V.MASK ISTRUZIONI MASCHERATE L obiettivo è quello di gestire, attraverso la vettorizzazione, situazioni in cui sono presenti condizioni sugli elementi del vettore. Consideriamo l esempio: for (i=0; i<n; i++) if (A[i]>0) then A[i] = B[i]; Si vuole sostituire tutti gli elementi del vettore A che sono maggiori di zero, con gli elementi di B. Ad ogni elemento del registro vettoriale viene associato, tramite una particolare istruzione, un elemento del registro V.MASK; gli elementi del registro V.MASK faranno da flag per gli elementi del vettore. Il flag permette di identificare se quell elemento è da processare oppure no. Per fare questo bisogna impostare, come già detto, il registro V.MASK tramite l istruzione SGTVS: SGTVS.D V1, F0 Pagina 115

116 Questa istruzione confronta gli elementi del vettore V1 con uno scalare e, se la condizione è verificata, imposta il relativo campo del V.MASK associato al relativo elemento del vettore. Quindi per tutti gli elementi che verificano la condizione verrà impostato il flag a 1 per indicare che solo quelli saranno processati successivamente. Quindi per l esempio considerato si ha il seguente codice: CVM LV V1,R1 # Turn on all elements # Load entire A vector SGTVS.D V1, F0 # Set bits in mask register where A>0 LV V1, R2 SV R1,V1 # Load B vector into A under mask # Store A back to memory under mask Per cui con l utilizzo delle istruzioni mascherate è possibile ulteriormente ottimizzare l esecuzione, e quindi ridurre i tempi; gli elementi verranno processati in questa maniera: È evidente che la verifica del flag relativo ad ogni elemento deve essere effettuata a monte dell unità funzionale, in modo tale da poter processare solo gli elementi con flag a 1. Temporary Register L operazione di mascheramento quindi richiede una fase di compressione dei dati, cioè i soli dati processati vengono temporaneamente memorizzati in un registro vettoriale, seguita da un fase di espansione in cui i dati vengono memorizzati nelle relative posizioni del registro destinazione. Pagina 116

117 RIDUZIONE A OPERAZIONI SCALARI Ci sono operazioni con vettori che non sono definite operazioni vettoriali, poiché creano dipendenza tra i dati e quindi conflitti nell esecuzione. È possibile ridurre queste operazioni ad operazioni di tipo vettoriale; questa tecnica permette dunque di risolvere questo tipo di problema. Consideriamo questa situazione: sum = 0; for (i=0; i<n; i++) sum += A[i]; # Loop-carried dependence on sum Questo codice somma gli elementi del vettore stesso creando però una dipendenza di dati. Ridurre questa situazione a operazioni vettoriali significa dividere a metà il vettore e trattarlo come due vettori distinti, per poter eseguire le operazioni vettoriali possibili. Quindi si sommano i rispettivi elementi per ottenere un terzo vettore; a sua volta questo vettore viene diviso a metà per operare ancora sui suoi elementi. Quando il numero degli elementi si riduce, diventa molto piccolo o dispari, allora si trattano gli elementi del vettore come degli scalari. Schematicamente la situazione è la seguente: VETTORE A VLR 2 VETTORE A VLR + = VETTORE B SCALARE A SCALARE B sum = 70 VETTORE A2 Pagina 117

118 ESERCIZIO Ottimizzare un loop che calcoli: Y=aX+bY (X e Y vettori, a e b scalari) per una CPU VETTORIALE, cercando di ridurre al minimo il numero di stalli. Essendo la dimensione dei registri vettoriali da 64 elementi, ogni vettore sarà spezzettato in un vettore Remainder da 32 elementi e in un vettore da 64 elementi. La situazione si può riassumere con la seguente figura: Supponiamo: R1, R2: registri contenenti gli indirizzi dei due vettori, A e B; R3: registro contenente la dimensione (96) dei vettori; R29, R30: registri contenenti rispettivamente gli scalari a e b. Il codice non ottimizzato è il seguente: 1 ANDI R4, R3, 63 2 MTC1 VLR, R4 3 LOOP: LV.D V1, R1 4 DSLL R5, R4, 3 5 DADDU R1, R1, R5 6 LV.D V2, R2 7 DADDU R2, R2, R5 8 MULTSV.D V1, V1, R29 9 MULTSV.D V2, V2, R30 10 ADDV.D V2, V1, V2 11 SV.D V2, R2 12 DADD R3, R3, -R4 13 LI R4, MTC1 VLR, R4 15 BGTZ R3, LOOP Pagina 118

119 OTTIMIZZAZIONE Prima di tutto è possibile, sfruttando la forma base+spiazzamento, utilizzare un unico registro per l incremento dei registri R1 e R2 evitando così di utilizzare due istruzioni (5 e 7). Il registro base conterrà l indirizzo del primo elemento del vettore, quindi diverso per ogni vettore, mentre lo spiazzamento, comune per tutti i vettori, conterrà il valore del salto per accedere al blocco di dati successivo. Per cui è possibile riscrivere le load/store nella seguente maniera: La sintassi da seguire è: LV.D dest, offset(base) LV.D V1, R7(R1) LV.D V2, R7(R2) SV.D V2, R7(R2) Dove R7 è il registro contenente lo spiazzamento; per cui basterà incrementarlo per accedere al blocco di dati successivo; per cui R7 è l unico indice che opera all interno del loop. In questo modo è possibile anche escludere il registro R3 che precedentemente faceva da contatore, ed usare R7 come registro su cui effettuare il controllo. Si ricordi che nel caso scalare, il problema veniva affrontato processando il vettore a partire dall ultimo elemento fino ad arrivare al primo, con un decremento dell indice di 8 byte. Nel caso del processore vettoriale, l indice non punterà all ultimo elemento, ma al primo elemento dell ultimo sottovettore, che, per una migliore implementazione, è il vettore remainder; per cui l indice ad ogni iterazione verrà decrementato di 64 elementi, ossia di 64 8 = 512 byte. Il decremento, sottoforma d istruzione, è il seguente: DADDI R7, R7, #-512 Per chiarire quando detto si consideri il seguente esempio: Si supponga un vettore di 140 elementi; questo vettore sarà diviso in due sottovettori da 64 elementi e un sottovettore da 12 elementi. Considerando il sottovettore remainder come ultimo blocco, l indice punterà al suo primo elemento, per cui attraverso il decremento di 512 byte si avrà accesso al primo elemento del secondo sottoblocco e successivamente, con un ulteriore decremento al primo elemento del primo sottoblocco. Le seguenti figure chiariscono la scelta di porre per ultimo il sottovettore remainder. L indice punterà al primo elemento dell ultimo sottoblocco R7 L indice punterà al primo elemento del R7 secondo sottoblocco L indice punterà al primo elemento del primo sottoblocco R7 Per posizionare R7 bisogna calcolare l indirizzo del primo elemento del sottovettore remainder. Questo è possibile attraverso l operazione: N remainder 8. Pagina 119

120 Fatte queste considerazioni il codice parzialmente ottimizzato è il seguente: 1 ANDI R4, R3, 63 2 MTC1 VLR, R4 3 DSUBI R7, R3, R4 4 DMULI R7, R7, #8 5 LOOP: LV.D V1, R7(R1) 6 MULTSV.D V1, V1, R29 7 LV.D V2, R7(R2) 8 MULTSV.D V2, V2, R30 9 ADDV.D V2, V1, V2 10 SV.D V2, R7(R2) 11 DADDI R7, R7, # MTC1 VLR, #64 13 BGEZ R7, LOOP Adesso vediamo come è possibile schedulare meglio il loop per eliminare gli eventuali stalli presenti. Dopo le due load ci sarà uno stallo con le successive operazioni di moltiplicazione che utilizzano come sorgenti i registri destinazione delle load. L istruzione BGEZ provoca uno stallo: sposto l istruzione MTC1 VLR, #64 nel delay slot sotto alla BCEZ. Per concludere il codice ottimizzato è il seguente (considerando unitaria la latenza di ciascuna unità funzionale): 1 ANDI R4, R3, 63 2 DSUBI R7, R3, R4 3 MTC1 VLR, R4 4 DMULI R7, R7, #8 5 LOOP: LV.D V1, R7(R1) 6 LV.D V2, R7(R2) 7 MULTSV.D V1, V1, R29 8 MULTSV.D V2, V2, R30 9 ADDV.D V2, V1, V2 10 SV.D V2, R7(R2) 11 DADDI R7, R7, # BCEZ R7, LOOP 13 MTC1 VLR, #64 Pagina 120

121 Analizziamo ora i diagrammi temporali delle istruzioni fondamentali per l operazione da effettuare; si consideri per semplicità che la cpu vettoriale sia ad una sola corsia e che la banda passante della memoria dati sia di tre dati per colpo di clock, per cui è possibile effettuare tre accessi in memoria. Inoltre si consideri la presenza di due moltiplicatori con una latenza di 4 colpi di clock, per cui dopo 4 cc il moltiplicatore mette a disposizione il primo risultato; due sommatori con una latenza di 2 colpi di clock. LEGENDA Disponibilità 1 elemento: Disponibilità 2 elemento: Disponibilità elementi successivi: Disponibilità ULTIMO elemento: Per il seguente diagramma VLR è impostato al valore 64 COLPI DI CLOCK ISTRUZIONI LV.D V1, R7(R1) IF ID EX MEM WB LV.D V2, R7(R2) IF ID EX MEM WB MULTSV.D V1, V1, R29 IF ID EX MEM WB MULTSV.D V2, V2, R30 IF ID EX MEM WB ADDV.D V2, V1, V2 IF ID STALLO EX MEM WB SV.D V2, R7(R2) IF ID EX STALLO MEM WB Bisogna quindi aggiungere le ulteriori istruzioni di gestione; il procedimento da seguire è analogo a quanto appena fatto. Per cui si completa l intera operazione Y=aX+bY con vettori da 64 elementi dopo 76 colpi di clock, senza contare le istruzioni di gestione fuori e dentro al loop. Chiarito questo, si supponga di avere la stessa cpu vettoriale con la sola differenza che adesso consideriamo 8 corsie. Questo significa che per ogni colpo di clock verranno effettuate 8 operazioni, per ogni istruzione vettoriale, per cui ad esempio una istruzione di load vettoriale caricherà in un solo colpo di clock 8 elementi. Per cui si riducono i colpi di clock e ne risulta il seguente diagramma: LEGENDA Disponibilità 1 8 elemento: Disponibilità 9 16 elemento: Disponibilità elemento: Disponibilità elemento: Per il seguente diagramma VLR è impostato al valore 64 COLPI DI CLOCK ISTRUZIONI LV.D V1, R7(R1) IF ID EX MEM WB LV.D V2, R7(R2) IF ID EX MEM WB MULTSV.D V1, V1, R29 IF ID EX MEM WB MULTSV.D V2, V2, R30 IF ID EX MEM WB ADDV.D V2, V1, V2 IF ID STALLO EX MEM WB SV.D V2, R7(R2) IF ID EX STALLO MEM WB Per cui si completa l intera operazione Y=aX+bY con vettori da 64 elementi dopo 19 colpi di clock. Pagina 121

122 Il diagramma completo per l esercizio assegnato è il seguente: si consideri una cpu a 8 corsie. LEGENDA Disponibilità 1 8 elemento del sottovettore: Disponibilità 9 16 elemento del sottovettore: Disponibilità elemento del sottovettore: Disponibilità elemento del sottovettore: COLPI DI CLOCK ISTRUZIONI ANDI R4, R3, 63 IF ID EX ME M WB ANDI R7, R3, R4 IF ID EX ME M WB MTC1 VLR, R4 VLR = 32 IF ID EX ME M WB DMULI R7, R7, #8 IF ID EX ME M WB LV.D V1, R7(R1) IF ID EX ME M WB LV.D V2, R7(R2) IF ID EX ME M WB MULTSV.D V1, V1, R29 IF ID EX ME M WB MULTSV.D V2, V2, R30 IF ID EX ME M WB ADDV.D V2, V1, V2 IF ID STALLO EX ME M WB SV.D V2, R7(R2) IF ID EX STALLO ME M WB DADDI R7, R7, #-512 IF ID EX ME M WB BCEZ R7, LOOP IF ID EX ME M WB MTC1 VLR, #64 VLR = 64 IF ID EX ME M WB LV.D V1, R7(R1) IF ID EX ST AL ME M WB LV.D V2, R7(R2) IF ID EX STALLO ME M WB MULTSV.D V1, V1, R29 IF ID EX ME M WB MULTSV.D V2, V2, R30 IF ID EX STALLO ME M WB ADDV.D V2, V1, V2 IF ID STALLO EX STALLO M E W B SV.D V2, R7(R2) ID ID EX STALLO M E W B DADDI R7, R7, #-512 IF ID EX ME M WB BCEZ R7, LOOP IF ID EX ME M WB MTC1 VLR, #64 IF ID EX ME M WB È possibile sovrapporre alcune fasi, poiché queste utilizzano unità funzionali diverse, o perché si è ipotizzato che alcune unità, come la memoria, possiedono una banda di dati maggiore. Essendo i vettori di 96 elementi il loop sarà eseguito due volte, prima con VLR = 32 e poi con VLR = 64; per eseguire l operazione richiesta ci vorranno 37 colpi di clock (la tabella non è completa per motivi di spazio). Pagina 122

123 ARCHITETTURA MULTICORE Fino ad ora si è visto come potessero essere migliorate le prestazioni di un calcolatore puntando su architetture ILP (Instruction Level Parallelism), cioè quelle architetture basate sul parallelismo delle istruzioni che con una serie di accorgimenti, quali pipeline delle unità funzionali, riduzione dei conflitti, predizione dei salti, ecc., hanno permesso di ottenere la miglior soluzione possibile per l ottimizzazione delle prestazioni; inoltre con l utilizzo di hardware particolari (VLIW, Super Scalare, Vettoriale) si è contribuito all aumento delle prestazioni, il tutto utilizzando una sola cpu. Quello che emerge è che l aumento delle prestazioni che è possibile ottenere è fortemente legato all hardware di controllo, il quale deve gestire al meglio la contemporanea esecuzione delle istruzioni in maniera da evitare conflitti; non sempre però questo porta ad un effettivo ed evidente miglioramento delle prestazioni. Infatti alcune valutazioni hanno evidenziato che insistere in queste direzioni non porta ad avere una effettiva efficienza (generalmente: EFFICIENZA = RISULTATI ). COSTI Inoltre queste valutazioni hanno evidenziato che è possibile mantenere alta l efficienza con un numero di processori maggiori. Seguendo queste valutazioni si è arrivati, grazie alla tecnologia a disposizione, a realizzare in un singolo chip più di un processore. Questa tecnologia risulta interessante, poiché ha costi relativamente bassi, in quanto si va replicare il singolo processore e quindi non richiede una riprogettazione complessa. Quindi invece di rinforzare, potenziare una singola caratteristica si va a replicare l intera cpu; il potenziamento di una caratteristica migliora le prestazioni di quella parte di esecuzione del programma che va ad usare quella componente, e quindi non vi è un miglioramento globale del sistema. La seguente figura mostra come l aumento dei registri, non comporta una miglioramento proporzionale al potenziamento eseguito. Passando da 32 a 128 registri, quindi quadruplicandone il numero, non si nota un aumento proporzionale delle istruzioni parallele, per cui non sempre il potenziamento si traduce in un effettivo miglioramento. Questo significa che il punto critico è diventato un altro aspetto; analogo discorso si potrebbe avere analizzando un miglioramento delle predizioni di salto. Pagina 123

124 PARALLELISMO A LIVELLO DI THREAD, MULTI-THREAD Per thread si intende un processo indipendente da un altro processo; indipendente nel senso che può appartenere allo stesso programma, ma che non è influenzato dagli esiti determinati dagli altri processi che costituiscono il programma. Ogni thread ha i suoi dati, istruzioni, registri necessari alla sua esecuzione. Fondamentalmente esistono tre tipi di multithread: 1. SIMULTANEOUS MULTI-THREADING: consideriamo una CPU che permette teoricamente di eseguire in simultaneo 8 istruzioni, grazie alla presenza di più unità funzionali uguali. L esecuzione di un singolo thread potrebbe generare una situazione del genere: In un colpo di clock dovrebbero essere prelevate 8 istruzioni, ma questo, come si vede, non avviene, poiché evidentemente non vi sono istruzioni che usano unità funzionali diverse. Quindi in un colpo di clock saranno processate poche istruzioni, provocando anche eventuali stalli. È possibile pensare di utilizzare le unità funzionali inutilizzate usando istruzioni di un altro thread; questo perché per definizione i thread sono indipendenti fra loro, quindi lo saranno anche i loro dati. Ciò significa che non vi saranno conflitti di dati: la situazione in presenza di un altro thread è rappresentata dalla seguente figura. Per cui i thread partono simultaneamente sfruttando le unità funzionali non utilizzate da un altro thread. 2. FINE-GRAINED MULTI-THREADING: (a grana fina) questa tipologia di multithreading prevede che il processore scambi il thread in esecuzione a ogni ciclo di clock. Questa tipologia di multithreading dovrebbe rimuovere la dipendenza dai dati dei singoli thread e quindi dovrebbe azzerare o comunque ridurre gli stalli della pipeline dovuta alla dipendenza dai dati. Dato che ogni thread dovrebbe funzionare in modo indipendente i singoli thread eseguiranno programmi non correlati e quindi vi saranno poche probabilità che le istruzioni di un thread necessitino dei risultati elaborati da un'istruzione di un altro thread in esecuzione in quel momento. 3. COARSE-GRAINED MULTI-THREAD: (a grana grossa) questa tipologia di multithread prevede che il processore esegua un singolo thread fino a quando questo non viene bloccato da un evento che normalmente ha una elevata latenza (per esempio un cache miss), in questo caso il processore provvede a eseguire un altro thread che era pronto per l'esecuzione. Il thread di rimpiazzo rimane in esecuzione fino a quando termina o viene bloccato da un evento. Per queste ultime due tipologie di multithread bisogna fare delle considerazioni: il multithreading parte dal presupposto che il passaggio tra thread avvenga in modo rapido; queste due tecniche effettuano il passaggio in un ciclo di clock. Al fine di ottenere questo il processore deve replicare alcune componenti per i due thread come i registri interni, il program counter e alcuni registri di stato. Per cui un cambio di contesto ottimizzato è fondamentale per avere tempi estremamente bassi. Pagina 124

125 Di seguito è riportato uno schema riassuntivo delle varie tecniche di parallelismo. MEMORIA CONDIVISA E MEMORIA DISTRIBUITA IN SISTEMI MULTICORE La categoria normalmente utilizzata nelle architetture multicore è quella a memoria condivisa; N core, ognuno comprendente una memoria cache, condividono un unica memoria centrale. Un altra categoria è caratterizzata da memorie locali per ogni core, che sono sincronizzate da una particolare infrastruttura, anche complessa, per mantenere una certa coerenza fra i dati. Si utilizza una memoria condivisa quando non è possibile individuare delle aree dati distinte e indipendenti per ogni singolo thread che ogni core deve eseguire. Per cui questa soluzione è ottimale dal punto di vista della coerenza fra i dati. Il problema legato a questa categoria è dovuto al fatto che diversi core devono accedervi contemporaneamente; ma questo non è possibile, o comunque non in elevate quantità, poiché la memoria possiede una banda passante finita, che limita gli accessi ad essa stessa. Per cui è evidente che una soluzione a memoria condivisa è effettivamente praticabile quando si utilizza un numero di core basso. Per superare quindi questo limite è opportuno implementare la categoria a memoria distribuita; l implementazione richiede la realizzazione di una efficiente rete di interconnessione, in modo da ridurre il tempo di comunicazione tra le memorie. Pagina 125

126 Indice Analitico A ALEE ISTRUZIONI ALU ISTRUZIONI BRANCH ISTRUZIONI LOAD RAW - WAW - WAR - RAR Amdahl, legge di Associativa... Vedi Memorie Cache B Banchi interlacciati Banchi paralleli C Clean Bit COARSE-GRAINED MULTI-THREAD Codifica dell'istruzione Completamente Associativa... Vedi Memorie cache Componenti del processore No- Pipeline... Vedi Processore No- Pipeline Control Unit Microprogrammata, Cablata Corsie D Dead Time Delay Slot Dirty Bit DRAM E EX - Execution F FIFO, metodo... Vedi Sostituzione FINE-GRAINED MULTI-THREADING Finestra dei registri Floating point Scheduling istruzioni G Gerarchia di memoria H HIT RATE HIT TIME I ID - Instruction Decode IF - Instruction Fetch Indirizzamento diretto Vedi Memorie cache Istruzioni... 7 di calcolo di controllo di tipo MOV... 9 di trasferimento dei dati... 7 Formato delle fuori ordine LVWS Set, floating point Set, vettoriale Superscalare Vettoriali Parallelismo VLIW Istruzioni di tipo I. Vedi Formato delle istruzioni Istruzioni di tipo Jump.. Vedi Formato delle istruzioni Istruzioni di tipo R Vedi Formato delle istruzioni L LRU, metodo... Vedi Sostituzione M MEM - Memory Access Memorie cache ad indirizzamento diretto Allocazione dei blocchi Completamnte associative Elettronica Funzionamento logico delle Organizzazione Prestazioni... 71; 78 Problematiche Scrittura Pagina 126 set associativa Memorie Cache Accesso alla memoria LOAD/STORE disallineata MIPS64 Set istruzioni MISS PENALITY MISS RATE MOTOROLA MVLR...Vedi Registri P Pipeline ALEE Strutturali, di dato da programma Microistruzioni Struttura processore Tecnica PowerPC Prinicipi di località Processore Accumulatore Floating point Multicore No-Pipeline Pipeline Ottimizzato Superscalare Vettoriale CRAY VLIW R Random, metodo... Vedi Sostituzione Registri... 9 V.LENGHT V.MASK Vettoriali VLR, MVLR Ricerca e identificazione S Salto Condizionato, Incondizionato Scoreboard Set, istruzioni Shift, istruzioni Logico, Aritmetico SIMULTANEOUS MULTI-THREADING Sostituzione SRAM... 70

127 Stazioni di prenotazione... Vedi Tomasulo, algoritmo Strotolamento T Tecnica Speculativa Tipi di dati... 7 Floating Point... 7 Interi... 7 Vettoriali Tomasulo, algoritmo Trasparenza dei livelli V V.LENGHT... Vedi Registri V.MASK... Vedi Registri uso del registro VECTOR STRIPMINING VLR...Vedi Registri W Write Back Write Through BIBLIOGRAFIA 1. JOHN L. HENNESSY, DAVID A. PATTERSON, Architettura degli elaboratori, 4 a edizione, APOGEO 2. PROF. ING. F. MARINO, G. MASTRONARDI Supporto Multimediale di Ausilio al Corso di CALCOLATORI ELETTRONICI, 3. DAVID A. PATTERSON, Slide di alcune lezioni scaricabili dal link: WIKIPEDIA, L enciclopedia libera Pagina 127

128 ESERCIZI DI A cura di: Fabio Stroppa Nicola Pietroleonardo

129 Esercizi di Calcolatori Elettronici A.A. INDICE MICROCODICE DELLE ISTRUZIONI FONDAMENTALI... 2 ESERCIZI MICROCODICE... 3 ESERCIZIO 1 - ADDW R1 R2 R ESERCIZIO 2 - ADDMEM R1 R2 R ESERCIZIO 3 ADD3 R1 R2 R ESERCIZIO 4 MAC R1,(R2),R ESERCIZIO 5 SWP R1 R ESERCIZIO 6 SWX R2 R31 R ESERCIZIO 7 LL R6 (#100,R3) ESERCIZIO 8 SL (#100,R3) R ESERCIZIO 9 SWPM R1 R ESERCIZI ASSEMBLY ESERCIZIO 1 SOMMA DI DUE VETTORI ESERCIZIO 2 MEDIA DI UN VETTORE ESERCIZIO 3 MINIMO DI UN VETTORE ESERCIZIO 4 LOAD DOUBLE NON ALLINEATA ESERCIZIO 5 STORE DOUBLE NON ALLINEATA ESERCIZIO 6 SOMMA DI VETTORI PIPELINE DA PROGRAMMA ALGORITMO DI TOMASULO ESERCIZIO ESERCIZIO ESERCIZI ASSEMBLY PROCESSORI SUPERSCALARI E VLIW ESERCIZIO ESERCIZI ASSEMBLY DLXV ESERCIZIO 1 SOMMA VETTORI DA 64 ELEMENTI ESERCIZIO 2 SOMMA DI VETTORI > ESERCIZIO 3 SOMMA DI MATRICI CON MxN > ESERCIZIO 4 OPERAZIONE Y = (ax + by)/c ESERCIZIO 5 PRODOTTO SCALARE TRA VETTORI DI 64 ELEMENTI Pagina 1

130 Esercizi di Calcolatori Elettronici A.A. MICROCODICE DELLE ISTRUZIONI FONDAMENTALI IF IF/ID.IR Mem[PC]; IF/ID.NPC (if ((EX/MEM.opcode == branch)or(ex/mem.opcode == jump) & EX/MEM.cond) {(EX/MEM.ALUOutput)} else{pc+4}); ID ID/EX.A Regs[IF/ID.IR[rs]]; ID/EX.B Regs[IF/ID.IR[rt]]; ID/EX.Imm sign-extended(if/id.ir[immediate field]); ID/EX.IR IF/ID.IR; ID/EX.NPC IF/ID.NPC; ISTRUZIONE DI DIRAMAZIONE EX EX/MEM.ALUOutput ID/EX.NPC + (ID/EX.Imm << 2); EX/MEM.cond (ID/EX.A == 0); MEM WB ISTRUZIONE ALU R op R EX EX/MEM.IR ID/EX.IR; EX/MEM.ALUOutput ID/EX.A op ID/EX.B; MEM MEM/WB.IR EX/MEM.IR; MEM/WB.ALUOutput EX/MEM.ALUOutput; WB Regs[MEM/WB.IR[rd]] MEM/WB.ALUOutput; ISTRUZIONE ALU R op Imm EX EX/MEM.IR ID/EX.IR; EX/MEM.ALUOutput ID/EX.A op ID/EX.Imm; MEM MEM/WB.IR EX/MEM.IR; MEM/WB.ALUOutput EX/MEM.ALUOutput; WB Regs[MEM/WB.IR[rd]] MEM/WB.ALUOutput; ISTRUZIONE LOAD EX EX/MEM.IR ID/EX.IR; EX/MEM.ALUOutput ID/EX.A + ID/EX.Imm; MEM MEM/WB.IR EX/MEM.IR; MEM/WB.LMD Mem[EX/MEM.ALUOutput]; WB Regs[MEM/WB.IR[rt]] MEM/WB.LMD; ISTRUZIONE STORE EX EX/MEM.IR ID/EX.IR; EX/MEM.ALUOutput ID/EX.A + ID/EX.Imm; EX/MEM.B ID/EX.B; MEM MEM/WB.IR EX/MEM.IR; Mem[EX/MEM.ALUOutput] EX/MEM.B; WB Pagina 2

131 Esercizi di Calcolatori Elettronici A.A. ESERCIZI MICROCODICE ESERCIZI MICROCODICE Pagina 3

132 Esercizi di Calcolatori Elettronici A.A. ESERCIZIO 1 - ADDW R1 R2 R3 Scrivere un microprogramma per l'istruzione ADDW R1 R2 R3 che fa R1=M[R2]+M[R3] per un MIPSpipeline, discutere i conflitti e possibili soluzioni architetturali. Equivale alla successione di queste operazioni assembly: LD R4, 0(R2) LD R5, 0(R3) DADD R1, R4, R5 Tale codice presenta uno stallo dopo l istruzione di load per conflitto di dati, in quanto il registro operando della somma è il registro destinazione della load, la quale al momento della fase exe dell istruzione di somma non ha ancora scritto in tale registro il valore prelevato dalla memoria. Conteggiamo quindi 4 istruzioni, che vengono eseguite in 5+(4-1) = 8 colpi di clock. IF IF/ID.IR Mem[PC]; IF/ID.NPC PC+4; ID ID/EX.IR IF/ID.IR; ID/EX.NPC IF/ID.NPC; ID/EX.A Regs[IF/ID.IR[rs]]; ID/EX.B Regs[IF/ID.IR[rt]]; ID/EX.Imm sign-extended(if/id.ir[immediate field]); In realtà l indirizzo a cui fare riferimento in memoria è già presente nei registri R2 ed R3 caricati nei latch ID/EX.A ed ID/EX.B nella fase di ID, dunque non è necessario sommare un immediato nullo. L ALU non svolge alcuna operazione di somma e la fase EX si limita a propagare il valore di A e B rispettivamente nel latch EX/MEM.ALUOutput e EX/MEM.B. EX1 EX/MEM.IR ID/EX.IR; EX/MEM.ALUOutput ID/EX.A; EX/MEM.B ID/EX.B; L operazione di MEM prevede due accessi alla memoria: uno per prelevare il primo dato MEM1 (indirizzo salvato in R2, A) e un altro per prelevare il secondo dato MEM2 (indirizzo salvato in R3, B). Quindi avremo bisogno di due fasi di MEM. È utile che, contemporaneamente al salvataggio nei latch del primo operando dalla memoria, venga sostituito il valore di EX/MEM.ALUOutput con il valore di B per contenere il secondo operando, così da ripetere nel colpo di clock successivo la medesima operazione. In realtà, se si utilizza lo stesso latch EX/MEM.ALUOutput si rischia di incorrere in un problema di incoerenza dei dati: l istruzione schedulata un colpo di clock dopo quella di interesse si troverà in fase EX mentre questa è in MEM1 e aggiornerà il valore di EX/MEM.ALUOutput con il risultato della sua operazione con l ALU, dunque è necessario salvare B in un altro latch aggiuntivo che chiamiamo EX/MEM.ALUOutput2. MEM1 MEM/WB.IR EX/MEM.IR; MEM/WB.LMD Mem[EX/MEM.ALUOutput]; EX/MEM.ALUOutput2 EX/MEM.B; Pagina 4

133 Esercizi di Calcolatori Elettronici A.A. Avendo ora disponibile B in EX/MEM.ALUOutput2 si può pensare al prelievo dalla memoria di un altra istruzione, la quale scriverà nuovamente in MEM/WB.LMD per contenere il secondo operando. È dunque importante salvare il valore del primo operando in MEM/WB.ALUOutput così da non perdere il dato. Attenzione, stesso problema precedente: nel caso l istruzione schedulata nel colpo di clock successivo a quella di interesse sia un operazione di ALU, la sua fase MEM verrà eseguita in contemporanea con la fase MEM2 in quanto tale operazione non farà effettivamente uso della memoria e quindi non crea conflitti o stalli; viene però modificato il valore di MEM/WB.ALUOutput al termine della fase di MEM, quindi è saggio salvare il primo operando (A) in un altro latch che chiamiamo MEM/WB.ALUOutput2, senza scomodare minimamente MEM/WB.ALUOutupt che sarà impegnato (probabilmente) dall istruzione successiva. Il prelievo del dato salvato in memoria nell indirizzo contenuto in EX/MEM.ALUOutput2 (B) viene ora salvato in MEM/WB.LMD, ma l operazione di lettura da memoria e scrittura nel registro può essere pensata come divisa in due fasi, ciascuna lunga un semiciclo di clock: nel primo semiciclo viene letto il dato in memoria all indirizzo EX/MEM.ALUOutput2 e nel secondo semiciclo viene scritto tale valore nel latch MEM/WB.LMD: non vi è alcuna sovrascrittura, in quanto abbiamo già salvato MEM/WB.LMD in MEMWB.ALUOutput2 durante il primo semiciclo. È importante inoltre che l IR dell istruzione continui a propagarsi nella pipeline, e quindi tale valore dovrà essere spostato da MEM/WB.IR in quanto tale latch ora ospiterà l IR dell istruzione schedulata successivamente quella di interesse. Dunque, salviamo l IR in un nuovo latch che chiamiamo MEM/WB.IR2. MEM2 MEM/WB.IR2 MEM/WB.IR; MEM/WB.ALUOutput2 MEM/WB.LMD; MEM/WB.LMD Mem[EX/MEM.ALUOutput2]; Avendo ora a disposizione entrambi gli operandi, è possibile compiere l operazione di somma. Si pensa di aggiungere un sommatore esterno all ALU in modo da non creare conflitti con istruzioni schedulate 3 colpi di clock dopo quella di interesse. EX2 MEM/WB.ALUOutput2 MEM/WB.LMD + MEM/WB.ALUOutput2; WB Regs[MEM/WB.IR2[rd]] MEM/WB.ALUOutput2; L istruzione viene eseguita in 7 colpi di clock, risparmiandone 1 rispetto alla sua scissione in 3 istruzioni. Ci saranno stalli obbligatori se l istruzione che segue la nostra ADDW è una load o store, che fa uso effettivo nella memoria (che sarà occupata in quel momento) oppure se la seconda istruzione schedulata dopo la ADDW è un istruzione ALU oppure una LOAD, che scrive nei registri durante la fase di write back. Al progetto del processore pipeline abbiamo aggiunto tre latch ed un sommatore. Pagina 5

134 Esercizi di Calcolatori Elettronici A.A. ESERCIZIO 2 - ADDMEM R1 R2 R3 Scrivere un microprogramma per l'istruzione ADDMEM R1 R2 R3 che fa Mem[R1]=Mem[R2]+Mem[R3] per un MIPS-pipeline, discutere i conflitti e possibili soluzioni architetturali. Equivale alla successione di queste operazioni assembly: LD R4, 0(R2) LD R5, 0(R3) DADD R6, R4, R5 SD 0(R1), R6 Tale codice presenta uno stallo dopo l istruzione di load per conflitto di dati, in quanto il registro operando della somma è il registro destinazione della load, la quale al momento della fase exe dell istruzione di somma non ha ancora scritto in tale registro il valore prelevato dalla memoria. Non vi sono stalli dopo l istruzione di somma, nonostante il suo registro destinazione sia il registro operando dell istruzione di store successiva se si pensa a cortocircuitare l ALU del processore in modo tale da evitare questi conflitti di dati. Conteggiamo quindi 5 istruzioni, che vengono eseguite in 5+(5-1) = 9 colpi di clock. L istruzione da codificare è essenzialmente simile all esercizio precedente, con l unica differenza che il risultato della somma non deve essere salvato in un registro ma in memoria, dunque si rende necessaria l operazione finale di store. Le modifiche apportate al processore per l operazione dell esercizio precedente rimangono inalterate. IF IF/ID.IR Mem[PC]; IF/ID.NPC PC+4; ID ID/EX.IR IF/ID.IR; ID/EX.NPC IF/ID.NPC; ID/EX.A Regs[IF/ID.IR[rs]]; ID/EX.B Regs[IF/ID.IR[rt]]; ID/EX.Imm sign-extended(if/id.ir[immediate field]); EX1 EX/MEM.IR ID/EX.IR; EX/MEM.ALUOutput ID/EX.A; EX/MEM.B ID/EX.B; MEM1 MEM/WB.IR EX/MEM.IR; MEM/WB.LMD Mem[EX/MEM.ALUOutput]; EX/MEM.ALUOutput2 EX/MEM.B; MEM2 MEM/WB.IR2 MEM/WB.IR; MEM/WB.ALUOutput2 MEM/WB.LMD; MEM/WB.LMD Mem[EX/MEM.ALUOutput2]; Dovendo salvare il risultato in memoria, si rende necessaria la lettura dell indirizzo a cui fare riferimento dal registro in cui è contenuto. Si nota una cosa fondamentale: durante la seconda fase di EX si scrive nel Pagina 6

135 Esercizi di Calcolatori Elettronici A.A. registro EX/MEM.B: tale operazione può portare a dei conflitti di dati se l istruzione schedulata tre colpi di clock dopo la ADDMEM è un operazione di store: Nella sua fase di EXE, la store scriverà il valore di ID/EX.B in EX/MEM.B per propagare il valore di B, utilizzando quindi il latch EX/MEM.B. Dunque, per evitare problemi di questo tipo, sarebbe consigliabile propagare ulteriormente il valore di B della istruzione di ADDMEM da EX/MEM.B a MEM/WB.B aggiungendo un nuovo registro al latch del processore. In realtà, successivamente scopriremo che l aggiunta di questo registro nel latch è inutile. EX2 MEM/WB.ALUOutput2 MEM/WB.LMD + MEM/WB.ALUOutput2; MEM/WB.B Regs[M/WB.IR2[rd]; } da svolgere nel secondo semiciclo di clock, lettura da registro MEM3 Mem[MEM/WB.B] MEM/WB.ALUOutput2; L istruzione viene eseguita in 7 colpi di clock, risparmiandone 2 rispetto alla sua scissione in 4 istruzioni. Ci saranno stalli obbligatori se l istruzione che segue la nostra ADDMEM è una load o store, che fa uso effettivo nella memoria (che sarà occupata in quel momento). Stesso discorso per l istruzione schedulata tre colpi di clock dopo la ADDMEM, che cadrà in fase MEM quando la ADDMEM è in MEM3. In base a quanto detto, la terza operazione dopo la ADDMEM, se è una store, provocherà uno stallo: tornando al discorso in cui si consigliava la presenza del latch MEM/WB.B si nota ora che è possibile utilizzare per tale funzione lo stesso registro EX/MEM.B; spostando infatti lo stallo che si trova dopo la fase EX della store prima della EX stessa, non si avranno problemi di sovrascrittura e di conflitti di memoria. Pagina 7

136 Esercizi di Calcolatori Elettronici A.A. ESERCIZIO 3 ADD3 R1 R2 R3 Scrivere un microprogramma per l'istruzione ADD3 R1 R2 R3 che fa R1=R1+R2+R3 per un MIPS-pipeline, discutere i conflitti e possibili soluzioni architetturali. Equivale alla successione di queste operazioni assembly: DADD R1, R1, R2 DADD R1, R1, R3 Tale codice non presenta stalli se si considera la corto circuitazione dell ALU. Conteggiamo quindi 2 istruzioni, che vengono eseguite in 5+(2-1) = 6 colpi di clock. IF IF/ID.IR Mem[PC]; IF/ID.NPC PC+4; ID ID/EX.IR IF/ID.IR; ID/EX.NPC IF/ID.NPC; ID/EX.A Regs[IF/ID.IR[rs]]; ID/EX.B Regs[IF/ID.IR[rt]]; ID/EX.Imm sign-extended(if/id.ir[immediate field]); La fase di EX1 dovrà sommare I registri R2 ed R3 e nel frattempo caricare R1 affinché l operazione di somma sia completata al colpo di clock successivo. Possiamo pensare di leggere R1 nella fase di ID aggiungendo un nuovo registro nel latch ID/EX chiamato C e propagarlo anche nel latch EX/MEM, quindi aggiungendo due registri; oppure si può pensare di potenziare l accesso alla memoria registri in modo tale da poter effettuare più letture in parallelo, in questo caso inserendo un ulteriore fase di ID nella fase EX1 questa non andrà in conflitto con la fase ID processata contemporaneamente dal processore per l istruzione schedulata un colpo di clock dopo. Si utilizza quindi il già presente registro EX/MEM.B. EX1 EX/MEM.IR ID/EX.IR; EX/MEM.ALUOutput ID/EX.A + ID/EX.B; EX/MEM.B Regs[ID/EX.IR[rd]]; EX2 MEM/WB.IR EX/MEM.IR; MEM/WB.ALUOutput EX/MEM.ALUOutput + EX/MEM.B; WB Regs[MEM/WB.IR[rd]] MEM/WB.ALUOutput; Inserendo un sommatore aggiuntivo nella fase di MEM, nominata EX2 per questa istruzione, non si hanno conflitti con l istruzione schedulata al colpo di clock successivo. L istruzione viene eseguita in 5 colpi di clock, risparmiandone 1 rispetto alla sua scissione in 2 istruzioni. Non ci sono stalli o conflitti con istruzioni successive. Pagina 8

137 Esercizi di Calcolatori Elettronici A.A. ESERCIZIO 4 MAC R1,(R2),R3 Scrivere un microprogramma per l'istruzione MAC R1,(R2),R3 che in RTL significa R1<-R1+M[R2]*R3 per un MIPS-pipeline, discutere i conflitti e possibili soluzioni architetturali (non si prevede un architettura tale da avere una ALU che svolge l istruzione MADD). Equivale alla successione di queste operazioni assembly: LD R4, 0(R2) DMUL R4, R4, R3 DADD R1, R1, R4 Tale codice presenta uno stallo dopo l istruzione di load per conflitto di dati, in quanto il registro operando della moltiplicazione è il registro destinazione della load, la quale al momento della fase exe dell istruzione di moltiplicazione non ha ancora scritto in tale registro il valore prelevato dalla memoria. Non vi sono stalli tra la mul e la add se si considera la corto circuitazione dell ALU. Conteggiamo quindi 4 istruzioni, che vengono eseguite in 5+(4-1) = 8 colpi di clock. IF IF/ID.IR Mem[PC]; IF/ID.NPC PC+4; ID ID/EX.IR IF/ID.IR; ID/EX.NPC IF/ID.NPC; ID/EX.A Regs[IF/ID.IR[rs]]; ID/EX.B Regs[IF/ID.IR[rt]]; ID/EX.Imm sign-extended(if/id.ir[immediate field]); La prima cosa da fare è accedere a memoria per caricare il dato dall indirizzo contenuto in R2 (a cui non va sommato alcun immediato). Contemporaneamente, propaghiamo il valore di R3 (contenuto in B) nel latch EX/MEM ma utilizzando un altro registro chiamato B2: questo perché se l istruzione schedulata un colpo di clock dopo questa è un istruzione di store al termine della sua fase di EX (ovvero nel colpo di clock in cui la MAC è in fase di MEM) sovrascriverà il valore di EX/MEM.B con il suo rt ed il valore che poi verrà successivamente letto dalla MAC per l operazione di moltiplicazione non sarà il valore di rt della MAC ma della store che le succede. EX1 EX/MEM.IR ID/EX.IR; EX/MEM.ALUOutput ID/EX.A; EX/MEM.B2 ID/EX.B; MEM MEM/WB.IR EX/MEM.IR; MEM/WB.LMD Mem[EX/MEM.ALUOutput]; Contemporaneamente all operazione di moltiplicazione si preleva il terzo operando contenuto in R1. Questo porta ad avere in contemporanea con la fase di EX2 un ulteriore fase di ID che creerebbe conflitti con l istruzione schedulata tre colpi di clock dopo la MAC: a tal proposito è possibile potenziare l accesso alla memoria registri in modo da avere più letture parallele. Pagina 9

138 Esercizi di Calcolatori Elettronici A.A. È importante inoltre che l IR dell istruzione continui a propagarsi nella pipeline, e quindi tale valore dovrà essere spostato da MEM/WB.IR in quanto tale latch ora ospiterà l IR dell istruzione schedulata successivamente quella di interesse. Dunque, salviamo l IR in un nuovo latch che chiamiamo MEM/WB.IR2. EX2 MEM/WB.IR2 MEM/WB.IR; MEM/WB.ALUOutput2 MEM/WB.LMD * EX/MEM.B2; EX/MEM.B2 Regs[MEM/WB.IR[rd]]; } svolta nel secondo semiciclo Si aggiunge un MEM/WB.ALUOutput2. Erroneamente si può pensare che questo registro non serva poiché questo registro viene scritto dalle normali istruzioni solo nella fase di MEM e solo da istruzioni ALU; per creare conflitto esse devono avvenire contemporaneamente con la fase EX3 della MAC e quindi con le istruzioni schedulate 2 colpi di clock dopo la MAC. Queste però si troveranno in una situazione di stallo poiché cercheranno di usare la ALU nella loro fase EX che è già utilizzata per la moltiplicazione della MAC in EX2; quindi non si presenta la necessità di aggiungere un MEM/WB.ALUOutput2, sbagliando. Tale registro serve perché l istruzione schedulata un colpo di clock dopo la MAC scriverà in EX/MEM.ALUOutput dopo la sua fase di EX, e quindi se si usa tale registro per contenere il prodotto e poi la somma al momento della fase EX2 si processerà un dato sbagliato. In sostanza, se non avete capito niente di ciò che è scritto qua, pensate solo che c è una sovrascrittura su EX/MEM.ALUOutput se utilizziamo tale registro per fare il prodotto! EX3 MEM/WB.ALUOutput2 MEM/WB.ALUOutput2+ EX/MEM.B2; WB Regs[MEM/WB.IR2[rd]] MEM/WB.ALUOutput; L istruzione viene eseguita in 7 colpi di clock, risparmiandone 1 rispetto alla sua scissione in 2 istruzioni. Ci sarà inevitabilmente uno stallo con l istruzione schedulata due colpi di clock dopo la MAC a meno che non si inserisca nel progetto un moltiplicatore aggiuntivo, ma è uno spreco decisamente evitabile considerando la frequenza di utilizzo di un istruzione di questo tipo. Inserendo un sommatore aggiuntivo nella fase EX3 si non si hanno conflitti con l istruzione schedulata tre colpi di clock dopo. Pagina 10

139 Esercizi di Calcolatori Elettronici A.A. ESERCIZIO 5 SWP R1 R2 Scrivere un microprogramma per l'istruzione SWP R1 R2 che fa Mem[R1] = Mem[R2] per un MIPSpipeline, discutere i conflitti e possibili soluzioni architetturali. Equivale alla successione di queste operazioni assembly: LD SD R3, 0(R2) 0(R1), R3 Tale listato presenta uno stallo, evitabile se si apporta una piccola modifica: si cortocircuita l uscita della memoria MEM/WB.LMD in ingresso alla memoria stessa per avere nella fase di MEM della store un Mem[MEM/WB.ALUOutput] MEM/WB.LMD. Conteggiamo quindi 3 istruzioni, che vengono eseguite in 5+(2-1) = 6 colpi di clock. IF IF/ID.IR Mem[PC]; IF/ID.NPC PC+4; ID ID/EX.IR IF/ID.IR; ID/EX.NPC IF/ID.NPC; ID/EX.A Regs[IF/ID.IR[rs]]; ID/EX.B Regs[IF/ID.IR[rt]]; ID/EX.Imm sign-extended(if/id.ir[immediate field]); In realtà l indirizzo a cui fare riferimento in memoria è già presente nei registri R2 ed R3 caricati nei latch ID/EX.A ed ID/EX.B nella fase di ID, dunque non è necessario sommare un immediato nullo. L ALU non svolge alcuna operazione di somma e la fase EX si limita a propagare il valore di A e B rispettivamente nel latch EX/MEM.ALUOutput e EX/MEM.B. EX EX/MEM.IR ID/EX.IR; EX/MEM.ALUOutput ID/EX.A; EX/MEM.B ID/EX.B; Il registro B che contiene l indirizzo in memoria in cui salvare il dato contenuto ora in ALUOutput dev essere propagato anche in questa fase di MEM1, quindi è necessario aggiungere un altro registro B al latch MEM/WB. MEM1 MEM/WB.IR EX/MEM.IR; MEM/WB.LMD Mem[EX/MEM.ALUOutput]; MEM/WB.B EX/MEM.B; Nella seconda fase di MEM verrà eseguita la store del dato contenuto in LMD. Non è necessario propagare l IR in quanto non si richiedono altre informazioni sugli operandi dell istruzione. Supponendo che l istruzione successiva alla SWP sia una load, questa scriverà nel registro MEM/WB.LMD durante la sua fase di MEM che verrà eseguita in contemporanea con questa fase di MEM2 che anch essa usa MEM/WB.LMD: tale registro non sarà sovrascritto perché la SWP legge il suo contenuto nel primo semiciclo di clock mentre la LOAD scrive nel registro il valore che preleva in memoria nel secondo semiciclo di clock. Pagina 11

140 Esercizi di Calcolatori Elettronici A.A. MEM2 Mem[MEM/WB.B] MEM/WB.LMD; L istruzione viene eseguita in 5 colpi di clock, risparmiandone 1 rispetto alla sua scissione in 2 istruzioni. Ci sarà inevitabilmente uno stallo con l istruzione schedulata un colpo di clock dopo se questa istruzione è una load o una store che fa uso effettivo della memoria. In alternativa, si poteva utilizzare al posto del nuovo registro MEM/WB.B lo stesso registro MEM/WB.ALUOutput: quando SWP è in fase MEM2 leggerà il contenuto di questo registro all inizio del primo semiciclo e salverà in memoria LMD (a quell indirizzo) per tutto il resto del ciclo di clock; se l operazione successiva alla SWP fosse una ALU starebbe eseguendo la sua fase di MEM in cui ALUOutput viene propagato dai latch EX/MEM e MEM/WB, però MEM/WB.ALUOutput viene scritto solo nel secondo semiciclo. Quindi non c è problema di sovrascrittura. Pagina 12

141 Esercizi di Calcolatori Elettronici A.A. ESERCIZIO 6 SWX R2 R31 R1 Scrivere un microprogramma per l'istruzione SWX R2 R31 R1 che fa Mem[R1+R31] = R2 per un MIPSpipeline, discutere i conflitti e possibili soluzioni architetturali. Equivale alla successione di queste operazioni assembly: DADD R1, R1, R31 SD 0(R1), R2 Tale codice presenta non presenta stalli se si va a considerare la corto circuitazione dell ALU. Conteggiamo quindi 2 istruzioni, che vengono eseguite in 5+(2-1) = 6 colpi di clock. IF IF/ID.IR Mem[PC]; IF/ID.NPC PC+4; ID ID/EX.IR IF/ID.IR; ID/EX.NPC IF/ID.NPC; ID/EX.A Regs[IF/ID.IR[rs]]; ID/EX.B Regs[IF/ID.IR[rt]]; ID/EX.Imm sign-extended(if/id.ir[immediate field]); Si può pensare di potenziare l accesso alla memoria registri in modo tale da poter effettuare più letture in parallelo, in questo caso inserendo un ulteriore fase di ID nella fase EX questa non andrà in conflitto con la fase ID processata contemporaneamente dal processore per l istruzione schedulata un colpo di clock dopo. Si utilizza quindi il già presente registro EX/MEM.B. EX EX/MEM.IR ID/EX.IR; EX/MEM.ALUOutput ID/EX.A + ID/EX.Imm; EX/MEM.B Regs[IF/ID.IR[rd]]; MEM MEM/WB.IR EX/MEM.IR; Mem[EX/MEM.ALUOutput] EX/MEM.B; L istruzione viene eseguita in 4 colpi di clock, risparmiandone 2 rispetto alla sua scissione in 2 istruzioni. Non vi sono stalli con istruzioni successive. Pagina 13

142 Esercizi di Calcolatori Elettronici A.A. ESERCIZIO 7 LL R6 (#100,R3) Scrivere un microprogramma per l'istruzione LL R6 (#100,R3) significa R6 Mem[Mem[100+R3]] per un MIPS-pipeline, discutere i conflitti e possibili soluzioni architetturali. Equivale alla successione di queste operazioni assembly: LD LD R1, 100(R3) R6, 0(R1) Tale listato presenta uno stallo, evitabile se si apporta una piccola modifica: si cortocircuita l uscita della memoria MEM/WB.LMD in ingresso alla memoria stessa per avere nella fase di MEM della seconda load un MEM/WB.LMD Mem[MEM/WB.LMD]. Conteggiamo quindi 2 istruzioni, che vengono eseguite in 5+(2-1) = 6 colpi di clock. IF IF/ID.IR Mem[PC]; IF/ID.NPC PC+4; ID ID/EX.IR IF/ID.IR; ID/EX.NPC IF/ID.NPC; ID/EX.A Regs[IF/ID.IR[rs]]; ID/EX.B Regs[IF/ID.IR[rt]]; ID/EX.Imm sign-extended(if/id.ir[immediate field]); EX EX/MEM.IR ID/EX.IR; EX/MEM.ALUOutput ID/EX.A + ID/EX.Imm; MEM1 MEM/WB.IR EX/MEM.IR; MEM/WB.LMD Mem[EX/MEM.ALUOutput]; MEM2 MEM/WB.LMD Mem[MEM/WB.LMD]; WB Regs[MEM/WB.IR2[rt]] MEM/WB.LMD; L istruzione viene eseguita in 6 colpi di clock, senza alcun risparmio rispetto alla sua scissione in 2 istruzioni. Ci sarà uno stallo con l istruzione successiva qualsiasi essa sia (tranne i salti) perché verranno contemporaneamente eseguite le fasi MEM e WB delle due istruzioni, e questo ci permette di non utilizzare registri aggiuntivi quali IR2 o LMD2. Mi sa tanto che conviene usare due operazioni al posto di una!! Pagina 14

143 Esercizi di Calcolatori Elettronici A.A. ESERCIZIO 8 SL (#100,R3) R6 Scrivere un microprogramma per l'istruzione SL (#100,R3) R6 significa Mem[Mem[100+R3]] R6 per un MIPS-pipeline, discutere i conflitti e possibili soluzioni architetturali. Equivale alla successione di queste operazioni assembly: LD SD R1, 100(R3) 0(R1), R6 Tale listato presenta uno stallo, evitabile se si apporta una piccola modifica: si cortocircuita l uscita della memoria MEM/WB.LMD in ingresso alla memoria stessa per avere nella fase di MEM della store un Mem[MEM/WB.LMD] MEM/WB.B. Conteggiamo quindi 2 istruzioni, che vengono eseguite in 5+(2-1) = 6 colpi di clock. IF IF/ID.IR Mem[PC]; IF/ID.NPC PC+4; ID ID/EX.IR IF/ID.IR; ID/EX.NPC IF/ID.NPC; ID/EX.A Regs[IF/ID.IR[rs]]; ID/EX.B Regs[IF/ID.IR[rt]]; ID/EX.Imm sign-extended(if/id.ir[immediate field]); EX EX/MEM.IR ID/EX.IR; EX/MEM.ALUOutput ID/EX.A + ID/EX.Imm; EX/MEM.B ID/EX.B MEM1 MEM/WB.IR EX/MEM.IR; MEM/WB.LMD Mem[EX/MEM.ALUOutput]; MEM/WB. ALUOutput EX/MEM.B; MEM2 Mem[MEM/WB.LMD] MEM/WB.ALUOutput; L istruzione viene eseguita in 5 colpi di clock, risparmiandone 1 rispetto alla sua scissione in 2 istruzioni. Ci sarà uno stallo se l istruzione che la segue è una load/store che fa uso effettivo della memoria; dunque l utilizzo del registro MEM/WB.LMD nella fase MEM2 non crea problemi poiché l unica istruzione che ne fa uso è la load, che in questo caso verrà stallata. Pagina 15

144 Esercizi di Calcolatori Elettronici A.A. ESERCIZIO 9 SWPM R1 R2 Scrivere un microprogramma per l'istruzione SWPM R1 R2 significa Mem[R1] Mem[R2] per un MIPSpipeline, discutere i conflitti e possibili soluzioni architetturali. Equivale alla successione di queste operazioni assembly: LD LD SD SD R3, 0(R1) R4, 0(R2) 0(R2), R3 0(R1), R4 Non ci sono stalli. Conteggiamo quindi 4 istruzioni, che vengono eseguite in 5+(4-1) = 8 colpi di clock. IF IF/ID.IR Mem[PC]; IF/ID.NPC PC+4; ID ID/EX.IR IF/ID.IR; ID/EX.NPC IF/ID.NPC; ID/EX.A Regs[IF/ID.IR[rs]]; ID/EX.B Regs[IF/ID.IR[rt]]; ID/EX.Imm sign-extended(if/id.ir[immediate field]); Propaghiamo il valore di A e B aggiungendo il registro A al latch EX/MEM. Non utilizziamo EX/MEM.ALUOutput perché poi il valore di A servirà nelle fasi successive. EX EX/MEM.IR ID/EX.IR; EX/MEM.A ID/EX.A; EX/MEM.B ID/EX.B; Usiamo un altro registro chiamato MEM/WB.ALUOutput2 per non avere problemi di sovrascrittura con istruzioni ALU successive che faranno uso di questo registro. MEM/WB.LMD invece è liberamente utilizzabile, perché l unica operazione che lo usa è la LOAD e questa si stallerà se segue la nostra istruzione in quanto verranno eseguite contemporaneamente due fasi MEM. MEM1 MEM/WB.IR EX/MEM.IR; MEM/WB.LMD Mem[EX/MEM.A]; MEM/WB. ALUOutput2 EX/MEM.B; MEM/WB.A EX/MEM.A; Si sarebbe anche potuto cortocircuitare lo stesso EX/MEM.A, ma tralasciamo ed aggiungiamo il registro anche a MEM/WB. Non è più necessario propagare l IR perché non dovremo più fare accessi alla memoria registri, visto che abbiamo propagato i valori di rs ed rt rispettivamente in MEM/WB.A e MEM/WB.ALUOutput2. Aggiungiamo il registro LMD2 al latch MEM/WB per salvare il contenuto della cella di memoria indirizzata al valore di rs. Pagina 16

145 Esercizi di Calcolatori Elettronici A.A. MEM2 MEM/WB.LMD Mem[MEM/WB.ALUOutput]; MEM/WB. LMD2 EX/MEM.LMD; Non vi è sovrascrittura perché la fase di mem dura tutto il colpo di clock, all inizio viene letto il valore di LMD e al secondo semiciclo del clock viene scritto tale valore in LMD2; nel frattempo, LMD potrà tranquillamente essere sovrascritto da ciò che troviamo in memoria all indirizzo rt. Ricapitolando, ora abbiamo in MEM/WB.LMD ciò che si trova in memoria all indirizzo rt ed in MEM/WB.LMD2 ciò che si trova in memoria all indirizzo rs. Il valore di rs è salvato in MEM/WB.A ed il valore di rt è salvato in MEM/WB.ALUOutput. MEM3 Mem[MEM/WB.A] MEM/WB.LMD; MEM4 Mem[EX/MEM.ALUOutput] MEM/WB. LMD2; L istruzione viene eseguita in 7 colpi di clock, risparmiandone 1 rispetto alla sua scissione in 4 istruzioni. Ci saranno stalli con le prossime tre istruzioni solo se queste sono istruzioni LOAD/STORE, ovvero che fanno uso effettivo della memoria. Pagina 17

146 Esercizi di Calcolatori Elettronici A.A. ESERCIZI ASSEMBLY ESERCIZI ASSEMBLY Pagina 18

147 Esercizi di Calcolatori Elettronici A.A. ESERCIZIO 1 SOMMA DI DUE VETTORI Somma di due vettori in un terzo vettore con processore scalare pipeline MIPS. Si vuole scrivere un programma assembly per un processore MIPS scalare pipeline che sommi due vettori di dati double contenuti in memoria e salvi il risultato in un terzo vettore. Siano A, B e C vettori di N elementi, l operazione da svolgere è: for(i=0; i<n; i++) { C[i] = A[i] + B[i]; } Il primo risparmio lo si può pensare sui registri: l utilizzo di un unico registro come indice che scorre all interno del vettore man mano che vengono svolte le somme riduce il numero di registri in gioco. Si ipotizza dunque di conoscere le locazioni in memoria dei tre vettori, cioè le locazioni in memoria dei primi elementi dei tre vettori: supponiamo A*0+ all indirizzo 1000, B*0+ all indirizzo 2000 e C*0+ all indirizzo Utilizziamo il registro R1 come indice, il quale dovrà essere incrementato di 8 (operiamo su vettori double) ad ogni iterazione. In realtà, se si pensa di inizializzare R1 al valore dell ultimo elemento del vettore, è possibile usare una BGEZ su R1 come condizione per il loop, così che se è verificata (se R1 è maggiore o uguale a 0) si salta all inizio del loop. In questo modo R1 dovrà essere decrementato di 8 ad ogni iterazione. R1 dovrà dunque essere inizializzato al valore (N-1)*8, essendo questo il valore occupato in memoria da ciascuno dei tre vettori. Dunque le prime tre istruzioni serviranno ad inizializzare il valore di R1 e saranno operazioni esterne al loop. Pagina 19

148 Esercizi di Calcolatori Elettronici A.A. DADDI R1, R0, N DADDI R1, R1, #-1 DMULI R1, R1, #8 Successivamente, scriviamo il loop. All inizio del loop mettiamo l etichetta loop per identificare la prima operazioni ove si dovrà saltare se verificata la condizione di salto. Le prime due operazioni saranno due load per caricare gli elementi dei vettori dalla memoria nei registri: supponiamo R2 sia destinato a contenere A ed R3 sia destinato a contenere B. loop: LD R2, R1(1000) LD R3, R1(2000) Procediamo con la somma dei due elementi. Potremmo utilizzare il registro R4 per contenere C, ma risulterebbe un inutile spreco di registri in quanto sia R2 che R3 non saranno più utilizzati nel corso dell iterazione. Scegliamo dunque di salvare C in R2. DADDI R2, R2, R3 Salviamo C in memoria. SD R1(3000), R2 Procediamo con il decremento dell indice di 8 e con la condizione di salto. DADDI R1, R1, #-8 BGEZ R1, loop Il programma in assembly risulta essere: loop: DADDI R1, R0, N DADDI R1, R1, #-1 DMULI R1, R1, #8 LD R2, R1(1000) LD R3, R1(2000) DADDI R2, R2, R3 SD R1(3000), R2 DADDI R1, R1, #-8 BGEZ R1, loop Tale listato è decisamente inaccettabile, in quanto ci saranno numerosi stalli. Supponendo che il nostro processore abbia già le modifiche necessarie alla cortocircuitazione dell ALU, e un sommatore aggiuntivo per effettuare il calcolo del PC dove saltare dopo un istruzione di brench/jump perdendo solo un colpo di clock, la situazione è la seguente: Pagina 20

149 Esercizi di Calcolatori Elettronici A.A. Calcoliamo in quanti colpi di clock viene eseguito questo programma in pipeline. Le istruzioni all interno del loop sono 6 più 3 stalli, cioè 9 istruzioni. L esecuzione impiegherà: Numero di colpi di clock per eseguire 1 istruzione + (numero di istruzioni -1) = 5 + (9-1) = 13 colpi di clock. Questi 13 colpi di clock valgono per un'unica istruzione. Considerando il loop, le 9 istruzioni dovranno essere moltiplicate per il numero di iterazioni, cioè N. Quindi ((9*N)-1)+5. A questi, andranno sommati i colpi di clock necessari per eseguire le tre istruzioni precedenti il loop: Numero di colpi di clock per eseguire 1 istruzione + (Numero di istruzioni precedenti il loop 1) + 1 istruzione (la prima del loop) - Numero di colpi di clock per eseguire 1 istruzione = = 5 + (3-1) = 3 Supponendo vettori di 10 elementi, il programma impiega (9*10)-1) = 97 colpi di clock per essere eseguito. Per ottimizzare il programma è quindi necessario spostare alcune istruzioni utilizzando la tecnica del delay slot. Spostiamo il decremento dell indice dopo la seconda load, in questo modo anche lo stallo che segue quest istruzione viene eliminato. Spostiamo inoltre la store dopo la bnez, con l accortezza di cambiare l indirizzo da sommare all indice R1, in quanto R1 è già stato decrementato di 8: dunque, per ottenere lo stesso indirizzo di memoria, si incrementa di 8 l'indirizzo nella store Pagina 21

150 Esercizi di Calcolatori Elettronici A.A. loop: DADDI R1, R0, N DADDI R1, R1, #-1 DMULI R1, R1, #8 LD R2, R1(1000) LD R3, R1(2000) DADDI R1, R1, #-8 DADDI R2, R2, R3 BGEZ R1, loop SD R1(3008), R2 Il loop viene eseguito in 5 + (6-1) = 10 colpi di clock, quindi supponendo vettori di 10 elementi, il programma viene eseguito in ((6*10)-1) = 67 colpi di clock, 30 in meno rispetto a quelli utilizzati per processare il listato con gli stalli. Pagina 22

Richiami sull architettura del processore MIPS a 32 bit

Richiami sull architettura del processore MIPS a 32 bit Caratteristiche principali dell architettura del processore MIPS Richiami sull architettura del processore MIPS a 32 bit Architetture Avanzate dei Calcolatori Valeria Cardellini E un architettura RISC

Dettagli

Richiami sull architettura del processore MIPS a 32 bit

Richiami sull architettura del processore MIPS a 32 bit Richiami sull architettura del processore MIPS a 32 bit Architetture Avanzate dei Calcolatori Valeria Cardellini Caratteristiche principali dell architettura del processore MIPS E un architettura RISC

Dettagli

Architettura degli Elaboratori Lez. 8 CPU MIPS a 1 colpo di clock. Prof. Andrea Sterbini

Architettura degli Elaboratori Lez. 8 CPU MIPS a 1 colpo di clock. Prof. Andrea Sterbini Architettura degli Elaboratori Lez. 8 CPU MIPS a 1 colpo di clock Prof. Andrea Sterbini sterbini@di.uniroma1.it Argomenti Progetto della CPU MIPS a 1 colpo di clock - Istruzioni da implementare - Unità

Dettagli

Il set istruzioni di MIPS Modalità di indirizzamento. Proff. A. Borghese, F. Pedersini

Il set istruzioni di MIPS Modalità di indirizzamento. Proff. A. Borghese, F. Pedersini Architettura degli Elaboratori e delle Reti Il set istruzioni di MIPS Modalità di indirizzamento Proff. A. Borghese, F. Pedersini Dipartimento di Scienze dell Informazione Università degli Studi di Milano

Dettagli

Fasi (MIPS) Dove NPC è un registro temporaneo PC (program counter) è il registro IP (instruction pointer)

Fasi (MIPS) Dove NPC è un registro temporaneo PC (program counter) è il registro IP (instruction pointer) Fasi (MIPS) Fasi senza pipeline: IF (istruction fetch): IR Mem[PC] ; NPC PC + 4 ; Dove NPC è un registro temporaneo PC (program counter) è il registro IP (instruction pointer) Lezione Architettura degli

Dettagli

Progettazione dell unità di elaborazioni dati e prestazioni. Il processore: unità di elaborazione. I passi per progettare un processore

Progettazione dell unità di elaborazioni dati e prestazioni. Il processore: unità di elaborazione. I passi per progettare un processore Il processore: unità di elaborazione Architetture dei Calcolatori (lettere A-I) Progettazione dell unità di elaborazioni dati e prestazioni Le prestazioni di un calcolatore sono determinate da: Numero

Dettagli

Il processore: unità di elaborazione

Il processore: unità di elaborazione Il processore: unità di elaborazione Architetture dei Calcolatori (lettere A-I) Progettazione dell unità di elaborazioni dati e prestazioni Le prestazioni di un calcolatore sono determinate da: Numero

Dettagli

L'architettura del processore MIPS

L'architettura del processore MIPS L'architettura del processore MIPS Piano della lezione Ripasso di formati istruzione e registri MIPS Passi di esecuzione delle istruzioni: Formato R (istruzioni aritmetico-logiche) Istruzioni di caricamento

Dettagli

Processore. Memoria I/O. Control (Parte di controllo) Datapath (Parte operativa)

Processore. Memoria I/O. Control (Parte di controllo) Datapath (Parte operativa) Processore Memoria Control (Parte di controllo) Datapath (Parte operativa) I/O Memoria La dimensione del Register File è piccola registri usati per memorizzare singole variabili di tipo semplice purtroppo

Dettagli

Processore. Memoria I/O. Control (Parte di controllo) Datapath (Parte operativa)

Processore. Memoria I/O. Control (Parte di controllo) Datapath (Parte operativa) Processore Memoria Control (Parte di controllo) Datapath (Parte operativa) I/O Parte di Controllo La Parte Controllo (Control) della CPU è un circuito sequenziale istruzioni eseguite in più cicli di clock

Dettagli

Le etichette nei programmi. Istruzioni di branch: beq. Istruzioni di branch: bne. Istruzioni di jump: j

Le etichette nei programmi. Istruzioni di branch: beq. Istruzioni di branch: bne. Istruzioni di jump: j L insieme delle istruzioni (2) Architetture dei Calcolatori (lettere A-I) Istruzioni per operazioni logiche: shift Shift (traslazione) dei bit di una parola a destra o sinistra sll (shift left logical):

Dettagli

Università degli Studi di Cassino

Università degli Studi di Cassino Corso di Istruzioni di confronto Istruzioni di controllo Formato delle istruzioni in L.M. Anno Accademico 2007/2008 Francesco Tortorella Istruzioni di confronto Istruzione Significato slt $t1,$t2,$t3 if

Dettagli

Istruzioni di trasferimento dati

Istruzioni di trasferimento dati Istruzioni di trasferimento dati Leggere dalla memoria su registro: lw (load word) Scrivere da registro alla memoria: sw (store word) Esempio: Codice C: A[8] += h A è un array di numeri interi Codice Assembler:

Dettagli

Architettura degli Elaboratori

Architettura degli Elaboratori Architettura degli Elaboratori Linguaggio macchina e assembler (caso di studio: processore MIPS) slide a cura di Salvatore Orlando, Marta Simeoni, Andrea Torsello Architettura degli Elaboratori 1 1 Istruzioni

Dettagli

Corso di Calcolatori Elettronici MIPS: Istruzioni di confronto Istruzioni di controllo Formato delle istruzioni in L.M.

Corso di Calcolatori Elettronici MIPS: Istruzioni di confronto Istruzioni di controllo Formato delle istruzioni in L.M. di Cassino e del Lazio Meridionale Corso di MIPS: Istruzioni di confronto Istruzioni di controllo Formato delle istruzioni in L.M. Anno Accademico 201/201 Francesco Tortorella Istruzioni di confronto Istruzione

Dettagli

Un altro tipo di indirizzamento. L insieme delle istruzioni (3) Istruz. di somma e scelta con operando (2) Istruzioni di somma e scelta con operando

Un altro tipo di indirizzamento. L insieme delle istruzioni (3) Istruz. di somma e scelta con operando (2) Istruzioni di somma e scelta con operando Un altro tipo di indirizzamento L insieme delle istruzioni (3) Architetture dei Calcolatori (lettere A-I) Tipi di indirizzamento visti finora Indirizzamento di un registro Indirizzamento con registro base

Dettagli

Sistemi e reti CPU Concetti di base

Sistemi e reti CPU Concetti di base Sistemi e reti CPU Concetti di base A cura dell Ing. Claudio Traini Cenni Storici 1971 il primo processore mai realizzato : Intel 4004 Progettato dal vicentino Federico Faggin 1 Cenni Storici 1976 Faggin

Dettagli

Riassunto. Riassunto. Ciclo fetch&execute. Concetto di programma memorizzato. Istruzioni aritmetiche add, sub, mult, div

Riassunto. Riassunto. Ciclo fetch&execute. Concetto di programma memorizzato. Istruzioni aritmetiche add, sub, mult, div MIPS load/store word, con indirizzamento al byte aritmetica solo su registri Istruzioni Significato add $t1, $t2, $t3 $t1 = $t2 + $t3 sub $t1, $t2, $t3 $t1 = $t2 - $t3 mult $t1, $t2 Hi,Lo = $t1*$t2 div

Dettagli

Architettura dei calcolatori e sistemi operativi. Il processore Capitolo 4 P&H

Architettura dei calcolatori e sistemi operativi. Il processore Capitolo 4 P&H Architettura dei calcolatori e sistemi operativi Il processore Capitolo 4 P&H 4. 11. 2015 Sommario Instruction Set di riferimento per il processore Esecuzione delle istruzioni Struttura del processore

Dettagli

Architettura hardware

Architettura hardware Architettura hardware la parte che si può prendere a calci Architettura dell elaboratore Sistema composto da un numero elevato di componenti, in cui ogni componente svolge una sua funzione elaborazione

Dettagli

Lezione 15. L elaboratore Elettronico

Lezione 15. L elaboratore Elettronico Lezione 15 Architettura di un calcolatore L elaboratore Elettronico Un elaboratore elettronico è una macchina elettronica in grado di elaborare dati secondo le specifiche fornite da un algoritmo Internamente

Dettagli

Capitolo 5 Struttura di base del processore

Capitolo 5 Struttura di base del processore Capitolo 5 Struttura di base del processore 5.1. Il periodo di clock deve ospitare tutti i ritardi di propagazione più il tempo di impostazione per i registri. a. Minimo periodo di clock = 70 + 600 + 50

Dettagli

Istruzioni assembler Istruzione N Registri

Istruzioni assembler Istruzione N Registri Istruzioni assembler Istruzione N Registri Aritmetica add a, b, c a = b+c addi a, b, num a = b + sub a, b, c a = b - c mul a, b, c a = b*c div a, b, c a = b/c utilizzati Descrizione 3 Somma. Somma b e

Dettagli

Architettura degli Elaboratori

Architettura degli Elaboratori circuiti combinatori: ALU slide a cura di Salvatore Orlando, Marta Simeoni, Andrea Torsello 1 ALU ALU (Arithmetic Logic Unit) circuito combinatorio all interno del processore per l esecuzione di istruzioni

Dettagli

Linguaggio macchina. 3 tipi di istruzioni macchina. Istruzioni per trasferimento dati. Istruzioni logico/aritmetiche

Linguaggio macchina. 3 tipi di istruzioni macchina. Istruzioni per trasferimento dati. Istruzioni logico/aritmetiche 3 tipi di istruzioni macchina Linguaggio macchina e assembler 1) trasferimento tra RAM e registri di calcolo della CPU 2) operazioni aritmetiche: somma, differenza, moltiplicazione e divisione 3) operazioni

Dettagli

Il linguaggio macchina

Il linguaggio macchina Architettura degli Elaboratori e delle Reti Lezione 16 Il linguaggio macchina Proff. A. Borghese, F. Pedeini Dipaimento di Scienze dell Informazione Univeità degli Studi di Milano L 16 1/33 Linguaggio

Dettagli

Linguaggio macchina. Architettura degli Elaboratori e delle Reti. Il linguaggio macchina. Lezione 16. Proff. A. Borghese, F.

Linguaggio macchina. Architettura degli Elaboratori e delle Reti. Il linguaggio macchina. Lezione 16. Proff. A. Borghese, F. Architettura degli Elaboratori e delle Reti Lezione 16 Il linguaggio macchina Proff. A. Borghese, F. Pedeini Dipaimento di Scienze dell Informazione Univeità degli Studi di Milano L 16 1/32 Linguaggio

Dettagli

Componenti principali

Componenti principali Componenti e connessioni Capitolo 3 Componenti principali n CPU (Unità Centrale di Elaborazione) n Memoria n Sistemi di I/O n Connessioni tra loro Architettura di Von Neumann n Dati e instruzioni in memoria

Dettagli

Il processore. Istituzionii di Informatica -- Rossano Gaeta

Il processore. Istituzionii di Informatica -- Rossano Gaeta Il processore Il processore (detto anche CPU, ovvero, Central Processing Unit) è la componente dell unità centrale che fornisce la capacità di elaborazione delle informazioni contenute nella memoria principale

Dettagli

static dynamic random access memory

static dynamic random access memory LA MEMORIA SRAM e D R A M static dynamic random access memory SRAM: unità che memorizza un gran numero di parole in un insieme di flip-flop, opportunamente connessi, mediante un sistema di indirizzamento

Dettagli

Esercitazione su Instruction Level Parallelism

Esercitazione su Instruction Level Parallelism Esercitazione su Instruction Level Parallelism Salvatore Orlando Arch. Elab. - S. Orlando 1 Pipeline con e senza forwarding Si considerino due processori MIPS (processore A e B) entrambi con pipeline a

Dettagli

CPU a ciclo multiplo

CPU a ciclo multiplo Architettura degli Elaboratori e delle Reti Lezione CPU a ciclo multiplo Proff. A. Borghese, F. Pedersini Dipartimento di Scienze dell Informazione Università degli Studi di Milano L 1/8 Sommario! I problemi

Dettagli

Architettura dei computer

Architettura dei computer Architettura dei computer In un computer possiamo distinguere quattro unità funzionali: il processore la memoria principale (memoria centrale, RAM) la memoria secondaria i dispositivi di input/output La

Dettagli

Architettura di un calcolatore e linguaggio macchina. Primo modulo Tecniche della programmazione

Architettura di un calcolatore e linguaggio macchina. Primo modulo Tecniche della programmazione Architettura di un calcolatore e linguaggio macchina Primo modulo Tecniche della programmazione CPU Central Processing Unit, processore Unita logica/aritmetica: elaborazione dati Unita di controllo: coordina

Dettagli

Elementi di informatica

Elementi di informatica Elementi di informatica Architetture degli elaboratori Il calcolatore Un calcolatore è sistema composto da un elevato numero di componenti Il suo funzionamento può essere descritto se lo si considera come

Dettagli

ARCHITETTURA DI UN ELABORATORE! Ispirata al modello della Macchina di Von Neumann (Princeton, Institute for Advanced Study, anni 40).!

ARCHITETTURA DI UN ELABORATORE! Ispirata al modello della Macchina di Von Neumann (Princeton, Institute for Advanced Study, anni 40).! ARCHITETTURA DI UN ELABORATORE! Ispirata al modello della Macchina di Von Neumann (Princeton, Institute for Advanced Study, anni 40).! MACCHINA DI VON NEUMANN! UNITÀ FUNZIONALI fondamentali! Processore

Dettagli

ARCHITETTURA DI UN SISTEMA DI ELABORAZIONE

ARCHITETTURA DI UN SISTEMA DI ELABORAZIONE ARCHITETTURA DI UN SISTEMA DI ELABORAZIONE Il computer o elaboratore è una macchina altamente organizzata capace di immagazzinare, elaborare e trasmettere dati con notevole precisione e rapidità. Schematicamente

Dettagli

Struttura di un elaboratore

Struttura di un elaboratore Struttura di un elaboratore Fondamenti di Informatica 1 Modello architetturale di un computer Ogni computer è costituito da un insieme di blocchi funzionali tra loro interconnessi da sistemi di comunicazioni,

Dettagli

Linguaggio macchina: utilizzo di costanti, metodi di indirizzamento

Linguaggio macchina: utilizzo di costanti, metodi di indirizzamento Architetture degli Elaboratori e delle Reti Lezione 17 Linguaggio macchina: utilizzo di costanti, metodi di indirizzamento Proff. A. Borghese, F. Pedeini Dipaimento di Scienze dell Informazione Univeità

Dettagli

CPU pipeline hazards

CPU pipeline hazards Architettura degli Elaboratori e delle Reti Lezione 23 CPU pipeline hazards Proff. A. Borghese, F. Pedersini Dipartimento di Scienze dell Informazione Università degli Studi di Milano L 23 /24 Sommario!

Dettagli

Componenti principali. Programma cablato. Architettura di Von Neumann. Programma cablato. Cos e un programma? Componenti e connessioni

Componenti principali. Programma cablato. Architettura di Von Neumann. Programma cablato. Cos e un programma? Componenti e connessioni Componenti principali Componenti e connessioni Capitolo 3 CPU (Unita Centrale di Elaborazione) Memoria Sistemi di I/O Connessioni tra loro 1 2 Architettura di Von Neumann Dati e instruzioni in memoria

Dettagli

Linguaggio Assembly e linguaggio macchina

Linguaggio Assembly e linguaggio macchina Architettura degli Elaboratori e delle Reti Lezione 11 Linguaggio Assembly e linguaggio macchina Proff. A. Borghese, F. Pedersini Dipartimento di Scienze dell Informazione Università degli Studi di Milano

Dettagli

La CPU e la Memoria. Sistemi e Tecnologie Informatiche 1. Struttura del computer. Sistemi e Tecnologie Informatiche 2

La CPU e la Memoria. Sistemi e Tecnologie Informatiche 1. Struttura del computer. Sistemi e Tecnologie Informatiche 2 La CPU e la Memoria Sistemi e Tecnologie Informatiche 1 Struttura del computer Sistemi e Tecnologie Informatiche 2 1 I registri La memoria contiene sia i dati che le istruzioni Il contenuto dei registri

Dettagli

Il processore: unità di controllo

Il processore: unità di controllo Il processore: unità di lo Architetture dei Calcolatori (lettere A-I) L unità di lo L unità di lo è responsabile della generazione dei segnali di lo che vengono inviati all unità di elaborazione Alcune

Dettagli

Arithmetic and Logic Unit e moltiplicatore

Arithmetic and Logic Unit e moltiplicatore Arithmetic and Logic Unit e moltiplicatore M. Favalli Engineering Department in Ferrara (ENDIF) ALU - multiplier Analisiesintesideicircuitidigitali 1 / 34 Sommario 1 Arithmetic and Logic Unit - ALU 2 Moltiplicatore

Dettagli

Linguaggio Assembly e linguaggio macchina

Linguaggio Assembly e linguaggio macchina Architettura degli Elaboratori e delle Reti Lezione 11 Linguaggio Assembly e linguaggio macchina Proff. A. Borghese, F. Pedersini Dipartimento di Scienze dell Informazione Università degli Studi di Milano

Dettagli

Somma di numeri floating point. Algoritmi di moltiplicazione e divisione per numeri interi

Somma di numeri floating point. Algoritmi di moltiplicazione e divisione per numeri interi Somma di numeri floating point Algoritmi di moltiplicazione e divisione per numeri interi Standard IEEE754 " Standard IEEE754: Singola precisione (32 bit) si riescono a rappresentare numeri 2.0 10 2-38

Dettagli

Il linguaggio macchina

Il linguaggio macchina Il linguaggio macchina Istruzioni macchina (PH 2.4) Indirizzamento (PH 2.9) Costanti a 32-bit (PH 2.9) 1 Linguaggio macchina Le istruzioni in linguaggio assembly devono essere tradotte in linguaggio macchina

Dettagli

Aritmetica dei Calcolatori

Aritmetica dei Calcolatori Aritmetica dei Calcolatori Nicu Sebe March 14, 2016 Informatica Nicu Sebe 1 / 34 Operazioni su Bit Bit Scienza della rappresentazione e dell elaborazione dell informazione Abbiamo visto come i computer

Dettagli

Architettura di un processore basato su registri generali.

Architettura di un processore basato su registri generali. Architettura di un processore basato su registri generali. M. Esposito (mesposit@unina.it) 26 febbraio 2007 In Fig. 1 è riportato uno schema di principio che raffigura l architettura di un processore basato

Dettagli

Linguaggio assembler e linguaggio macchina (caso di studio: processore MIPS)

Linguaggio assembler e linguaggio macchina (caso di studio: processore MIPS) Linguaggio assembler e linguaggio macchina (caso di studio: processore MIPS) Salvatore Orlando Arch. Elab. - S. Orlando 1 Livelli di astrazione Scendendo di livello, diventiamo più concreti e scopriamo

Dettagli

Componenti e connessioni. Capitolo 3

Componenti e connessioni. Capitolo 3 Componenti e connessioni Capitolo 3 Componenti principali CPU (Unità Centrale di Elaborazione) Memoria Sistemi di I/O Connessioni tra loro Architettura di Von Neumann Dati e instruzioni in memoria (lettura

Dettagli

Comparazione fra vari processori

Comparazione fra vari processori RISC Reduced Instruction Set Computer Caratteristiche chiave Numero elevato di registri ad uso generale oppure utilizzo di compilatori per ottimizzare l uso dei registri Set istruzioni semplice e limitato

Dettagli

Linguaggio Assembly e linguaggio macchina

Linguaggio Assembly e linguaggio macchina Architettura degli Elaboratori e delle Reti Lezione 11 Linguaggio Assembly e linguaggio macchina Proff. A. Borghese, F. Pedersini Dipartimento di Scienze dell Informazione Università degli Studi di Milano

Dettagli

Architettura hardware

Architettura hardware Architettura dell elaboratore Architettura hardware la parte che si può prendere a calci Sistema composto da un numero elevato di componenti, in cui ogni componente svolge una sua funzione elaborazione

Dettagli

Istruzioni macchina. Dove sono gli operandi? Ciclo della CPU. Elementi di un istruzione macchina. Rappresentazione delle istruzioni

Istruzioni macchina. Dove sono gli operandi? Ciclo della CPU. Elementi di un istruzione macchina. Rappresentazione delle istruzioni Istruzioni macchina Linguaggio macchina Insieme delle istruzioni (instruction set) che la CPU puo eseguire Capitolo 10 1 2 Elementi di un istruzione macchina Codice operativo Specifica l operazione da

Dettagli

L unità di controllo di CPU a singolo ciclo

L unità di controllo di CPU a singolo ciclo L unità di controllo di CPU a singolo ciclo Prof. Alberto Borghese Dipartimento di Informatica alberto.borghese@unimi.it Università degli Studi di Milano Riferimento sul Patterson: capitolo 4.2, 4.4, D1,

Dettagli

Componenti di un processore

Componenti di un processore Componenti di un processore Unità di Controllo Bus Interno REGISTRI Program Counter (PC) Registro di Stato (SR) Registro Istruzioni (IR) Registri Generali Unità Aritmetico- Logica Registro Indirizzi Memoria

Dettagli

CPU a ciclo multiplo

CPU a ciclo multiplo Architettura degli Elaboratori e delle Reti Lezione CPU a ciclo multiplo Proff. A. Borghese, F. Pedersini Dipartimento di Scienze dell Informazione Università degli Studi di Milano L /9 Sommario! I problemi

Dettagli

Esercitazione su Instruction Level Parallelism Salvatore Orlando

Esercitazione su Instruction Level Parallelism Salvatore Orlando Esercitazione su Instruction Level Parallelism Salvatore Orlando Arch. Elab. - S. Orlando 1 Pipeline con e senza forwarding Si considerino due processori MIPS (processore A e B) entrambi con pipeline a

Dettagli

1. Si effettui la divisione di 7/5 utilizzando un efficiente algoritmo e illustrando la corrispondente architettura hardware.

1. Si effettui la divisione di 7/5 utilizzando un efficiente algoritmo e illustrando la corrispondente architettura hardware. 1. Si effettui la divisione di 7/5 utilizzando un efficiente algoritmo e illustrando la corrispondente architettura hardware. 2. Spiegare i diversi tipi di indirizzamento usati dalle istruzioni del set

Dettagli

Problemi del ciclo singolo

Problemi del ciclo singolo Problemi del ciclo singolo Ciclo di clock lungo Istruzioni potenzialmente veloci sono rallentate Impiegano sempre lo stesso tempo dell istruzione più lenta Unità funzionale e collegamenti della parte operativa

Dettagli

Il linguaggio assembly

Il linguaggio assembly Il linguaggio assembly PH 2.3 (continua) 1 Argomenti Organizzazione della memoria Istruzioni di trasferimento dei dati Array Istruzioni logiche 2 1 La memoria del MIPS I contenuti delle locazioni di memoria

Dettagli

DEC PDP8, III Generazione, '65-'75

DEC PDP8, III Generazione, '65-'75 Parte I DEC PDP8, III Generazione, '65-'75 PDP8 Architettura (Livello Registri) 12 bit Program Counter PC 12 bit Memory Address Register MAR Random Access Memory RAM 4096 x 16 1 bit I 3 bit Operation Code

Dettagli

Microelettronica Corso introduttivo di progettazione di sistemi embedded

Microelettronica Corso introduttivo di progettazione di sistemi embedded Microelettronica Corso introduttivo di progettazione di sistemi embedded Architettura dei sistemi a microprocessore prof. Stefano Salvatori A.A. 2014/2015 Eccetto dove diversamente specificato, i contenuti

Dettagli

Laboratorio di Architettura degli Elaboratori LabArch 2007 Terzo Quadimestre, a.a Docente: H. Muccini

Laboratorio di Architettura degli Elaboratori LabArch 2007 Terzo Quadimestre, a.a Docente: H. Muccini [http://www.di.univaq.it/muccini/labarch] Laboratorio di Architettura degli Elaboratori LabArch 2007 Terzo Quadimestre, a.a. 2006-2007 Docente: H. Muccini Lecture 12: - Numeri con segno -Somma e sottrazione

Dettagli

Esercizi svolti e da svolgere sugli argomenti trattati nella lezione 25

Esercizi svolti e da svolgere sugli argomenti trattati nella lezione 25 Esercizi svolti e da svolgere sugli argomenti trattati nella lezione 25 Esercizi svolti Es.. Si progetti in dettaglio il circuito che, dati quattro registri sorgente Si e quattro registri destinazione

Dettagli

CPU pipeline 4: le CPU moderne

CPU pipeline 4: le CPU moderne Architettura degli Elaboratori e delle Reti Lezione 25 CPU pipeline 4: le CPU moderne Proff. A. Borghese, F. Pedersini Dipartimento di Scienze dell Informazione Università degli Studi di Milano L 25 1/16

Dettagli

ISA (Instruction Set Architecture) della CPU MIPS

ISA (Instruction Set Architecture) della CPU MIPS Architettura degli Elaboratori Lezione 20 ISA (Instruction Set Architecture) della CPU MIPS Prof. Federico Pedersini Dipartimento di Informatica Uniersità degli Studi di Milano L16-20 1 Linguaggio macchina

Dettagli

Sistemi di Elaborazione delle Informazioni

Sistemi di Elaborazione delle Informazioni SCUOLA DI MEDICINA E CHIRURGIA Università degli Studi di Napoli Federico II Corso di Sistemi di Elaborazione delle Informazioni Dott. Francesco Rossi a.a. 2016/2017 1 Programma del corso Informatica di

Dettagli

Il Processore: l unità di controllo

Il Processore: l unità di controllo Il Processore: l unità di controllo La frequenza con cui vengono eseguiti i cicli di esecuzione è scandita da una componente detta clock Ad ogni impulso di clock la UC esegue un ciclo di esecuzione di

Dettagli

Elementi base per la realizzazione dell unità di calcolo

Elementi base per la realizzazione dell unità di calcolo Elementi base per la realizzazione dell unità di calcolo Memoria istruzioni elemento di stato dove le istruzioni vengono memorizzate e recuperate tramite un indirizzo. ind. istruzione Memoria istruzioni

Dettagli

Programmazione A.A Architettura dei Calcolatori. ( Lezione V ) Componenti hardware e loro schema funzionale

Programmazione A.A Architettura dei Calcolatori. ( Lezione V ) Componenti hardware e loro schema funzionale Programmazione A.A. 2002-03 I Architettura dei Calcolatori ( Lezione V ) Componenti hardware e loro schema funzionale Prof. Giovanni Gallo Dr. Gianluca Cincotti Dipartimento di Matematica e Informatica

Dettagli

Architettura di una CPU

Architettura di una CPU Massimo VIOLANTE Politecnico di Torino Dipartimento di Automatica e Informatica Sommario Organizzazione di un processore Linguaggio macchina Modi di indirizzamento Tipi di istruzioni 2 M. Violante 1.1

Dettagli

AXO - Architettura dei Calcolatori e Sistema Operativo. organizzazione strutturata dei calcolatori

AXO - Architettura dei Calcolatori e Sistema Operativo. organizzazione strutturata dei calcolatori AXO - Architettura dei Calcolatori e Sistema Operativo organizzazione strutturata dei calcolatori I livelli I calcolatori sono progettati come una serie di livelli ognuno dei quali si basa sui livelli

Dettagli

Architettura dei Calcolatori elettronici

Architettura dei Calcolatori elettronici Architettura dei Calcolatori elettronici CORSO DI CALCOLATORI ELETTRONICI I CdL Ingegneria Biomedica (A-I) DIS - Università degli Studi di Napoli Federico II Dal punto di vista architetturale un calcolatore

Dettagli

Il processore Pentium

Il processore Pentium Caratteristiche principali (I) Architettura interna a 32 bit Address bus a 32 bit: si possono indirizzare fino a 4 GB di memoria fisica Data bus a 64 bit (si tratta in pratica di 2 data bus a 32 bit in

Dettagli

I formati delle istruzioni

I formati delle istruzioni Appunti di Calcolatori Elettronici Le istruzioni I formati delle istruzioni... 1 Criteri generali di progettazione dei formati delle istruzioni... 2 Cenni all indirizzamento... 4 Indirizzamento immediato...

Dettagli

Architettura degli Elaboratori. Classe 3 Prof.ssa Anselmo. Appello del 19 Febbraio Attenzione:

Architettura degli Elaboratori. Classe 3 Prof.ssa Anselmo. Appello del 19 Febbraio Attenzione: Cognome.. Nome.... Architettura degli Elaboratori Classe 3 Prof.ssa Anselmo Appello del 19 Febbraio 2016 Attenzione: Inserire i propri dati nell apposito spazio sottostante e in testa a questa pagina.

Dettagli

Architettura di tipo registro-registro (load/store)

Architettura di tipo registro-registro (load/store) Caratteristiche principali dell architettura del processore MIPS E un architettura RISC (Reduced Instruction Set Computer) Esegue soltanto istruzioni con un ciclo base ridotto, cioè costituito da poche

Dettagli

ARCHITETTURA DI UN ELABORATORE

ARCHITETTURA DI UN ELABORATORE ARCHITETTURA DI UN ELABORATORE Unità funzionali Ispirata al modello della Macchina di Von Neumann (Princeton, Institute for Advanced Study, anni 40). La macchiana di Von Neumann: Non distingueva fra RAM

Dettagli

La macchina di Von Neumann

La macchina di Von Neumann Università degli Studi di Palermo Facoltà di Ingegneria La macchina di Edoardo Ardizzone & Ignazio Infantino Appunti per il corso di Fondamenti di Informatica Corso di Laurea in Ingegneria Informatica

Dettagli

Unità aritmetica e logica

Unità aritmetica e logica Aritmetica del calcolatore Capitolo 9 Unità aritmetica e logica n Esegue le operazioni aritmetiche e logiche n Ogni altra componente nel calcolatore serve questa unità n Gestisce gli interi n Può gestire

Dettagli

Sistemi di numerazione

Sistemi di numerazione SOMMARIO Sistemi di numerazione...2 Sistema decimale (o a base 10)...2 Sistema binario...2 Operazioni sui numeri binari...3 Espressioni logiche...4 Definizione...4 Prodotto Logico : AND...4 Somma Logica

Dettagli

Calcolatori Elettronici

Calcolatori Elettronici Calcolatori Elettronici Il linguaggio assemblativo MIPS (1) Istruzioni di ALU: operazioni ed operandi Trasferimenti tra memoria e CPU Vettori (1) Le costanti Livelli di astrazione s o f t w a r e H W Linguaggio

Dettagli

Il calcolatore. È un sistema complesso costituito da un numero elevato di componenti. è strutturato in forma gerarchica

Il calcolatore. È un sistema complesso costituito da un numero elevato di componenti. è strutturato in forma gerarchica Il calcolatore È un sistema complesso costituito da un numero elevato di componenti. è strutturato in forma gerarchica ogni livello di descrizione è caratterizzato da una struttura rappresentante l organizzazione

Dettagli

Macchina di Riferimento: argomenti

Macchina di Riferimento: argomenti Macchina di Riferimento: argomenti L'architettura di una macchina MIPS Organizzazione della memoria I registri della CPU L'esecuzione dei programmi Il ciclo fetch-execute Il simulatore SPIM 1 Architettura

Dettagli

Indirettezza. Fetch/Execute. Fetch/Execute. Introduzione della Indirettezza (indirect)

Indirettezza. Fetch/Execute. Fetch/Execute. Introduzione della Indirettezza (indirect) Ciclo esecutivo delle istruzioni: Fetch/Execute Lo avete visto nel corso di Introduzione alle Architetture degli Elaboratori Stallings, Capitolo 3 Ne vediamo una versione revisionata Indirettezza Per recuperare

Dettagli

Corso di Calcolatori Elettronici I Istruzioni macchina ing. Alessandro Cilardo

Corso di Calcolatori Elettronici I Istruzioni macchina ing. Alessandro Cilardo Corso di Calcolatori Elettronici I Istruzioni macchina ing. Alessandro Cilardo Corso di Laurea in Ingegneria Biomedica Istruzioni del processore Abbiamo visto in precedenza alcuni esempi di istruzioni

Dettagli

Lezione 22 La Memoria Interna (1)

Lezione 22 La Memoria Interna (1) Lezione 22 La Memoria Interna (1) Vittorio Scarano Architettura Corso di Laurea in Informatica Università degli Studi di Salerno Organizzazione della lezione Dove siamo e dove stiamo andando La gerarchia

Dettagli

SOLUZIONI DELLA PROVA SCRITTA DEL CORSO DI. NUOVO E VECCHIO ORDINAMENTO DIDATTICO 28 Settembre 2006

SOLUZIONI DELLA PROVA SCRITTA DEL CORSO DI. NUOVO E VECCHIO ORDINAMENTO DIDATTICO 28 Settembre 2006 SOLUZIONI DELLA PROVA SCRITTA DEL CORSO DI NUOVO E VECCHIO ORDINAMENTO DIDATTICO 28 Settembre 26 MOTIVARE IN MANIERA CHIARA LE SOLUZIONI PROPOSTE A CIASCUNO DEGLI ESERCIZI SVOLTI ESERCIZIO 1 (8 punti)

Dettagli

Corso di Fondamenti di Informatica Elementi di Architettura

Corso di Fondamenti di Informatica Elementi di Architettura di Cassino e del Lazio Meridionale Corso di Informatica Elementi di Architettura Anno Accademico 2016/2017 Francesco Tortorella Modello di von Neumann Bus di sistema CPU Memoria Centrale Interfaccia Periferica

Dettagli

ARCHITETTURE AVANZATE DEI CALCOLATORI, A.A. 2007/08 Soluzione esercizi sul pipelining

ARCHITETTURE AVANZATE DEI CALCOLATORI, A.A. 2007/08 Soluzione esercizi sul pipelining ARCHITETTURE AVANZATE DEI CALCOLATORI, A.A. 2007/08 Soluzione esercizi sul pipelining Esercizio 1) N.B. Nei diagrammi a cicli multipli non sono indicati i registri di pipeline (per semplicità) a) Si tratta

Dettagli

Architettura degli Elaboratori. Classe 3 Prof.ssa Anselmo. Appello del 18 Febbraio Attenzione:

Architettura degli Elaboratori. Classe 3 Prof.ssa Anselmo. Appello del 18 Febbraio Attenzione: Cognome.. Nome.... Architettura degli Elaboratori Classe 3 Prof.ssa Anselmo Appello del 18 Febbraio 2015 Attenzione: Inserire i propri dati nell apposito spazio sottostante e in testa a questa pagina.

Dettagli

ISA Input / Output (I/O) Data register Controller

ISA Input / Output (I/O) Data register Controller ISA Input / Output (I/O) Numerose Periferiche di tanti tipi diversi, collegati alla CPU mediante BUS diversi. Solo Input (tastiera, mouse), producono dati che la CPU deve leggere. Solo Output (Schermo),

Dettagli

Capitolo 5 Elementi architetturali di base

Capitolo 5 Elementi architetturali di base Capitolo 5 Elementi architetturali di base Giuseppe Lami Istituto di Scienza e Tecnologie dell Informazione CNR Via Moruzzi, 1 - Pisa giuseppe.lami@isti.cnr.it Struttura - Unità di elaborazione e controllo

Dettagli

Elaborazione dell informazione

Elaborazione dell informazione Elaborazione dell informazione Primo esempio Ricominciamo dai numeri (45 + 25) è definita rigorosamente Un primo calcolatore (a) Figura 1.1 Configurazione del pallottoliere (a) prima e (b) dopo l esecuzione

Dettagli

Lezione 20. Assembly MIPS: Il set istruzioni, strutture di controllo in Assembly

Lezione 20. Assembly MIPS: Il set istruzioni, strutture di controllo in Assembly Architettura degli Elaboratori Lezione 20 Assembly MIPS: Il set istruzioni, strutture di controllo in Assembly Prof. F. Pedersini Dipartimento di Scienze dell Informazione Università degli Studi di Milano

Dettagli

Pipeline Problemi 1. Pipeline Problemi 2

Pipeline Problemi 1. Pipeline Problemi 2 Problemi 1 Vari fenomeni pregiudicano il raggiungimento del massimo di parallelismo teorico (stallo) Sbilanciamento delle fasi Durata diversa per fase e per istruzione Problemi strutturali La sovrapposizione

Dettagli

Introduzione alle gerarchie di memoria

Introduzione alle gerarchie di memoria Introduzione alle gerarchie di memoria 1 Un ripasso Circuito sequenziale Segnale di clock Circuito sincrono Temporizzazione sensibile ai fronti Latch tipo S-R Latch tipo D Flip-flop tipo D Register file

Dettagli