Dispense Calcolatori Elettronici Con Esercizi

May 5, 2017 | Author: Atish Andrea Rambaran | Category: N/A
Share Embed Donate


Short Description

Download Dispense Calcolatori Elettronici Con Esercizi...

Description

Appunti di Calcolatori Elettronici

A.A. 2009/2010

APPUNTI DI CALCOLATORI ELETTRONICI

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 2009/2010. Parte teorica a cura di Nicola Pietroleonardo. Esercizi ed approfondimenti a cura di Fabio Stroppa.

Copyright (c) 2009-2010-2011 Nicola Pietroleonardo e Fabio Stroppa. [email protected] [email protected] Questo testo è pubblicato sotto licenza: Creative Commons Attribuzione - Non commerciale – Condividi allo stesso modo 2.5 Italia http://creativecommons.org/licenses/by-nc-sa/2.5/it/

Il testo della licenza è disponibile qui: http://creativecommons.org/licenses/by-nc-sa/2.5/it/legalcode Tutte le versioni di questo testo sono disponibili nell'area download di Desfa.org. Gli autori non forniscono nessuna garanzia sulle nozioni esposte, nonché sulla precisione delle stesse; fermo restando il forte impegno degli autori nel rendere questo documento il più preciso possibile. Questo testo è da intendersi pertanto a puro scopo informativo.

E DI T OR: N ic o la P ie t ro le o n a r d o P ROD UZ I ON E : N ic o la P ie t ro l e o n a rd o , Fa b io S t ro p p a GRA FI C A DI COP E R TI N A : Fa b riz io P . Ba ld in i - h t t p :// w ww . b a ld u s. a lt e r vist a . o rg /

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 2

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

IND I CE G E NE R AL E PARTE PRIMA .................................................................................................................................. 7 

SET DI ISTRUZIONI .................................................................................................................................... 8 ISTRUZIONI DI TRASFERIMENTO DEI DATI ........................................................................................................... 8 ISTRUZIONI DI TIPO M (MOV)........................................................................................................................ 10 ISTRUZIONI DI CALCOLO ................................................................................................................................ 11 ISTRUZIONI DI CONTROLLO ............................................................................................................................ 12 TABELLA SOTTOINSIEME ISTRUZIONI DI MIPS64®.............................................................................................. 13



ESECUZIONE DELLE ISTRUZIONI ALL’INTERNO DEL PROCESSORE – STRUTTURA DEL PROCESSORE ............................... 14

FORMATO DELLE ISTRUZIONI ....................................................................................................................... 14 CODIFICA DELL’ISTRUZIONE PER UN PROCESSORE NO-PIPELINE........................................................................... 15 STRUTTURA DEL PROCESSORE NO-PIPELINE ..................................................................................................... 16 DESCRIZIONE DETTAGLIATA DI OGNI PASSAGGIO ............................................................................................... 17 1^ FASE

IF – INSTRUCTION FETCH............................................................................................... 17

2^ FASE

ID – INSTRUCTION DECODE ........................................................................................... 17

3^ FASE

EX – EXECUTION ......................................................................................................... 18

4^ FASE

MEM – MEMORY ACCESS ............................................................................................. 19

5^ FASE

WB – WRITE BACK...................................................................................................... 20

RIEPILOGO .............................................................................................................................................. 21 TECNICA PIPELINE – TEMPO DI ESECUZIONE DI UN PROGRAMA .......................................................................... 23 STRUTTURA DEL PROCESSORE PIPELINE ........................................................................................................... 26 EVENTI DI CIASCUNO STADIO DELLA PIPELINE DI MIPS....................................................................................... 27 

BREVE CENNO SULLE MEMORIE DEL PROCESSORE (CACHE DI 1°LIVELLO) – A CCESSO ALLA MEMORIA ....................... 29



ALEE STRUTTURALI – ALEE DI DATO ........................................................................................................ 31 ALEE STRUTTURALE. ..................................................................................................................................... 31 ALEE DI DATO ............................................................................................................................................. 31 1.

ISTRUZIONI ALU ............................................................................................................................... 32

2.

ISTRUZIONI LOAD ............................................................................................................................. 35

3.

ISTRUZIONE BRANCH......................................................................................................................... 36

MIPS PIPELINE OTTIMIZZATO ......................................................................................................................... 37 DELAY SLOT – TECNICA STATICA ..................................................................................................................... 38 TECNICA SPECULATIVA – TECNICA DINAMICA .................................................................................................... 39 CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 3

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010



SROTOLAMENTO DEL LOOP ....................................................................................................................... 41



PIPELINE DA PROGRAMMA ....................................................................................................................... 43

ESERCIZI DI RIEPILOGO ..................................................................................................................................... 45 ESERCIZIO 1 ................................................................................................................................................ 45 ESERCIZIO 2 ................................................................................................................................................ 48 ESERCIZIO 3 ................................................................................................................................................ 51 ESERCIZIO 4 ................................................................................................................................................ 53 ESERCIZIO 5 ................................................................................................................................................ 55

PARTE SECONDA .......................................................................................................................... 62 

GERARCHIA DI MEMORIA ....................................................................................................................... 63 MECCANISMO A FINESTRA DEI REGISTRI .......................................................................................................... 63 PRINCIPI FONDAMENTALI DELLA GERARCHIA DI MEMORIA ................................................................................. 63 

TRASPERENZA DEI LIVELLI .................................................................................................................. 63



PRINCIPI DI LOCALITA’ ...................................................................................................................... 64 -

LOCALITA’ SPAZIALE ...................................................................................................................... 64

-

LOCALITA’ TEMPORALE.................................................................................................................. 64

QUATTRO DOMANDE PER LA CLASSIFICAZIONE DELLE GERARCHIE DI MEMORIE..................................................... 64 MEMORIE CACHE ...................................................................................................................................... 65 

UN PO’ DI STORIA E CURIOSITÀ.............................................................................................................. 65



STRATEGIE DI ALLOCAZIONE DEI BLOCCHI ................................................................................................ 65 CACHE COMPLETAMENTE ASSOCIATIVA ....................................................................................................... 66 CACHE AD INDIRIZZAMENTO DIRETTO ......................................................................................................... 66 CACHE SET ASSOCIATIVA ........................................................................................................................... 66



STRATEGIE DI RICERCA E IDENTIFICAZIONE ............................................................................................... 67



STRATEGIE DI SOSTITUZIONE (FALLIMENTI DI ACCESSO) ............................................................................. 68 1.

METODO RANDOM .......................................................................................................................... 68

2.

METODO LRU (LAST RECENTLY USED) ................................................................................................. 68

3.

METODO FIFO (FIRST IN FIRST OUT) ................................................................................................... 69

FALLIMENTI DI ACCESSO ALLA CACHE – LEGGE DELLE TRE C ........................................................................... 69 

STRATEGIE DI SCRITTURA NELLA CACHE ................................................................................................... 70 1.

WRITE THROUGH. ............................................................................................................................ 70

2.

WRITE BACK.................................................................................................................................... 70

ELETTRONICA DELLE MEMORIE................................................................................................................. 71 CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 4

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

SRAM. ............................................................................................................................................ 71 DRAM. ........................................................................................................................................... 71 VALUTAZIONE DELLE PRESTAZIONI DELLA MEMORIA CACHE ......................................................................... 72 FUNZIONAMENTO LOGICO DI UNA MEMORIA CACHE .................................................................................. 75 

CACHE POWERPC ............................................................................................................................. 75



CACHE MOTOROLA 68000 ................................................................................................................ 77

INTERAZIONE DELLE MEMORIE CACHE IN UN SISTEMA COMPLESSO ............................................................... 78 PROBLEMATICHE RELATIVE ALL’I/O..................................................................................................... 78 PROBLEMATICHE RELATIVE AI SISTEMI MULTICORE ............................................................................... 78 MIGLIORAMENTO DELLE PRESTAZIONI DELLA BANDA PASSANTE DI UNA MEMORIA ......................................... 79 BANCHI MULTIPLI DI MEMORIA PARALLELI .................................................................................................. 79 BANCHI MULTIPLI DI MEMORIA INTERLACCIATI............................................................................................. 79 ORGANIZZAZIONE DELLE MEMORIE A SEMICONDUTTORE ............................................................................. 81 ESERCIZI DI RIEPILOGO ................................................................................................................................ 82 ESERCIZIO 1 ............................................................................................................................................ 82 ESERCIZIO 2 ............................................................................................................................................ 82

PARTE TERZA ................................................................................................................................ 84 

PROCESSORE FLOATING POINT ................................................................................................................ 85 SCHEDULING DELLE ISTRUZIONI FLOATING POINT .............................................................................................. 88 ALGORITMO DI TOMASULO ....................................................................................................................... 89 APPLICAZIONE ALGORITMO DI TOMASULO - ESEMPIO ................................................................................ 91 VANTAGGI .............................................................................................................................................. 98

PARTE QUARTA ............................................................................................................................ 99 

PROCESSORI VLIW ................................................................................................................................ 100



PROCESSORI SUPERSCALARI .................................................................................................................. 103



PROCESSORI VETTORIALI ....................................................................................................................... 104 TABELLA SET ISTRUZIONI VETTORIALI. ............................................................................................................ 105 OPERAZIONI DI LOAD E STORE ..................................................................................................................... 105 L’ISTRUZIONE LVWS .................................................................................................................................... 106 I REGISTRI VLR E MVLR ............................................................................................................................... 106 PRESTAZIONI ............................................................................................................................................. 107 ANALISI REALE DELL’ARCHITETTURA DI UNA CPU VETTORIALE – CRAY-1 (1976).................................................. 108

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 5

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

SCHEMA LOGICO .................................................................................................................................... 108 IDEE ALLA BASE DELLA ORGANIZZAZIONE VETTORIALE ................................................................................. 109 CODICE VETTORIALE ............................................................................................................................... 109 ESECUZIONE ARITMETICA DELLE ISTRUZIONI ............................................................................................... 110 SISTEMA DI MEMORIZZAZIONE DI DATI VETTORIALI NEI REGISTRI VETTORIALI ................................................. 110 ESECUZIONE ISTRUZIONI VETTORIALI ......................................................................................................... 110 STRUTTURA DELLE UNITA’ VETTORIALI ...................................................................................................... 111 DIFFERENZA FRA ARCHITETTURA MEMORIA-MEMORIA E ARCHITETTURA A REGISTRI VETTORIALI ....................... 111 VETTORIZZAZIONE AUTOMATICA DEL CODICE ............................................................................................. 112 GESTIONE DI VETTORI CON DIMENSIONE SUPERIORE A MVLR – VECTOR STRIPMINING ..................................... 112 PARALLELISMO DELLE ISTRUZIONI VETTORIALI............................................................................................. 114 PENALITA’ DI AVVIO DELLE CPU VETTORIALI............................................................................................... 115 GESTIONE DELLE CONDIZIONI – USO DEL REGISTRO V.MASK – ISTRUZIONI MASCHERATE ................................. 115 RIDUZIONE A OPERAZIONI SCALARI ........................................................................................................... 117 ESERCIZIO ............................................................................................................................................. 118 

ARCHITETTURA MULTICORE .................................................................................................................... 123 PARALLELISMO A LIVELLO DI THREAD, MULTI-THREAD .................................................................................... 124 1.

SIMULTANEOUS MULTI-THREADING .................................................................................................. 124

2.

FINE-GRAINED MULTI-THREADING. .................................................................................................. 124

3.

COARSE-GRAINED MULTI-THREAD. ................................................................................................... 124

MEMORIA CONDIVISA E MEMORIA DISTRIBUITA IN SISTEMI MULTICORE ............................................................ 125

INDICE ANALITICO ................................................................................ 126 BIBLIOGRAFIA ...................................................................................... 127 ESERCIZI SVOLTI ................................................................................... 128

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 6

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

PARTE PRIMA

PARTE PRIMA PROCESSORE SCALARE ARCHITETTURA INTERA

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 7

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

 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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 8

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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. 00000101 56bit

+

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: 00000101 Complemento a 1 11111010 + 1 11111011 Il numero ottenuto è -5 in binario (complemento a 2). Se invece 11111011 fosse un numero assoluto, ossia senza segno, sarebbe 255 – 4 = 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. 11111111111111…………………1 56bit

+

11111011 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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 9

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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;

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 10

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici  

A.A. 2009/2010

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: 𝑥 ∙ 𝑦 + 𝑧). 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).

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 11

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 12

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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 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

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

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

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

Controllo: Salti condizionati e non condizionati; relativi al PC o usando un registro

BEQZ, BNEZ BEQ,BNE BGTZ, BLTZ BGEZ, BLEZ BC1T,BC1F MOVN, MOVZ J, JR TRAP ERET

Significato dell’istruzione 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: http://www.mips.com/products/architectures/mips64/

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 13

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici 

A.A. 2009/2010

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 𝑙𝑜𝑔2 𝑛 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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 14

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 15

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 16

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici 

A.A. 2009/2010

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[IR6..10] B  Regs[IR11..15] Imm  ((IR16)16##IR16..31)

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 17

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 18

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

 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

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 19

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

 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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 20

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 21

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

ISTRUZIONE ALU GPR op IMM

ISTRUZIONE STORE

ISTRUZIONE BRANCH

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 22

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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à: 𝑇+ 𝑁−1 𝑡 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: 𝑡 =

𝑇 𝑛𝑙

𝑜𝑝𝑝𝑢𝑟𝑒

𝑇 𝑝𝑝

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 23

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

Quindi: 𝑇+ 𝑁−1

𝑇 𝑁𝑇 𝑇 𝑛𝑙𝑇 + 𝑁𝑇 − 𝑇 𝑁𝑇 𝑛𝑙 − 1 𝑇 =𝑇+ − = = + 𝑛𝑙 𝑛𝑙 𝑛𝑙 𝑛𝑙 𝑛𝑙 𝑛𝑙 con

Sul termine

𝑁𝑇 𝑛𝑙

𝑛𝑙 −1 𝑇 𝑛𝑙

parametro trascurabile;

è possibile fare dei ragionamenti: 𝑇

si è partiti dal presupposto che 𝑡 = 𝑛𝑙 , il quale potrebbe essere vero soltanto se il tempo di esecuzione di 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 TC; 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à: 𝑡 = 𝑇𝐿 + 𝑇𝐶 + 𝑇𝑆 TL: tempo di lettura del latch TC: tempo di calcolo della fase più lenta TS: 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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 24

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 25

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 26

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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 è EX/MEM.cond ← (if Se l’istruzione è EX/MEM.cond ← (if

una BEQZ (ID/EX.A una BNEZ (ID/EX.A

allora: == 0) {1}); allora: != 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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 27

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 28

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici 

BREVE CENNO SULLE

A.A. 2009/2010

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𝑛 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: 0

3 4

7 8

11

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 29

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

Ad esempio si supponga la seguente situazione di LOAD: 12

14

16

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. 12

13

14

15

16

e

R

p

L

O C

4 byte

17

18

19

U h

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 30

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici 

A.A. 2009/2010

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

CALCOLATORI ELETTRONICI A.A. 2009/2010

// Read R1 // Write R1

Pagina 31

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 32

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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. CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 33

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 34

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 35

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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).

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 36

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

MIPS PIPELINE OTTIMIZZATO

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 37

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 38

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 39

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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: ESEGUITO ESEGUITO

0 NON ESEGUITO

NON ESEGUITO

STATO 0: salto non verificato STATO 1: salto verificato

1

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 40

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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) stallo DADD R4,R4,R5 SD R3(0),R4 DADDI R1,R1,#8 DADDI R2,R2,#8 DADDI R3,R3,#8 DADDI R6,R6,#-1 stallo BNEZ R6,-9 stallo

Istruzioni necessarie

R1 punta al vettore A R2 punta al vettore B R3 punta al vettore C



C[i] = A[i] + B[i]

Istruzioni di gestione

Questo programma dovrebbe durare (9 ∙ 𝑁) + 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 ∙ 𝑁) + 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 ∙ 𝑁) + 1 colpi di clock: DADDI R6,R0,N LD R4,R1(0) LD R5,R2(0) stallo DADD R4,R4,R5 SD R3(0),R4 DADDI R1,R1,#8

DADDI R6,R0,N LD R4,R1(0) LD R5,R2(0) DIVENTA

DADDI R2,R2,#8 DADDI R3,R3,#8 DADDI R6,R6,#-1 stallo BNEZ R6,-9 stallo

CALCOLATORI ELETTRONICI A.A. 2009/2010

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

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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

//utilizzo un altro registro //utilizzo un altro registro

DADD R5,R5,R6 SD (3000)R1,R2 SD (2992)R1,R5 DADDI R1,R1,#-16 BNEZ R1,-10

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 42

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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; CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 43

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 44

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

ESERCIZI DI RIEPILOGO ESERCIZIO 1 Scrivere le microfasi della seguente istruzione: 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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 45

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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] //con rt + 1 accedo a F5 (a livello concettuale)

FASE MEM2 Mem[EX/MEM.ALUOUTPUT] ← EX/MEM.B

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

1* SEMICICLO

EX/MEM.ALUOUTPUT2 ← EX/MEM.ALUOUTPUT + 4 EX/MEM.B ← ID/EX.IR[rt+1]

2* SEMICICLO

FASE MEM2 Mem[EX/MEM.ALUOUTPUT2] ← EX/MEM.B

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 46

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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 (I):

ID IF

EX ID

MEM1 MEM2 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 (I):

ID IF

EX ID

MEM1 MEM2 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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 47

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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]];

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 48

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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

seconda istr: POP

ID

EX

MEM

WB

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

seconda istr: PUSH

ID

EX

MEM

WB

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 seconda istr: PUSH

CALCOLATORI ELETTRONICI A.A. 2009/2010

IF

ID

EX

MEM

WB

IF

ID

EX

MEM

Pagina 49

WB

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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

seconda istr: POP

ID

EX

MEM

WB

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 seconda istr: POP

CALCOLATORI ELETTRONICI A.A. 2009/2010

IF

ID

EX

MEM

WB

IF

ID

EX

MEM

Pagina 50

WB

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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] ← 𝑐𝑎𝑟𝑟𝑦

Sfruttando una suddivisione in semicicli, ID/EX.A e ID/EX.B sono letti nel primo semiciclo e scritti nel secondo.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 51

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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

seconda istr: qualsiasi

ID

EX1

EX2

WB1

WB2

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 seconda istr: qualsiasi

IF

ID

EX1

EX2

WB1(MEM1)

WB2(MEM2)

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 52

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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[1000 + 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

seconda istr: LW R1,0(R6)

ID

EX

MEM

WB

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 CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 53

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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 seconda istr: qualsiasi

IF

ID

EX

MEM1

MEM2

WB

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 54

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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

seconda istr: (istr. con PC corretto)

CALCOLATORI ELETTRONICI A.A. 2009/2010

ID

EX

MEM

WB

IF

stallo

stallo

stallo

Pagina 55

IF

ID

EX

MEM

WB

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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

seconda istr: (istr. con PC corretto)

ID

EX

MEM

WB

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

seconda istr: istr N-2 terza istr:

istr N-1

quarta istr:

(istr. con PC corretto)

ID

EX

MEM

WB

IF

ID

EX

MEM

WB

IF

ID

EX

MEM

WB

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 56

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 57

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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: LD 1200 ADD 1204 ST 1200

specificando anche qual è il suo scopo. 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 1200. M[1200] ← ACC

Come è facile notare questa architettura non permette una gestione in pipeline dell’istruzioni.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 58

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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).

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 59

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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: LOAD ALU FASE MEM: FASE MEM:

STORE FASE MEM:

BCOND FASE SETPC:

Mem[MAR] ← ACC µPC ← 0

if COND: PC ← MAR (via ALU)

LMDR ← Mem[MAR]

LMDR ← Mem[MAR]

FASE EXE/WB:

FASE EXE/WB:

ACC ← LMDR+0 µPC ← 0

ACC ← LMDR op ACC µPC ← 0

INT (da sistema) FASE STPC:

RTI FASE SETPC:

JSUB FASE STPC:

RET (from subroutine) FASE SETPC:

IAR ← PC

PC ← IAR

SAR ← PC

PC ← SAR

FASE SETPC:

µPC ← 0

FASE SETPC:

µPC ← 0

µPC ← 0

PC ← MAR (via ALU)

PC ← MAR (via ALU)

µPC ← 0

µ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. CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 60

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

Per cui si ha:

LD 1200 FASE IF IR ← Mem[PC] PC ← PC+4

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

ADD 1204 FASE IF IR ← Mem[PC] PC ← PC+4

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 µPC ← 0

(op == +)

ST 1200 FASE IF IR ← Mem[PC] PC ← PC+4

FASE ADD/ID MAR ← IR AND #0FFFFFFF µPC ← MM[IR[opcode]]

FASE MEM Mem[MAR] ← ACC

(MAR == 1200)

µPC ← 0

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 61

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

PARTE SECONDA

PARTE SECONDA MEMORIE CACHE

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 62

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici 

A.A. 2009/2010

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. BREVE CENNO SU :

1° LIVELLO

2° LIVELLO

MEMORIA CENTRALE

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 63

Pietroleonardo Nicola Stroppa Fabio

Costo/byte

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).

Appunti di Calcolatori Elettronici 

A.A. 2009/2010

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: 𝑇 = 𝑇𝐿𝑖−1 + 𝑇𝑆𝑖 Dove: 𝑇𝐿𝑖−1 è 𝑖𝑙 𝑡𝑒𝑚𝑝𝑜 𝑑𝑖 𝐿𝑒𝑡𝑡𝑢𝑟𝑎 𝑑𝑎𝑙 𝑙𝑖𝑣𝑒𝑙𝑙𝑜 𝑖𝑛𝑓𝑒𝑟𝑖𝑜𝑟𝑒 𝑖 − 1 𝑇𝑆𝑖 è 𝑖𝑙 𝑡𝑒𝑚𝑝𝑜 𝑑𝑖 𝑆𝑐𝑟𝑖𝑡𝑡𝑢𝑟𝑎 𝑎𝑙 𝑙𝑖𝑣𝑒𝑙𝑙𝑜 𝑠𝑡𝑒𝑠𝑠𝑜 𝑖 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) CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 64

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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 32’000 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

0 1 2 3 4 5 6 7

CALCOLATORI ELETTRONICI A.A. 2009/2010

1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7

Pagina 65

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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. 0 1 2 3 4 5 6 7

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 𝟏𝟔 𝟖 = 𝟎𝟎𝟏𝟏𝟏𝟎 𝟐 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 𝟏𝟏𝟎 𝟐 = 𝟔 𝟖 . Questa operazione equivale a: 𝑖𝑛𝑑𝑖𝑟𝑖𝑧𝑧𝑜 𝑑𝑖 𝑏𝑙𝑜𝑐𝑐𝑜 10 𝑀𝑂𝐷 𝑛𝑢𝑚𝑒𝑟𝑜 𝑒𝑓𝑓𝑒𝑡𝑡𝑖𝑣𝑜 𝑑𝑖 𝑙𝑖𝑛𝑒𝑒 𝑛𝑒𝑙𝑙𝑎 𝑐𝑎𝑐𝑕𝑒 Considerando l’esempio si ha: 14 𝑀𝑂𝐷 8 = 6 0 1 2 3 4 5 6 7

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: (𝑖𝑛𝑑𝑖𝑟𝑖𝑧𝑧𝑜 𝑑𝑖 𝑏𝑙𝑜𝑐𝑐𝑜) 10 𝑀𝑂𝐷 (𝑛𝑢𝑚𝑒𝑟𝑜 𝑒𝑓𝑓𝑒𝑡𝑡𝑖𝑣𝑜 𝑑𝑖 𝑠𝑒𝑡 𝑛𝑒𝑙𝑙𝑎 𝑐𝑎𝑐𝑕𝑒) Considerando l’esempio si ha: 14 𝑀𝑂𝐷 4 = 2. Questa operazione equivale a leggere gli ultimi due bit dei 6 che identificano il set: 001110. 0 1 2 3 4 5 6 7

0

1

0

1

0

1

0

1

Set. 0 Set. 1 Set. 2 Set. 3

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 66

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

 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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 67

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

 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 𝑛(𝑛 − 1) confronti e quindi sarà necessaria una rete di 𝑛(𝑛 − 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

CALCOLATORI ELETTRONICI A.A. 2009/2010

/ 0

3 0

2 0

Pagina 68

1 0

0 3

0 3

2 3

3 1

1 0

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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 4

LINEA 1

LINEA 2

LINEA 5 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).

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 69

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

 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 CPU 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 CACHE 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. MEMORIA I/O Un’ottimizzazione utilizzata di solito per ridurre il tempo di stallo consiste CENTRALE 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. 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. CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 70

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 71

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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: 𝑀𝑅 = 1 − 𝐻𝑅;  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ò: 𝑻𝑬𝑴𝑷𝑶 𝑫𝑰 𝑪𝑷𝑼 = = 𝑪𝑰𝑪𝑳𝑰 𝑫𝑰 𝑪𝑷𝑼 𝑰𝑵 𝑬𝑺𝑬𝑪𝑼𝒁𝑰𝑶𝑵𝑬 + 𝑪𝑰𝑪𝑳𝑰 𝑫𝑰 𝑺𝑻𝑨𝑳𝑳𝑶 𝑰𝑵 𝑴𝑬𝑴𝑶𝑹𝑰𝑨 ∗ 𝑻𝑬𝑴𝑷𝑶 𝑫𝑬𝑳 𝑪𝑰𝑪𝑳𝑶 𝑫𝑰 𝑪𝑳𝑶𝑪𝑲

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: 𝑪𝑰𝑪𝑳𝑰 𝑫𝑰 𝑺𝑻𝑨𝑳𝑳𝑶 𝑰𝑵 𝑴𝑬𝑴𝑶𝑹𝑰𝑨 = 𝑪𝑰𝑪𝑳𝑰 𝑫𝑰 𝑺𝑻𝑨𝑳𝑳𝑶 𝑰𝑵 𝑳𝑬𝑻𝑻𝑼𝑹𝑨 + 𝑪𝑰𝑪𝑳𝑰 𝑫𝑰 𝑺𝑻𝑨𝑳𝑳𝑶 𝑰𝑵 𝑺𝑪𝑹𝑰𝑻𝑻𝑼𝑹𝑨 = =

𝑳𝑬𝑻𝑻𝑼𝑹𝑬 𝑰𝑵 𝑴𝑬𝑴𝑶𝑹𝑰𝑨 𝑷𝑹𝑶𝑮𝑹𝑨𝑴𝑴𝑨

𝑺𝑪𝑹𝑰𝑻𝑻𝑼𝑹𝑬 𝑰𝑵 𝑴𝑬𝑴𝑶𝑹𝑰𝑨 𝑷𝑹𝑶𝑮𝑹𝑨𝑴𝑴𝑨

∗ 𝑴𝑰𝑺𝑺 𝑹𝑨𝑻𝑬 𝑷𝑬𝑹 𝑳𝑬 𝑳𝑬𝑻𝑻𝑼𝑹𝑬 ∗ 𝑷𝑬𝑵𝑨𝑳𝑰𝒁𝒁𝑨𝒁𝑰𝑶𝑵𝑬 𝑫𝑰 𝑭𝑨𝑳𝑳𝑰𝑴𝑬𝑵𝑻𝑶 𝑷𝑬𝑹 𝑳𝑬 𝑳𝑬𝑻𝑻𝑼𝑹𝑬 +

∗ 𝑴𝑰𝑺𝑺 𝑹𝑨𝑻𝑬 𝑷𝑬𝑹 𝑳𝑬 𝑺𝑪𝑹𝑰𝑻𝑻𝑼𝑹𝑬 ∗ 𝑷𝑬𝑵𝑨𝑳𝑰𝒁𝒁𝑨𝒁𝑰𝑶𝑵𝑬 𝑫𝑰 𝑭𝑨𝑳𝑳𝑰𝑴𝑬𝑵𝑻𝑶 𝑷𝑬𝑹 𝑳𝑬 𝑺𝑪𝑹𝑰𝑻𝑻𝑼𝑹𝑬

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 72

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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: 𝑻𝑬𝑴𝑷𝑶 𝑴𝑬𝑫𝑰𝑶 𝑫𝑰 𝑨𝑪𝑪𝑬𝑺𝑺𝑶 𝑨𝑳𝑳𝑨 𝑴𝑬𝑴𝑶𝑹𝑰𝑨

= 𝑯𝑰𝑻 𝑻𝑰𝑴𝑬 + 𝑴𝑰𝑺𝑺 𝑹𝑨𝑻𝑬 ∗ 𝑷𝑬𝑵𝑨𝑳𝑰𝒁𝒁𝑨𝒁𝑰𝑶𝑵𝑬 𝑫𝑰 𝑭𝑨𝑳𝑳𝑰𝑴𝑬𝑵𝑻𝑶

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

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 73

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

SCHEMA RIASSUNTIVO DEI VANTAGGI/SVANTAGGI DELLE TECNICHE E DEI METODI ANALIZZATI aumentando

VANTAGGI

SVANTAGGI

ASSOCIATIVITA’ - Minor numero di conflitti - Benefici in cache di medie dimensioni - Maggiori costi: ampiezza delle etichette e aggiunta di comparatori - Politica di sostituzione più costosa

CALCOLATORI ELETTRONICI A.A. 2009/2010

DIMENSIONE BLOCCHI - Minor numero di etichette

- Maggior tempo di trasferimento

Pagina 74

POLITICA LRU

BUFFER DI SCRITTURA

- Minor Miss Rate per cache a bassa associatività

- Minor stallo di scrittura

- Maggior costo hardware

- Maggior costo hardware

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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 68000 

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:

16384 128

= 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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 75

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

Di seguito è riportata un figura che implementa il funzionamento logico della cache del PowerPC.

xy: codificano se la linea è valida o meno; ------- : LINEE 00 ------- : LINEE 01 ------- : LINEE 10 ------- : LINEE 11 =

: COMPARATORE : PORTA AND

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 76

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici 

A.A. 2009/2010

Cache MOTOROLA 68000 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:

4096 64

= 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 68000 è simile a quella del PowePC con dovuti accorgimenti vista la minima differenza di funzionamento.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 77

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 78

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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: 𝐼 𝑏𝑦𝑡𝑒 𝐵= 𝑇 𝑠 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

00

12 bit

1Kbyte

8 bit

1Kbyte

1Kbyte

8 bit

1Kbyte

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 WORD 0 WORD 1 WORD 2 WORD 3 Ind. 0 WORD 4 WORD 5 WORD 6 WORD 7 Ind. 1 WORD 8 WORD 9 WORD 10 WORD 11 Ind. 2 Per cui in ingresso ad ogni modulo si hanno gli 8 bit più significativi dei 12 più 2 bit uguali a zero. CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 79

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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

8 bit

2 bit

00

00

8 bit

00

8 bit

00

8 bit

00

12 bit

1Kbyte

32 bit

1Kbyte

1Kbyte

32 bit

1Kbyte

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 + ts), 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 (ts). 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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 80

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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).

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 81

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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 (= 22 − 11 − 4) 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 32 − 8 − 2 = 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). CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 82

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici 

A.A. 2009/2010

Cache ad indirizzamento diretto con 128 blocchi da 32 words;

numero di blocchi in memoria =

4 𝐺𝐵 32∗4 𝑏𝑦𝑡𝑒

= 225 ;

numero di bit necessari per indirizzare un blocco in memoria = 25 bit, di cui la parte meno significativa di 𝑙𝑜𝑔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 xx xxxx xxxx xxxx xxxx yyy yyyy

SPIAZZAMENTO 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 𝑀𝐵 256

= 216 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).

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 83

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

PARTE TERZA

PARTE TERZA PROCESSORE SCALARE ARCHITETTURA FLOATING POINT

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 84

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici 

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 85

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 86

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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

CALCOLATORI ELETTRONICI A.A. 2009/2010

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

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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-afterRead (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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 88

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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. 2. 3. 4. 5.

BUSY: campo di un bit che indica se la stazione di prenotazione è disponibile. OP: campo che indica l’operazione che dovrà essere eseguita. Vj: campo che indica dove è contenuto il valore del primo registro sorgente. Vk: campo che indica dove è contenuto il valore del secondo registro sorgente. 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. CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 89

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 90

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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 MULTD

F6, F2, F0,

34+, R2 45+, R3 F2, F4

SUBD DIVD ADDD

F8, F6, F2 F10, F0, F6 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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 91

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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 CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 92

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 93

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 94

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 95

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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 12 – 13 – 14 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.

CLOCK 16 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. CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 96

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

CLOCK 17 ÷ 55 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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 97

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 98

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

PARTE QUARTA

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

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 99

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici 

A.A. 2009/2010

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 𝑏𝑖𝑡 𝑥 4 𝑖𝑠𝑡𝑟𝑢𝑧𝑖𝑜𝑛𝑖). 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

UNITA’ 1

UNITA’ 2

UNITA’ 3

UNITA’ 4

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. 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 UNITA’ ACC. MEM. 1

CALCOLATORI ELETTRONICI A.A. 2009/2010

32 bit UNITA’ ACC. MEM. 2

32 bit UNITA’ FP 1

Pagina 100

32 bit UNITA’ FP 2

32 bit UNITA’ INTERA/BRANC H

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

Il listato del programma già ottimizzato, con la tecnica dello srotolamento del loop eseguita per sette volte, è il seguente: 1 LOOP: 2

L.D L.D

F0,0(R1) F6,-8(R1)

3 4 5

L.D L.D L.D

F10,-16(R1) F14,-24(R1) F18,-32(R1)

6 7 8 9

L.D L.D ADD.D ADD.D

F22,-40(R1) F26,-48(R1) F4,F0,F2 F8,F6,F2

10 11 12

ADD.D ADD.D ADD.D

F12,F10,F2 F16,F14,F2 F20,F18,F2

13 14 15 16

ADD.D ADD.D S.D S.D

F24,F22,F2 F28,F26,F2 0(R1),F4 -8(R1),F8

17 18 19

S.D S.D S.D

-16(R1),F12 -24(R1),F16 -32(R1),F20

20 21 22 23

S.D DSUBUI BNEZ S.D

-40(R1),F24 R1,R1,#56 R1,LOOP 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. CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 101

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

È 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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 102

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici 

A.A. 2009/2010

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.

UNITA’ INTERA

Istruzione intera

Istruzione Floating point

MEM. DATI

UNITA’ FLOATING POINT

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;

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 103

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici 

A.A. 2009/2010

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

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 104

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 105

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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: LOADV

V2,…

LOADV V3,… ADDV V1,V2,V3 STOREV …,V1

1cc IF

2cc ID

3cc EX

4cc MEM

5cc WB

6cc

7cc

8cc

9cc

IF

ID

EX IF

MEM ID IF

WB EX ID

MEM EX

WB MEM

WB

stallo

(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. CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 106

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 107

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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 1976. 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; 1

tramite il moltiplicatore verrà eseguita poi l’operazione: 𝑥 ∙ 𝑦

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.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 108

Pietroleonardo Nicola Stroppa Fabio

Appunti di Calcolatori Elettronici

A.A. 2009/2010

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 LI R4, 64 for (i=0; i64 per un DLXV con MVLR = 64. Si vuole realizzare una procedura che esegua C[>64] = A[>64] + B[>64]. Utilizziamo R1 per contenere la dimensione del vettore. Utilizziamo R10 come indice per scorrere tra i vari sottovettori. Utilizziamo R2 per contenere l’indirizzo in memoria del primo elemento del vettore A. Utilizziamo R3 per contenere l’indirizzo in memoria del primo elemento del vettore B. Utilizziamo R4 per contenere l’indirizzo in memoria del primo elemento del vettore C. I due vettori avranno dimensioni superiori a MVLR. Si può dunque pensare di suddividere i due vettori in tanti sottovettori da 64 elementi l’uno. Il problema principale è però che non sappiamo a priori se queste dimensioni sono divisibili per MVLR.  Nel caso lo fossero, bisognerà semplicemente incrementare l’indice di un valore pari a 8 byte x 64 elementi = 512 byte ad ogni iterazione per passare al sottovettore successivo senza modificare mai VLR.  Nel caso non lo fossero, e questo è il caso generale da usare per risolvere questo tipo di problema, bisognerà considerare un vettore residuo. Quindi scomporre il vettore principale in tanti sottovettori da 64 più un altro con dimensione minore di 64. È logico schedulare come primo sottovettore il vettore residuo, in modo tale da non dover verificare ad ogni iterazione se si è giunti al penultimo sottovettore e quindi cambiare alla fine il VLR. Si pone quindi VLR uguale al residuo e lo si cambia alla fine di ogni loop ponendolo uguale a 64. Per ottenere la dimensione di questo residuo, si può utilizzare questa operazione: ANDI

R10, R1, #63

Infatti, gli ultimi 6 bit di un numero binario qualsiasi corrispondono proprio al suo residuo se divisi per 64, ed essendo 26=64, ponendo 6 bit a 1 si ottiene il numero decimale 63 che posto in AND con la dimensione del vettore mette a zero tutti i bit più significativi del sesto. Ipotizzando un vettore di 187 elementi si ha: 187 / 64 = 2,921  64 x 2 = 128  187 – 128 = 59 (187)10 (10111011)2 (63)10  (111111)2 10111011 AND 111111 = 00111011 (00111011)2  (59)10 Poniamo il valore 64 in un registro qualsiasi (R5) in modo tale da poterlo poi spostare in VLR con l’istruzione MTC1 quando richiesto. DADDI

R5, R0, #64

Considerando l’esempio della somma dei vettori per un processore scalare, abbiamo verificato che è più conveniente tenere un indice partendo dal fondo del vettore per arrivare fino in cima. Quindi volendo andare in coda al vettore, l’indice da utilizzare non dovrà partire da 0 ma da (dimensione del vettore – residuo) x 8 byte. Ricordiamoci di settare VLR pari al residuo prima di porre l’indice in coda al vettore.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 57

Pietroleonardo Nicola Stroppa Fabio

Esercizi di Calcolatori Elettronici MTC1 DSUB DMUL

A.A. 2009/2010

VLR, R10 R10, R1, R10 R10, R10, #8

Ora si può iniziare il loop. loop:

LV LV ADDV.D SV

V1, R10(R2) V2, R10(R3) V1, V1, V2 R10(R4), V1

Alla fine del loop, si decrementa il valore dell’indice di una quantità pari ad un sottovettore, quindi di 64 elementi, ognuno da 8 byte, quindi 512 byte. DADDI

R10, R10, #-512

Imposto VLR pari a 64, dato che da ora in poi, i sottovettori saranno sempre di dimensioni pari a MVLR. MTC1

VLR, R5

Impongo la condizione che fino a ché l’indice è maggiore o uguale a zero, l’iterazione deve essere eseguita. BGEZ

R10, loop

Il listato completo è:

loop:

ANDI DADDI MTC1 DSUB DMUL LV LV stallo ADDV.D SV DADDI MTC1 BGEZ stallo

R10, R1, #63 R5, R0, #64 VLR, R10 R10, R1, R10 R10, R10, #8 V1, R10(R2) V2, R10(R3) V1, V1, V2 R10(R4), V1 R10, R10, #-512 VLR, R5 R10, loop

L’istruzione di salto provoca i soliti stalli.  Spostiamo la MTC1 nel delay slot sotto BGEZ per non perdere il colpo di clock.  Lo stallo sotto la LV non potrà essere evitato.

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 58

Pietroleonardo Nicola Stroppa Fabio

Esercizi di Calcolatori Elettronici

A.A. 2009/2010

ESERCIZIO 3 – SOMMA DI MATRICI CON MxN > 64 Somma di due matrici con un numero di elementi MxN >64 per un DLXV con MVLR = 64. Si vuole realizzare una procedura che esegua C[>64][>64] = A[>64] [>64] + B[>64] [>64]. Prima di pensare a somme matriciali con due for, uno per riga e uno per colonna, ragioniamo un attimo su come vengono salvate le matrici in memoria per giungere ad una gradevole soluzione. In memoria, le matrici vengono salvate per righe. Questo significa che due blocchi contigui in memoria conterranno elementi successivi della stessa riga. A[0][0] A[0][1] A[0][2] A[0][3] A[0][4] A[0][5] A*0+*…+ Una volta terminata la riga 0, successivamente, in memoria sarà allocata tutta la riga 1. Dunque, le matrici in memoria non sono altro che vettori di dimensione MxN. Il programma in assembly è identico a quello della somma di due vettori di dimensione >64, con l’unica differenza che la dimensione questa volta non sarà immediatamente passata come parametro alla routine ma bisognerà ricavarsela con una semplice moltiplicazione. Utilizziamo R1 per contenere la M ed R6 per contenere N.

loop:

DMUL ANDI DADDI MTC1 DSUB DMUL LV LV ADDV.D SV DADDI BGEZ MTC1

CALCOLATORI ELETTRONICI A.A. 2009/2010

R1, R1, R6 R10, R1, #63 R5, R0, #64 VLR, R10 R10, R1, R10 R10, R10, #8 V1, R10(R2) V2, R10(R3) V1, V1, V2 R10(R4), V1 R10, R10, #-512 R10, loop VLR, R5

Pagina 59

Pietroleonardo Nicola Stroppa Fabio

Esercizi di Calcolatori Elettronici

A.A. 2009/2010

ESERCIZIO 4 – OPERAZIONE Y = (aX + bY)/c Y= (aX + bY)/c con X e Y vettori di dimensione >64 e a, b e c scalari per un DLXV con MVLR = 64. Si vuole realizzare una procedura che esegua Y[>64] = (aX[>64] + bY[>64])/c. Utilizziamo R1 per contenere la dimensione del vettore. Utilizziamo R5 per contenere l’immediato costante 64. Utilizziamo R10 come indice per scorrere tra i vari sottovettori. Utilizziamo R2 per contenere l’indirizzo in memoria del primo elemento del vettore A. Utilizziamo R3 per contenere l’indirizzo in memoria del primo elemento del vettore B. Utilizziamo F0 per contenere lo scalare c. Utilizziamo F2 per contenere lo scalare a. Utilizziamo F4 per contenere lo scalare b.

loop:

ANDI DADDI MTC1 DSUB DMUL LV stallo MULVS.D LV stallo MULVS.D ADDV.D DIVVS.D SV DADDI MTC1 BGEZ stallo

R10, R1, #63 R5, R0, #64 VLR, R10 R10, R1, R10 R10, R10, #8 V1, R10(R2) V1, V1, F2 V2, R10(R3) V2, V2, F4 V2, V1, V2 V2, V2, F0 R10(R3), V2 R10, R10, #-512 VLR, R5 R10, loop

L’operazione MULVS.D V1, V1, F1 e MULVS.D V2, V2, F2 moltiplicano un vettore per uno scalare. L’operazione DIVVS.D V2, V2, F2 divide un vettore per uno scalare. Riordiniamo il programma per eliminare eventuali stalli. Non si sono considerati gli stalli dovuti alla fase EX delle unità floating point, quale moltiplicatore e divisore: il loro output sarà ottenuto solo dopo un numero di colpi di clock che varia in base alla latenza di tali unità, ed è quindi incalcolabile ad occhio quando questi provocheranno uno stallo.

loop:

ANDI DADDI MTC1 DSUB DMUL LV LV MULVS.D MULVS.D ADDV.D

CALCOLATORI ELETTRONICI A.A. 2009/2010

R10, R1, #63 R5, R0, #64 VLR, R10 R10, R1, R10 R10, R10, #8 V1, R10(R2) V2, R10(R3) V1, V1, F2 V2, V2, F4 V2, V1, V2 Pagina 60

Pietroleonardo Nicola Stroppa Fabio

Esercizi di Calcolatori Elettronici DIVVS.D SV DADDI BGEZ MTC1

A.A. 2009/2010

V2, V2, F0 R10(R3), V2 R10, R10, #-512 R10, loop VLR, R5

Un metodo alternativo per risolvere l’algoritmo con, probabilmente, meno colpi di clock è quello di dividere prima del loop sia a che b per c. Questo porterebbe essere vantaggioso se le latenze delle unità funzionali non sono unitarie, in quanto supponiamo sia 10 la latenza del divisore e 4 quella del moltiplicatore, l’operazione di divisione che dura 10 colpi di clock la si fa una volta all’inizio, e non la si ripete 64 volte nel loop per ogni elemento (considerando una sola corsia e una sola unità funzionale per corsia). Se fosse a latenza unitaria, sprecheremmo solo un colpo di clock nel loop contro i due fuori dal loop (perché contemporaneamente a queste 64 divisioni venivano svolte 63 moltiplicazioni – la prima moltiplicazione era svolta prima della prima divisione così come l’ultima divisione è svolta dopo l’ultima moltiplicazione – aggiungendo solo un colpo di clock alla fine), ma ripeterlo 64 volte per 10 colpi di clock dopo le 64 moltiplicazioni per 4 colpi di clock significa un aumento notevole dei colpi di clock per eseguire il programma!

loop:

ANDI DADDI MTC1 DSUB DMUL DIV.D DIV.D LV LV MULVS.D MULVS.D ADDV.D SV DADDI BGEZ MTC1

CALCOLATORI ELETTRONICI A.A. 2009/2010

R10, R1, #63 R5, R0, #64 VLR, R10 R10, R1, R10 R10, R10, #8 F2, F2, F0 F4, F4, F0 V1, R10(R2) V2, R10(R3) V1, V1, F2 V2, V2, F4 V2, V1, V2 R10(R3), V2 R10, R10, #-512 R10, loop VLR, R5

Pagina 61

Pietroleonardo Nicola Stroppa Fabio

Esercizi di Calcolatori Elettronici

A.A. 2009/2010

ESERCIZIO 5 – PRODOTTO SCALARE TRA VETTORI DI 64 ELEMENTI Prodotto scalare tra due vettori di 64 elementi con il metodo della riduzione a scalare. Si vuole realizzare una procedura che esegua c = A[64] x B[64]. Il prodotto scalare tra due vettori si realizza sommando i vari prodotti risultanti dalla moltiplicazione elemento per elemento: c = (A[0] x B[0]) + (A[1] x B[1]) + (A[2] x B[2]) + (A[3] x B[3]) + (A*4+ x B*4+) + (A*5+ x B*5+) + … Quindi per ottenere il risultato bisognerà innanzitutto moltiplicare i due vettori con l’operazione vettoriale MULV.D, successivamente dividere il vettore risultante in due sottovettori e sommarli. Tale divisione e somma dev’essere ripetuta fino a che non si giunge ad un unico elemento scalare che sarà poi il risultato finale (riduzione a scalare). Essendo i due vettori di dimensione 64 non vi sono problemi per quanto riguarda la moltiplicazione iniziale, e non vi è bisogno di alcun loop. Utilizziamo R1 per contenere la dimensione del vettore. Utilizziamo R2 per contenere l’indirizzo in memoria del primo elemento del vettore A. Utilizziamo R3 per contenere l’indirizzo in memoria del primo elemento del vettore B. Utilizziamo R4 per contenere l’immediato costante 1, per poi utilizzarlo come condizione di disuguaglianza nel branch. Utilizziamo R5 per contenere l’immediato costante 2, per poi fare la divisione a metà del vettore risultato della moltiplicazione (l’operazione DDIVI non esiste!). Utilizziamo R6 come indice per puntare alla seconda metà del sottovettore. DADDI MTC1 LV LV MULV.D SV

R1, R0, #64 VLR, R1 V1, 0(R2) V2, 0(R3) V1, V1, V2 0(R2), V1

Impostiamo le costanti 1 e 2: DADDI DADDI

R4, R0, #1 R5, R0, #2

Iniziamo il loop. Nel loop dovremo inizialmente dividere il vettore per due, e poi impostare un indice che punti al secondo sottovettore moltiplicando la dimensione dei due sottovettori (nella prima iterazione 64/2=32) per 8 byte. Poi si caricano i vettori, si sommano ed infine store. Ultima istruzione, branch, se il risultato della divisione è diverso da 1, allora ripeti il loop, se non lo è, hai finito. loop:

DDIV MTC1 DMULI LV LV ADDV.D

CALCOLATORI ELETTRONICI A.A. 2009/2010

R1, R1, R5 VLR, R1 R6, R1, #8 V1, 0(R2) V2, R6(R2) V1, V1, V2 Pagina 62

Pietroleonardo Nicola Stroppa Fabio

Esercizi di Calcolatori Elettronici SV BNE

A.A. 2009/2010

0(R2), V1 R1, R4, loop

Lo scalare c sarà salvato all’indirizzo di memoria R2, che inizialmente conteneva il primo elemento del vettore. Il listato completo è:

loop:

DADDI MTC1 LV LV stallo MULV.D SV DADDI DADDI DDIV MTC1 DMULI LV LV stallo ADDV.D SV BNE stallo

R1, R0, #64 VLR, R1 V1, 0(R2) V2, 0(R3) V1, V1, V2 0(R2), V1 R4, R0, #1 R5, R0, #2 R1, R1, R5 VLR, R1 R6, R1, #8 V1, 0(R2) V2, R6(R2) V1, V1, V2 0(R2), V1 R1, R4, loop

Riordiniamo il programma per eliminare eventuali stalli. Non si sono considerati gli stalli dovuti alla fase EX delle unità floating point, quale moltiplicatore e sommatore: il loro output sarà ottenuto solo dopo un numero di colpi di clock che varia in base alla latenza di tali unità, ed è quindi incalcolabile ad occhio quando questi provocheranno uno stallo.

loop:

DADDI R1, R0, #64 MTC1 VLR, R1 LV V1, 0(R2) LV V2, 0(R3) DADDI R4, R0, #1 MULV.D V1, V1, V2 SV 0(R2), V1 DADDI R5, R0, #2 DDIV R1, R1, R5 MTC1 VLR, R1 DMULI R6, R1, #8 LV V1, 0(R2) LV V2, R6(R2) stallo non eliminabile ADDV.D V1, V1, V2 BNE R1, R4, loop SV 0(R2), V1

CALCOLATORI ELETTRONICI A.A. 2009/2010

Pagina 63

Pietroleonardo Nicola Stroppa Fabio

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF