dispense calcolatori elettronici con esercizi

191

Upload: atish-andrea-rambaran

Post on 30-Jul-2015

530 views

Category:

Documents


10 download

TRANSCRIPT

Page 1: Dispense Calcolatori Elettronici Con Esercizi
Page 2: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 2

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

AAPPPPUUNNTTII DDII CCAALLCCOOLLAATTOORRII EELLEETTTTRROONNIICCII

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.

EEDDIITTOORR:: NNiiccoollaa PPiieettrroolleeoonnaarrddoo

PPRROODDUUZZIIOONNEE:: NNiiccoollaa PPiieettrroolleeoonnaarrddoo,, FFaabbiioo SSttrrooppppaa

GGRRAAFFIICCAA DDII CCOOPPEERRTTIINNAA:: FFaabbrriizziioo PP.. BBaallddiinnii -- hhttttpp::////wwwwww..bbaalldduuss..aalltteerrvviissttaa..oorrgg//

Page 3: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 3

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

IINNDDIICCEE GGEENNEERRAALLEE

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) – ACCESSO 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

Page 4: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 4

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 5: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 5

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 6: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 6

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 7: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 7

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

PARTE PRIMA

PARTE PRIMA

PROCESSORE SCALARE

ARCHITETTURA INTERA

Page 8: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 8

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 9: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 9

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

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 11111011

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.

56bit + 8bit = 64 bit

56bit + 8bit = 64 bit

Page 10: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 10

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

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;

ALU

UNITA’ DI CALCOLO FLOATING POINT

REGISTRI FLOATING POINT

REGISTRI GPR

Page 11: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 11

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 12: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 12

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 13: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 13

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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 Significato dell’istruzione

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 Carica un byte, carica un byte senza segno, memorizza un byte (da/in

registri per interi)

LH, LHU, SH Carica mezza parola, carica mezza parola senza segno, memorizza

mezza parola (da/in registri per interi)

LW, LWU, SW Carica una parola, carica una parola senza segno, memorizza una parola

(da/in registri per interi)

LD, SD Carica una doppia parola, memorizza una doppia parola (da/in registri

per interi)

L.S, L.D, S.S, S.D Carica un SP, carica un DP, memorizza un SP, memorizza un DP

MFC0, MTC0 Copia da/a un GPR a/da un registro speciale

MOV.S, MOV.D Copia da un registro in virgola mobile a singola o doppia precisione a un

altro registro dello stesso tipo

MFC1, MTC1 Copia da 32 bit in/da registri in virgola mobile da/in registri interi

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

DADD, DADDI, DADDU,

DADDIU

Addiziona, addiziona un valore immediato (tutti i valori immediati sono

a 16 bit); con segno e senza segno

DSUB, DSUBU Sottrai; con segno e senza segno

DMUL, DMULU, DDIV,

DDIVU, MADD

Moltiplica e dividi; con segno e senza segno; moltiplica-e-addiziona;

tutte le operazioni richiedono e producono valori a 64 bit

AND, ANDI Esegui AND, esegui AND con un dato immediato

OR, ORI, XOR, XORI Esegui OR, esegui OR con un dato immediato; esegui OR esclusivo,

esegui or esclusivo con un dato immediato

LUI 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

DSSL, DSRL, DSRA, DSLLV,

DSRLV, DSRAV

Scorri; sia in modo immediato (DS__) sia in forma variabile (DS__V); gli

scorrimenti sono logico verso sinistra, logico verso destra, aritmetico

verso destra

SLT, SLTI, SLTU, SLTIU Imposta un valore inferiore a, omposta un valore inferiore ad un valore

immediato; con segno e senza segno

Controllo:

Salti condizionati e non

condizionati; relativi al PC

o usando un registro

BEQZ, BNEZ Salta se un GPR è/non-è uguale a zero; scostamento di 16 bit da PC+4

BEQ,BNE Salta se i GPR sono/non-sono uguali; scostamento di 16 bit da PC+4

BGTZ, BLTZ Salta se un GPR è maggiore/minore a zero; scostamento di 16 bit da

PC+4

BGEZ, BLEZ Salta se un GPR è maggiore/minore o uguale a zero; scostamento di 16

bit da PC+4

BC1T,BC1F Verifica il bit di confronto nel registro di stato per le operazioni in

virgola mobile e salta; scostamento di 16 bit da PC+4

MOVN, MOVZ Copia un GPR in un altro GPR se il terzo GPR è negativo, se è zero

J, JR Salta incondizionatamente; scostamento di 26 bit da PC+4 (J) oppure

destinazione in un registro (JR)

TRAP Trasferisce il controllo al sistema operativo a un indirizzo vettorizzato

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

Page 14: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 14

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 15: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 15

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 16: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 16

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 17: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 17

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

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

Page 18: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 18

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 19: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 19

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 20: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 20

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 21: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 21

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 22: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 22

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ISTRUZIONE ALU GPR op IMM

ISTRUZIONE STORE

ISTRUZIONE BRANCH

Page 23: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 23

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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 NT, 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 NT, 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.

Page 24: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 24

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Quindi:

𝑇 + 𝑁 − 1 𝑇

𝑛𝑙= 𝑇 +

𝑁𝑇

𝑛𝑙−

𝑇

𝑛𝑙=

𝑛𝑙𝑇 + 𝑁𝑇 − 𝑇

𝑛𝑙=

𝑁𝑇

𝑛𝑙+ 𝑛𝑙 − 1 𝑇

𝑛𝑙

con 𝑛𝑙−1 𝑇

𝑛𝑙 parametro trascurabile;

Sul termine 𝑁𝑇

𝑛𝑙 è 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.

Page 25: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 25

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 26: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 26

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

pipeline, 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.

Page 27: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 27

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Di seguito sono riportati gli eventi di ciascuno stadio della pipeline di MIPS.

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.

IF/ID.NPC ← PC+4; IF/ID.PC ← (if ((EX/MEM.opcode == branch) || (EX/MEM.opcode == jump) & EX/MEM.cond)

{EX/MEM.ALUOutput} else {PC+4});

Se l’istruzione è una BEQZ allora:

EX/MEM.cond ← (if (ID/EX.A == 0) {1});

Se l’istruzione è una BNEZ allora:

EX/MEM.cond ← (if (ID/EX.A != 0) {1});

Bisogna considerare anche i casi in cui

l’istruzione è una BNQ o una BNE;

Page 28: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 28

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 29: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 29

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

BREVE CENNO SULLE MEMORIE DEL PROCESSORE (CACHE DI 1°LIVELLO) – ACCESSO ALLA MEMORIA Nel processore ci sono due memorie cache di 1° livello distinte perché si ha bisogno di un’unità su cui scrivere e leggere le istruzioni e un’unità su cui scrivere e leggere i dati; devono essere distinte per evitare un alea strutturale gravissima, che comporterebbe uno spreco di colpi di clock. Questo idea di organizzazione è definita come architettura Harvard. Successivamente affronteremo la trattazione della memoria; ora ci soffermiamo su un singolo aspetto che è quello dell’ACCESSO ALLA MEMORIA. La memoria è pensata in questa maniera: 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:

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.

PORTA INDIRIZZO PORTA DATI

PORTA D’INGRESSO PORTA DI USCITA

0 3 4 7 8 11

Page 30: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 30

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Ad esempio si supponga la seguente situazione di LOAD:

L O C U

La parola LOCU non potrà essere letta perché l’indirizzo non avrà gli ultimi due bit uguali a zero, ma solo l’ultimo. Per leggere la parola devo:

1. LOAD dei primi 4 byte; 2. LOAD dei successivi 4 byte; 3. SHIFT di 16 bit dei primi 4 byte; 4. SHIFT di 16 bit dei successivi 4 byte; 5. operazione di OR per ottenere la parola LOCU.

Si supponga ora la seguente situazione di STORE: Si vuole scrivere la parola LOCU a partire dall’indirizzo 15; non si deve però andare a modificare il contenuto degli altri indirizzi.

e R p L O C U h 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.

12 14 16

4 byte 4 byte

12 14 16

4 byte 4 byte

13 15 18 17

19

Page 31: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 31

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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; // Write R0

DSUB R2, R0, R3; // 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; // Write R1

. . .

DSUB R1, R2, R3; // 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; // Read R1

DSUB R1, R2, R3 // Write R1

Page 32: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 32

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 33: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 33

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 34: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 34

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 35: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 35

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 36: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 36

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 37: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 37

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

MIPS PIPELINE OTTIMIZZATO

Page 38: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 38

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 39: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 39

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 40: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 40

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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:

STATO 0: salto non verificato

STATO 1: salto verificato

Quando si è nello stato 0 vorrà dire che il salto non dovrà essere effettuato; se effettivamente la condizione

non si verifica si rimane nello stato 0, altrimenti si passa nello stato 1, in cui vale in maniera duale lo stesso

discorso.

È possibile migliorare questa tecnica se si considera anche la storia passata e non solo quello che è successo

l’ultima volta; in questa maniera è possibile costruire una macchina a quattro stati, cioè questo significa

avere nell’ultima colonna della tabella due bit di controllo anziché uno.

La seguente figura mostra la macchina a stati che permette di considerare la storia passata.

STATO 00: certezza assoluta di salto non verificato

STATO 01: predizione di salto non verificato

STATO 10: predizione di salto verificato

STATO 11: certezza assoluta di salto verificato

Quando si è nello stato 11 vorrà dire che il salto dovrà essere effettuato; se effettivamente il salto si verifica

si rimane sempre nello stesso stato, altrimenti si va nello stato 10, in cui si predice comunque la verifica del

salto in base al fatto che le ultime volte il salto si era verificato; quando si è in questo stato se

effettivamente il salto non si verifica bisognerà passare nello stato 00, altrimenti si ritorna nello stato 11.

Quando si è nello stato 00 vorrà dire che il salto non dovrà essere effettuato, e vale in maniera duale lo

stesso discorso.

0 1

NON ESEGUITO

NON ESEGUITO

ESEGUITO

ESEGUITO

Page 41: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 41

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Quindi utilizzando due bit anziché uno, un salto condizionato che privilegia la sua esecuzione o la sua non-

esecuzione (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:

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)

DADD R4,R4,R5

SD R3(0),R4

DADDI R1,R1,#8

DADDI R2,R2,#8

DADDI R3,R3,#8

DADDI R6,R6,#-1

BNEZ R6,-9

stallo

stallo

stallo

DADDI R6,R0,N

LD R4,R1(0)

LD R5,R2(0)

DADDI R1,R1,#8

DADD R4,R4,R5

SD R3(0),R4

DADDI R6,R6,#-1

DADDI R2,R2,#8

BNEZ R6,-8

DADDI R3,R3,#8

DIVENTA

DADDI R6,R0,N

LD R4,R1(0)

LD R5,R2(0)

DADD R4,R4,R5

SD R3(0),R4

DADDI R1,R1,#8

DADDI R2,R2,#8

DADDI R3,R3,#8

DADDI R6,R6,#-1

BNEZ R6,-9

stallo

stallo

stallo

Istruzioni necessarie

Istruzioni di gestione

R1 punta al vettore A

R2 punta al vettore B ⇒ C[i] = A[i] + B[i]

R3 punta al vettore C

Page 42: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 42

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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) //utilizzo un altro registro

LD R6,R1(1992) //utilizzo un altro registro

DADD R2,R2,R3

DADD R5,R5,R6

SD (3000)R1,R2

SD (2992)R1,R5

DADDI R1,R1,#-16

BNEZ R1,-10

Page 43: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 43

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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;

Page 44: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 44

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 45: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 45

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 46: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 46

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

EX/MEM.ALUOUTPUT2 ← EX/MEM.ALUOUTPUT + 4

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

FASE MEM2

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

1* SEMICICLO

2* SEMICICLO

Page 47: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 47

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Con questa scrittura, questa istruzione prevedrebbe 5 fasi, sebbene la presenza di MEM2 causerebbe uno

stallo alle istruzioni successive, qualora l'istruzione I immediatamente seguente ad essa faccia

effettivamente riferimento a memoria durante la sua fase MEM:

(SD): IF ID EX MEM1 MEM2

(I): IF ID EXE Stallo MEM WB

Quindi se l’istruzione I è una istruzione di load o di store ci sarà uno stallo al momento della sua fase MEM.

Si noti però che nel primo semiciclo della fase MEM1 oltre ad accedere alla memoria, si sta utilizzando

l’ALU per calcolare il nuovo indirizzo; per cui l’istruzione I avrebbe anche la sua fase EXE in stallo. Per cui lo

stallo andrebbe messo prima della fase EXE, quindi non si avrà poi lo stallo per la fase MEM, cioè la

situazione diventerebbe la seguente:

(SD): IF ID EX MEM1 MEM2

(I): IF ID Stallo EXE MEM WB

Nel secondo caso lo stallo si avrebbe sempre e comunque, perché tutte le istruzioni fanno uso dell’ALU;

mentre nel primo caso, con un opportuna modifica, lo stallo si avrebbe solo se l’istruzione I effettivamente

fa riferimento alla memoria.

Per risolvere il conflitto fra MEM1 e la fase EXE dell’istruzione I bisogna pensare di modificare parte

dell’hardware del processore; poiché MEM1, oltre all’accesso alla memoria, non fa altro che una somma

per il calcolo dell’indirizzo successivo, allora è possibile aggiungere un sommatore nella fase MEM, il quale

ha il compito di determinare il nuovo indirizzo in modo tale che non venga occupata e utilizzata l’ALU. Il

processore eseguirà così in parallelo la fase MEM1 e la fase EXE2; la modifica da apportare e quindi la

seguente:

EX/MEM.ALUOUTPUT va in ingresso

alla Data memory e ad un sommatore

predisposto per calcolare il secondo

indirizzo; quest’ultimo dovrà essere

scritto in EX/MEM.ALUOUTPUT2 e

non in EX/MEM.ALUOUTPUT perché

è usato dall’istruzione che in quel

momento è nella fase EX e che quindi

sta usando l’ALU e il suo risultato

andrà in EX/MEM.ALUOUTPUT.

Page 48: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 48

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 49: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 49

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

FASE EXE (if (COND2) µPc ← MM[gestione interrupt stack underflow]);

EX/MEM.SP ← ID/EX.SP - 4;

FASE MEM MEM/WB.LMD ← Mem[EX/MEM.SP];

FASE WB Regs[MEM/WB.IR[Rb] ← MEM/WB.LMD; // con Rb registro ricevente il dato prelevato dallo stack

In una pipeline vista a 5 stadi sembra quindi che il miglior modo di operare con uno stack e quello con SP

puntatore al primo vuoto.

Questo esercizio richiedeva di analizzare il caso di un’istruzione POP; vediamo ora come si complicano le

cose nel caso d’istruzione PUSH.

Se SP è sempre puntatore al primo vuoto l’operazione da effettuare per prima è quella di scrittura nello

Stack e poi di aggiornamento con incremento di SP; questo significa utilizzare l’ALU dopo la fase MEM e di

conseguenza un peggioramento di prestazioni. Allora può sembrare non conveniente avere SP puntatore al

primo vuoto, ma meglio averlo puntatore all’ultimo pieno, in maniera tale da incrementare SP e poi

accedere alla memoria per scrivere.

Per cui bisogna decidere una tecnica che vada bene per un caso e trovare una soluzione per evitare stalli

nell’altro caso; questo è possibile inserendo, come nell’esercizio precedente, un sommatore nella fase

MEM che effettui l’aggiornamento di SP.

Bisogna però prestare attenzione, poiché stiamo considerando comunque un’architettura pipeline, ai casi

in cui si presentano più istruzioni PUSH o POP contemporaneamente, ad esempio:

1°CASO: istruzione POP seguita da un’istruzione POP

prima istr: POP IF ID EX MEM WB

seconda istr: POP IF ID EX MEM WB

Questa situazione non presenta alcun tipo di problema poiché nel momento in cui la seconda istruzione

effettua la sua fase EX il valore SP sarà già stato aggiornato per cui tutto procede senza problemi.

2°CASO: istruzione PUSH seguita da un’istruzione PUSH

prima istr: PUSH IF ID EX MEM WB

seconda istr: PUSH IF ID EX MEM WB

Questa situazione non presenta alcun tipo di problema poiché nel momento in cui la seconda istruzione

effettua la sua fase EX il valore SP sarà già stato aggiornato dal sommatore, presente nella fase MEM della

prima istruzione, per cui tutto procede senza problemi.

3°CASO: istruzione POP seguita da un’istruzione PUSH

prima istr: POP IF ID EX MEM WB

seconda istr: PUSH IF ID EX MEM WB

Page 50: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 50

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Questa situazione non presenta alcun tipo di problema poiché nel momento in cui la seconda istruzione

effettua la sua fase EX il valore SP sarà già stato aggiornato per cui tutto procede senza problemi.

4°CASO: istruzione PUSH seguita da un’istruzione POP

prima istr: PUSH IF ID EX MEM WB

seconda istr: POP IF ID stallo EX MEM WB

Questa situazione presenta un stallo della fase EX dell’istruzione POP; questo problema è dovuto al fatto

che soltanto al termine della fase MEM dell’istruzione PUSH il sommatore aggiornerà SP, per cui non potrà

essere eseguita contemporaneamente la fase EX dell’istruzione POP poiché SP non è ancora aggiornato.

Per evitare questo stallo è possibile pensare di eseguire l’aggiornamento di SP direttamente nella fase EX

dell’istruzione PUSH; vediamo in dettaglio cosa si dovrebbe fare:

Nella fase EX passiamo SP al latch EX/MEM e tramite l’ALU (quindi non serve più il sommatore)

l’aggiorniamo e lo passiamo al latch ID/EX; per cui in microcodice si ha:

FASE EXE

EX/MEM.SP ← ID/EX.SP

ID/EX.SP ← ID/EX.SP + 4

In questo modo al termine della fase EXE il valore di SP risulterà aggiornato, per cui l’istruzione POP

successiva non dovrà più stallare poiché ora il dato sarà disponibile.

prima istr: PUSH IF ID EX MEM WB

seconda istr: POP IF ID EX MEM WB

Page 51: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 51

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 52: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 52

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

FASE EXE2 (comprende la fase MEM1) MEM/WB.IR ← EX/MEM.IR

MEM/WB.ALUOUTPUT ← EX/MEM.ALUOUTPUT

EX/MEM.ALUOUTPUT ← ID/EX.A + ID/EX.B + PSW[c]

Sfruttando una suddivisione in semicicli, EX/MEM.ALUOUTPUT è letta nel primo semiciclo, scritta nel secondo.

FASE WB1 (comprende la fase MEM2)

Regs[MEM/WB.IR[rd]] ← MEM/WB.ALUOUTPUT

MEM/WB.ALUOUTPUT ← EX/MEM.ALUOUTPUT

Sfruttando una suddivisione in semicicli, MEM/WB.ALUOUTPUT è letta nel primo semiciclo, scritta nel secondo.

FASE WB2

Regs[MEM/WB.IR[rd']] ← MEM/WB.ALUOUTPUT

µPC ← 0

Pensata così l’istruzione termina in sei fasi; analizziamo ora i conflitti che potrebbe generare:

prima istr: ADDL IF ID EX1 EX2 WB1 WB2

seconda istr: qualsiasi IF ID EX MEM WB

per la seconda istruzione vi è uno stallo nel momento in cui vi è la fase EX (avviene in contemporanea con la

EX2) e nel momento della fase ID poiché provoca incoerenza in quanto EX1 sta scrivendo nei registri A e B e

a lo stesso sta facendo ID. Per cui inserendo lo stallo prima della fase ID si ottiene:

prima istr: ADDL IF ID EX1 EX2 WB1(MEM1) WB2(MEM2)

seconda istr: qualsiasi IF stallo ID EX MEM WB

È possibile migliorare la situazione considerando che se le operazioni in doppia precisione fossero molto

frequenti, potremmo pensare di utilizzare dei latch A, B, ALUOUTPUT capaci di contenere 64 bit, invece di

32, evitando la seconda fase di prelievo degli operandi (nella fase EX1) che obbligano di fatto ad uno stallo

l'istruzione successiva, in quanto ne impediscono l'ID.

Comunque l’ALU continuerebbe a processare gli operandi in due tempi ciascuno da 32 bit: avremmo

comunque la necessità di avere due fasi di EXE (e conseguente stallo delle istruzioni successive in conflitto

strutturale sull'ALU, risolvibile inserendo un sommatore nella fase EX2 in modo tale da non usare l’ALU). In

questo modo bisognerà potenziare la C.U. e aggiungere hardware; non si ottiene quindi nessun

miglioramento per cui conviene avere un’ALU a 64 bit.

In maniera analoga a quanto appena visto vale per l’ipotetica istruzione SUBL, considerando il bit di borrow

(riporto) della PSW invece del bit di carry.

Page 53: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 53

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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 ID EX MEM WB

seconda istr: LW R1,0(R6) IF ID EX MEM WB

Ci sarà bisogno di uno stallo poiché la seconda LW deve calcolare R6 + 0 per avere l’indirizzo, e quindi la EX

della seconda istruzione deve stallare; ma poiché essendo zero il secondo addendo della somma, allora con

una corto-circuitazione della memoria, in cui l’uscita della memoria va alla porta indirizzo della memoria

stessa, si evita lo stallo. Questa operazione vale solamente in questo caso, poiché la seconda load deve

effettuare una somma con zero. Quindi bisognerà modificare la C.U.

Per cui con questi accorgimenti non si hanno stalli e l’istruzione successiva terminerebbe al colpo di clock 6.

Quindi per ottimizzare il microcodice di questa istruzione, che prevede un doppio accesso a memoria,

supponiamo nella architettura MIPS, un collegamento dall'uscita dati della memoria al registro

EX/MEM.ALUOUTPUT. In tal caso, il microcodice, potrebbe essere:

FASE IF

IF/ID.IR ← Mem[PC]

IF/ID.NPC ← PC + 4

FASE ID ID/EX.A ← Regs[IF/ID.IR[rs]]

ID/EX.B ← Regs[IF/ID.IR[rt]]

ID/EX.IR ← IF/ID.IR

ID/EX.NPC ← IF/ID.NPC

ID/EX.Imm ← sign-extend(IF/ID.IR[immediate field])

µPC ← MM[IF/ID.IR[opcode]]

FASE EX EX/MEM.ALUOUTPUT ← ID/EX.A + ID/EX.Imm

EX/MEM.IR ← ID/EX.IR

FASE MEM1 EX/MEM.ALUOUTPUT ← Mem[EX/MEM.ALUOUTPUT]

MEM/WB.IR ← EX/MEM.IR

FASE MEM2

Page 54: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 54

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

MEM/WB.LMD ← Mem[EX/MEM.ALUOUTPUT]

FASE WB Regs[MEM/WB.IR[rd]] ← MEM/WB.LMD

Pensata così l’istruzione termina in sei fasi; analizziamo ora i conflitti che potrebbe generare:

prima istr: LW IF ID EX MEM1 MEM2 WB

seconda istr: qualsiasi IF ID EX MEM WB

La fase di MEM2 della prima istruzione provoca un problema con la fase MEM della seconda istruzione solo

se quest’ultima è un’istruzione di load o di store, altrimenti la fase MEM è una sola fase di passaggio. Per

cui si potrebbe far precedere l’istruzione LW solo da istruzioni che non effettuano load o store.

Il vero problema sorge nel momento in cui la seconda istruzione entra in fase di WB; questo problema è

semplicemente risolvibile potenziando il canale che porta i dati nei registri.

Page 55: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 55

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESERCIZIO 5 Progettare un microprogramma in linguaggio RTL da associare ad una istruzione:

RTI (return from interrupt)

per una macchina MIPS nei due casi:

- salvataggio del PC in un registro IAR (Interrupt address return)

- salvataggio del PC in uno stack, facendo ipotesi su come è gestito lo stack.

Per semplicità si trascuri il ripristino dei registri e della parola di stato.

L’istruzione RTI permette di ritornare alla normale esecuzione di un programma dopo che è stata servita

l’interruzione. Il microprogramma ad essa associato può essere:

FASE IF

IF/ID.IR ← Mem[PC]

IF/ID.NPC ← PC + 4

FASE ID ID/EX.A ← Regs[IF/ID.IR[rs]]

ID/EX.B ← Regs[IF/ID.IR[rt]]

ID/EX.IR ← IF/ID.IR

ID/EX.NPC ← IF/ID.NPC

ID/EX.Imm ← sign-extend(IF/ID.IR[immediate field])

µPC ← MM[IF/ID.IR[opcode]]

Consideriamo prima il caso in cui il PC sia stato salvato nell’IAR, quindi nei casi di interrupt mascherati, cioè

nei casi in cui l’interrupt non viene interrotto, in maniera tale da non perdere il PC.

FASE EXE

EX/MEM.ALUOUTPUT ← IAR

FASE MEM

MEM/WB.ALUOUTPUT ← EX/MEM.ALUOUTPUT

FASE WB

PC ← MEM/WB.ALUOUTPUT

µPC ← 0

L’IAR viene caricato nel PC per ripristinare il valore del PC quando c’è stata l’interruzione e viene resettato il

µPC a 0 per fare il fetch della successiva istruzione.

Anche se l’istruzione porta via cinque fasi provocherebbe comunque degli stalli per le prossime istruzioni,

perché il fetch non potrà essere effettuato in quanto il PC sarà disponibile solo dopo la fase di WB. Per cui

se si gestisce così l’istruzione si avrebbe una situazione del genere:

prima istr: RTI IF ID EX MEM WB

seconda istr: (istr. con PC corretto) IF stallo stallo stallo IF ID EX MEM WB

Page 56: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 56

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Per cui è necessario effettuare il WB il prima possibile; questo si può ottenere cortocircuitando

direttamente IAR con il PC consentendo di ridurre ad uno solo gli stalli (nella fase di EXE si avrebbe

direttamente PC ← IAR). Per cui si ottiene:

prima istr: RTI IF ID EX MEM WB

seconda istr: (istr. con PC corretto) IF stallo IF ID EX MEM WB

Un ulteriore miglioramento potrebbe essere ottenuto a livello di scheduling, inserendo dopo l'istruzione RTI

le ultime due istruzioni di procedura di gestione dell’interrupt, in maniera tale da non sprecare colpi di

clock; si ottiene così questa situazione:

prima istr: RTI IF ID EX MEM WB

seconda istr: istr N-2 IF ID EX MEM WB

terza istr: istr N-1 IF ID EX MEM WB

quarta istr: (istr. con PC corretto) IF ID EX MEM WB

dove:

N-2 è la terz’ultima istruzione di gestione dell’interrupt;

N-1 è la penultima istruzione di gestione dell’interrupt

Vediamo ora il caso in cui il PC venga salvato nello STACK, quindi nei casi di interrupt non mascherabili, cioè

nei casi in cui l’interrupt può essere interrotto, e il valore del PC non viene perso poiché viene salvato nello

stack; al momento del termine delle procedure di gestione degli interrupt, si procede con il prelievo dallo

stack dei rispettivi PC.

Si suppone che lo STACK risieda in memoria per indirizzi crescenti e che lo Stack Pointer punti all’ultima

locazione piena.

Page 57: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 57

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 58: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 58

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 59: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 59

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 60: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 60

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

FASE MEM:

LMDR ← Mem[MAR]

FASE EXE/WB:

ACC ← LMDR+0

µPC ← 0

FASE MEM:

LMDR ← Mem[MAR]

FASE EXE/WB:

ACC ← LMDR op ACC

µPC ← 0

FASE MEM:

Mem[MAR] ← ACC

µPC ← 0

FASE SETPC:

if COND:

PC ← MAR (via ALU)

µPC ← 0

INT (da sistema) RTI JSUB RET (from subroutine)

FASE STPC:

IAR ← PC

FASE SETPC:

PC ← MAR (via ALU)

µPC ← 0

FASE SETPC:

PC ← IAR

µPC ← 0

FASE STPC:

SAR ← PC

FASE SETPC:

PC ← MAR (via ALU)

µPC ← 0

FASE SETPC:

PC ← SAR

µPC ← 0

Dove:

MEM è la fase di accesso alla memoria;

EXE/WB è la fase di calcolo effettivo e di aggiornamento dell'Accumulatore;

STPC (Store PC) è la fase in cui viene memorizzato il PC prima di gestire un interrupt o saltare ad una

subroutine;

SETPC è la fase di impostazione (o ripristino istruzioni di return) del PC.

La sua codifica in RTL si ottiene banalmente trascrivendo in sequenza opportunamente le microistruzioni

relative alle fasi come definito nella prima parte dell'esercizio rispettivamente per una Load, per una

operazione ALU (somma) e per una Store.

Page 61: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 61

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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 (op == +)

µPC ← 0

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

Page 62: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 62

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

PARTE SECONDA

PARTE SECONDA

MEMORIE CACHE

Page 63: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 63

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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:

MECCANISMO A FINESTRA DEI REGISTRI L’ideale sarebbe avere una CPU con molti

registri, veloci e convenienti; ma mettere a

disposizione un numero elevato di registri

all’interno del processore non sarebbe

conveniente, poiché in realtà questo porterebbe

a reperire informazioni in maggior tempo.

Infatti si riesce ad accedere in maniera diretta e veloce ai registri, proprio se questi sono in numero limitato;

inoltre poiché ogni registro ha un nome identificativo univoco, nel caso in cui si vuole avere un numero

molto più ampio di registri bisognerebbe puntare ad un registro specificando un numero di bit molto più

grande e questo significherebbe avere un’istruzione con tre operandi, ciascuno dei quali con un elevato

numero di bit; quindi l’istruzione avrebbe un numero troppo grande per individuare solo i registri. In seguito

ci si accorgerà che quando nel processore si inserisce una memoria cache, in pratica, si riesce a

implementare la logica a più registri attraverso il meccanismo a finestra; il progettista può decidere di

inserire nel processore più di 32 o 64 registri, ma dando la visibilità alla CPU solo ad un numero ristretto di

registri. Questo meccanismo è utile nei casi in cui vi è una chiamata alla procedura di gestione di un

interrupt; la procedura potrebbe utilizzare i registri per scriverci delle informazioni necessarie all’esecuzione.

Il meccanismo permette di far puntare la CPU ad altri registri, in maniera tale da non far sovrascrivere i dati

e inoltre questo meccanismo permette di non effettuare, o comunque limitare, il salvataggio dei registri

nello stack (è richiesto solo il salvataggio di PC e del PSW e di un codice che identifica di quanto è stata

spostata la finestra).

PRINCIPI FONDAMENTALI DELLA GERARCHIA DI MEMORIA

TRASPERENZA DEI LIVELLI: ogni livello intermedio della gerarchia è “trasparente” al processore e

“simula” il processore per il livello immediatamente inferiore, mentre “simula” la memoria per il

livello immediatamente superiore. Per comprendere meglio questo concetto, si consideri questo

esempio:

supponiamo che la memoria centrale chiede dei dati ai dischi;

dal punto di vista dei dischi è come se fosse il processore a richiedere i dati, quindi la memoria per il

livello sottostante simula il processore;

la cache (livello immediatamente superiore) è vista come processore dalla memoria, ma

quest’ultima simula la memoria per la cache.

Per cui, dal punto di vista del processore tutto ciò che sta sotto è memoria.

Co

sto/b

yte

1° LIVELLO

2° LIVELLO

MEMORIA CENTRALE

Page 64: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 64

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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)

Page 65: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 65

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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 1

0

1

1

1

2

1

3

1

4

1

5

1

6

1

7

2

0

2

1

2

2

2

3

2

4

2

5

2

6

2

7

3

0

3

1

3

2

3

3

3

4

3

5

3

6

3

7

Page 66: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 66

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 67: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 67

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 68: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 68

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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 / 3 2 1 0 0 2 3 1

LINEA CANDIDATA LRU 0 0 0 0 3 3 3 1 0

Page 69: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 69

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

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:

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

LINEA

3

LINEA

1

LINEA

2

LINEA

5

LINEA

4

LINEA

3

LINEA

1

LINEA

2

LINEA

5 Linea 4

Blocco che verrà sostituito

(la tabella riporta il numero di fallimenti per 1000 istruzioni)

Page 70: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 70

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

STRATEGIE DI SCRITTURA NELLA CACHE

Innanzitutto bisogna dire che le letture dominano gli accessi alla cache. Tutti gli accessi per le istruzioni

sono letture, inoltre molte istruzioni non scrivono in memoria. Sembrerebbe quindi che ottimizzando le

operazioni di lettura si migliorerebbero le prestazioni della cache. Ciò è vero solo parzialmente. La legge di

Amdahl stabilisce infatti che progetti mirati a ottenere alte prestazioni non possono trascurare le

operazioni di scrittura.

L’operazione più frequente, cioè la lettura di una linea, può essere resa facilmente più veloce effettuandola

contemporaneamente alle operazioni di lettura e verifica dell’etichetta. Perciò la lettura della linea, può

iniziare non appena il suo indirizzo è disponibile. Se l’accesso riesce, allora la linea viene passata subito alla

CPU. Se invece fallisce non c’è alcun beneficio, ma neppure un danno.

Questo non succede per le operazioni di scrittura. Il processore specifica la dimensione del dato da scrivere;

solo una particolare parte della linea può essere modificata.

In generale ciò significa che sulla linea viene eseguita una sequenza leggi –> modifica –> scrivi: viene letta la

linea originale, ne viene modificata una parte e, infine, viene scritta la linea con il nuovo valore.

Oltretutto, la modifica della linea non può iniziare finché l’etichetta non è stata controllata per verificare la

riuscita dell’accesso. Poiché la valutazione dell’etichetta non può avvenire in parallelo, le operazioni di

scrittura richiedono più tempo di quelle di lettura.

Perciò è la politica di scrittura che distingue molti progetti di memorie cache.

Le strategie di scrittura più tipiche sono due:

1. WRITE THROUGH: l’informazione viene scritta sia nel blocco della cache, sia

nel blocco del livello inferiore della memoria. Nel caso di politica write

through, lo stato in cui si trova la CPU che aspetta il termine di

un’operazione di scrittura prende il nome di stallo di scrittura (write stall), in

effetti l’operazione di scrittura avviene alla velocità della memoria centrale.

Un’ottimizzazione utilizzata di solito per ridurre il tempo di stallo consiste

nell’inserimento di un buffer di scrittura che consente al processore di

proseguire mentre la memoria viene modificata. Questo buffer è costituito nella seguente maniera:

essendo un buffer è organizzato da un insieme di celle in coda; vi è lo spazio non solo per contenere i

dati ma anche, per ogni cella, un’etichetta che indica in quale indirizzo della memoria il dato deve

essere scritto. Inoltre nell’etichetta vi è anche una sorta di bit di validità, il quale assicura che se nel

buffer vi è un dato ripetuto ma modificato, viene invalidato quello che deve ancora uscire; in questa

maniera il processo di scrittura in memoria centrale è velocizzato.

Comunque, uno stallo di scrittura è possibile anche in presenza di un buffer di scrittura, poiché esso è di

dimensioni limitate.

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.

I vantaggi della strategia WT sono: semplice implementazione; cache sempre clean; il livello gerarchico

inferiore dispone della copia più recente dei dati.

CPU

CACHE

MEMORIA CENTRALE I/O

CPU

CACHE

MEMORIA CENTRALE I/O

Page 71: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 71

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

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

Circuito di una cella di memoria DRAM.

Page 72: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 72

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

= 𝑳𝑬𝑻𝑻𝑼𝑹𝑬 𝑰𝑵 𝑴𝑬𝑴𝑶𝑹𝑰𝑨

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

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

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

Page 73: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 73

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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:

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:

Pollution Point

x

Dimensione del blocco da considerare: arrotondare alla potenza di 2 più vicina

Page 74: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 74

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

ASSOCIATIVITA’ DIMENSIONE BLOCCHI POLITICA LRU BUFFER DI SCRITTURA

VANTAGGI

- Minor numero di

conflitti

- Benefici in cache di

medie dimensioni

- Minor numero di

etichette

- Minor Miss Rate per

cache a bassa

associatività

- Minor stallo di scrittura

SVANTAGGI

- Maggiori costi:

ampiezza delle

etichette e

aggiunta di

comparatori

- Politica di

sostituzione più

costosa

- Maggior tempo di

trasferimento

- Maggior costo

hardware

- Maggior costo

hardware

aumentando

Page 75: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 75

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

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

32 bit

Page 76: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 76

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 77: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 77

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

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

32 bit

Page 78: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 78

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

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.

CPU 1 CPU 2 CPU 3

CACHE CACHE CACHE

MEM. CENTRALE I/O

Page 79: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 79

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Una tecnica meno semplice è quella dei Banchi Interlacciati: questa tecnica permette di ridurre il tempo. Consideriamo ad esempio sempre i 4 moduli distinti i quali in un certo tempo in uscita hanno 32 bit (per cui

ogni modulo può essere pensato come un insieme dei banchi multipli di memoria visti in precedenza). Ogni

modulo è di 1 Kbyte, per cui ricevono un indirizzo di 10 bit; dovendo tirare fuori 32 bit (parole di 4 byte) dei

10 bit che ne ricevono i due meno significativi sono uguali a zero.

L’indirizzo che arriva all’intera memoria è un’indirizzo di 12 bit, di cui i due meno significativi sono uguali a

zero; i 10 bit rimanenti, a loro volto sono suddivisi in 2 bit meno significativi e 8 bit più significativi.

La word non sarà suddivisa nei vari moduli, ma sarà messa per intera in un modulo. Per cui ogni modulo

conterrà word intere, con questa logica:

MODULO 1 MODULO 2 MODULO 3 MODULO 4

Ind. 0 WORD 0 WORD 1 WORD 2 WORD 3

Ind. 1 WORD 4 WORD 5 WORD 6 WORD 7

Ind. 2 WORD 8 WORD 9 WORD 10 WORD 11

Per cui in ingresso ad ogni modulo si hanno gli 8 bit più significativi dei 12 più 2 bit uguali a zero.

4 Kbyte

1Kbyte

1Kbyte

1Kbyte

1Kbyte

32 bit

8 bit 8 bit 8 bit 8 bit

12 bit

Page 80: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 80

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

8 bit 00

Poi i 32 bit uscenti da ogni singolo modulo vanno in un MUX che userà i 2 bit meno significativi dei 12 come

selettore per decidere quale indirizzo da 32 bit deve passare.

I 10 bit in ingresso ai moduli andranno a cercare la parola richiesta, la quale andrà poi in ingresso al MUX

per la selezione: ad esempio se i 10 bit richiedono la word che si trova all’indirizzo 2, i moduli daranno in

uscita rispettivamente:

MODULO 1 word 8;

MODULO 2 word 9;

MODULO 3 word 10;

MODULO 4 word 11;

Queste word andranno in ingresso al MUX che ne selezionerà una grazie ai 2 bit di selezione;

la figura che riassume la tecnica dei moduli interlacciati è la seguente.

8 bit 2 bit 00

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.

4 Kbyte

1Kbyte

1Kbyte

1Kbyte

1Kbyte

32 bit 32 bit 32 bit 32 bit

32 bit

12 bit

8 bit 00

8 bit 00

8 bit 00

Page 81: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 81

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 82: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 82

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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)

ETICHETTA SET SPIAZZAMENTO

xxx xxxx yyy yyyy yyyy 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.

(x, y, z indicano dei bit di valore non specificato).

INDIRIZZO (32 bit)

ETICHETTA SET SPIAZZAMENTO

xx xxxx xxxx xxxx xxxx xxxx yy zzzz zz00

Page 83: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 83

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

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

(x, y, z indicano dei bit di valore non specificato).

INDIRIZZO (32 bit)

ETICHETTA LINEA SPIAZZAMENTO

xx xxxx xxxx xxxx xxxx yyy yyyy zzz zz00

INDIRIZZO (32 bit)

ETICHETTA SPIAZZAMENTO

xxxx xxxx xxxx xxxx zzzz zzzz zzzz zz00

Page 84: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 84

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

PARTE TERZA

PARTE TERZA

PROCESSORE SCALARE

ARCHITETTURA FLOATING POINT

Page 85: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 85

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 86: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 86

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 87: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 87

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Tipo di istruzione/codice

operativo Significato dell’istruzione

Virgola mobile:

operazioni in virgola

mobile in formato SP e DP

ADD.D, ADD.S, ADD.PS Addiziona numeri in DP, in SP e coppie di numeri in SP

SUB.D, SUB.S, SUB.PS Sottrai numeri in DP, in SP e coppie di numeri in SP

MUL.D, MUL.S, MUL.PS Moltiplica numeri in DP, in SP e coppie di numeri in SP

MADD.D, MADD.S, MADD.PS Moltiplica e addiziona numeri in DP, in SP e coppie di numeri in SP

DIV.D, DIV.S, DIV.PS Dividi numeri in DP, in SP e coppie di numeri in SP

CVT._._

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.

C.__.D, C.__.S 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

MFC1, MTC1 Copia da 32 bit in/da registri in virgola mobile da/in registri interi

Page 88: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 88

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

SCHEDULING DELLE ISTRUZIONI FLOATING POINT Le unità di calcolo floating point hanno una latenza che non è simile indipendentemente dalle operazioni; la

differenza, in termini di colpi di clock, fra una operazione ad aritmetica intera e una in floating point

comincia ad essere significativa. Una scelta semplice sarebbe quella di dimensionare il clock in base

all’operazione che richiede più tempo, facendo sì che dilatando la latenza sia possibile effettuare tutte le

operazioni; però questo determina uno spreco di tempo soprattutto nei casi in cui un programma fa uso

solo ed esclusivamente dell’unità in aritmetica intera, poiché queste operazioni dovranno durare quanto la

più lunga operazione in floating point. Allora non si dilata il clock ma si garantisce all’unità floating point un

certo numero di colpi di clock per le operazioni da effettuare, consentendo di eseguire velocemente le

istruzioni che non fanno uso delle unità floating point.

Il problema che si viene a creare è che questi tempi portano inevitabilmente a degli stalli e conflitti

precedentemente analizzati; ad esempio una operazione di divisione in aritmetica floating point seguita da

una operazione di load, le quali utilizzano uno stesso registro destinazione, terminerebbe dopo

quest’ultima, generando evidentemente un conflitto di tipo WAW.

DDIV.D F4 … …

LOAD F4 … …

Per cui queste tipo di problematiche portano a realizzare unità di calcolo più sofisticate in modo tale da

diminuire il tempo sprecato dovuto alla dilatazione del clock.

Si utilizza l'algoritmo di Tomasulo, algoritmo sviluppato dal ricercatore dell'IBM Robert Tomasulo per

permettere l'esecuzione fuori ordine delle istruzioni. La sua prima implementazione si è avuta nell'unità in

virgola mobile del IBM 360/91. Questo algoritmo si differenzia dallo scoreboarding per l'utilizzo della

rinominazione dei registri. Mentre lo scoreboarding risolve le Write-after-Write (WAW) e le Write-after-

Read (WAR) con gli stalli, l'algoritmo di Tomasulo permette l'esecuzione di altre istruzioni. Inoltre

l'algoritmo di Tomasulo prevede un bus comune per fornire i valori calcolati a tutte le reservation station.

L'algoritmo migliora l'esecuzione parallela delle istruzioni e fornisce prestazioni migliori dello

scoreboarding.

Lo scheduling delle istruzioni dovrà prevedere alcune variazioni:

1. FASE DI DECODIFICA: bisogna fare attenzione affinché non vi siano conflitti di dato effettivi, per cui

la fase di decodifica viene scissa in due stadi ben distinti:

1. ISSUE: fase in cui l’istruzione viene decodificata controllando che non vi

siano azzardi strutturali, etichettata come istruzione floating point e

inserita in una coda d’istruzioni floating point, una coda flessibile la quale

permette di non stallare in caso di conflitti di struttura, in cui le unità di

calcolo sono occupate; le istruzioni possono essere anticipate rispetto ad

altre se hanno la relativa unità di calcolo disponibile.

2. READ OPERANDI: fase che legge gli operandi, dopo aver verificato che non

vi siano conflitti di dato, in maniera tale che gli operandi siano messi in

ingresso alle unità senza generare conflitti.

2. FASE DI ESECUZIONE: esecuzione delle istruzioni in base allo scheduling previsto dall’algoritmo di

Tomasulo.

3. SCRITTURA DEI RISULTATI: i risultati, attraversi un bus comune, vengono scritti nel banco dei

registri e in quelle unità di calcolo che eventualmente aspettano un risultato per svolgere la propria

operazione.

Page 89: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 89

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

1. BUSY: campo di un bit che indica se la stazione di prenotazione è disponibile.

2. OP: campo che indica l’operazione che dovrà essere eseguita.

3. Vj: campo che indica dove è contenuto il valore del primo registro sorgente.

4. Vk: campo che indica dove è contenuto il valore del secondo registro sorgente.

5. Qj: campo che indica se il primo registro sorgente è disponibile o meno; assume valore zero quando

è disponibile; valori diversi da zero per indicare l’unità che sta utilizzando il registro.

6. Qk: campo identico a Qj ma si riferisce al secondo registro sorgente.

7. A: campo che contiene l’indirizzo sorgente/destinazione per le operazioni di load/store.

È importante sottolineare che le stazioni di prenotazione per le unità di load conterranno solo i campi Busy,

Op ed A, poiché il primo operando dell’istruzione è un registro destinazione, il cui valore verrà

eventualmente prelevato dal CDB; mentre le stazioni di prenotazione per le unità di store conterranno i

campi Busy, Op, Vj, Qj, A, poiché l’operando dell’istruzione è un registro sorgente e va per tanto

monitorato.

BUSY OP Vj Vk Qj Qk

Page 90: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 90

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 91: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 91

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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 F6, 34+, R2

LD F2, 45+, R3

MULTD F0, F2, F4

SUBD F8, F6, F2

DIVD F10, F0, F6

ADDD F6, F8, F2

È facile notare, come questo listato presenti una serie di conflitti di dato.

La situazione iniziale si può schematizzare con la seguente figura, figura che verrà riportata più volte per

spiegare passo – passo lo svolgimento delle istruzioni:

PARTE SUPERIORE

- Sulla sinistra sono riportate le istruzioni, indicando il

valore j e k.

- Al centro vi è una tabella di riepilogo, nella quale sono

monitorate le varie fasi di ciascuna istruzione: indicando

l’istante (colpo di clock) in cui l’istruzione viene

decodificata (Issue), completata (Comp) e istante in cui

avviene la scrittura dei risultati (Result).

- Sulla destra vengono monitorate le risorse per

permettere le operazioni di load: disponibilità (Busy),

indirizzo (Address).

PARTE CENTRALE

- È riportata la situazione delle Stazioni di Prenotazione (Reservation Stations) indicando il tempo per

portare a termine l’operazione (Time), il nome della stazione (Name), e i vari campi che caratterizzano

queste stazioni.

PARTE INFERIORE

- È indicato il colpo di clock effettivo e lo stato dei registri.

Page 92: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 92

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 93: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 93

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 94: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 94

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 95: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 95

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 96: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 96

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 97: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 97

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 98: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 98

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 99: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 99

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

PARTE QUARTA

PARTE QUARTA

ALTRI TIPI DI PROCESSORE

PROCESSORI VLIW

PROCESSORI SUPERSCALARI

PROCESSORI VETTORIALI

MULTICORE

Page 100: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 100

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

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

UNITA’ 1 UNITA’ 2 UNITA’ 3 UNITA’ 4

UNITA’ ACC. MEM.

1

UNITA’ FP 1

UNITA’ FP 2

UNITA’ INTERA/BRANCH

UNITA’ ACC. MEM.

2

Page 101: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 101

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Il listato del programma già ottimizzato, con la tecnica dello srotolamento del loop eseguita per sette volte,

è il seguente:

1 LOOP: L.D F0,0(R1)

2 L.D F6,-8(R1)

3 L.D F10,-16(R1)

4 L.D F14,-24(R1)

5 L.D F18,-32(R1)

6 L.D F22,-40(R1)

7 L.D F26,-48(R1)

8 ADD.D F4,F0,F2

9 ADD.D F8,F6,F2

10 ADD.D F12,F10,F2

11 ADD.D F16,F14,F2

12 ADD.D F20,F18,F2

13 ADD.D F24,F22,F2

14 ADD.D F28,F26,F2

15 S.D 0(R1),F4

16 S.D -8(R1),F8

17 S.D -16(R1),F12

18 S.D -24(R1),F16

19 S.D -32(R1),F20

20 S.D -40(R1),F24

21 DSUBUI R1,R1,#56

22 BNEZ R1,LOOP

23 S.D 8(R1),F28 ; 8-56 = -48 per cui S.D -48(R1),F28

Brevemente questo programma somma gli elementi di un vettore, memorizzato a partire da R1, con una

costante memorizzata in F2.

Riempendo i campi con logica, per ogni singolo colpo di clock, dell’istruzione VLIW si ottiene la seguente

situazione:

Si nota come alcune VLIW hanno due o tre campi NO – OP.

Page 102: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 102

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 103: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 103

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

CC 1 CC 2 CC 3 CC 4 CC 5

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:

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.

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;

MEM. ISTR.

UNITA’ INTERA

UNITA’ FLOATING

POINT

MEM. DATI

Istruzione intera

Istruzione Floating

point

Page 104: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 104

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 105: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 105

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 106: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 106

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Per cui, grazie a questo dispositivo, è possibile avere al termine della fase MEM dell’istruzione LOADV il

primo elemento del vettore nella corrispondente cella del registro destinazione; per ogni colpo di clock

successivo si avrà a disposizione, nella specifica cella del registro destinazione, l’elemento successivo del

vettore.

Quindi è evidente che se la memoria consente una banda passante maggiore che permette, ad esempio, la

lettura di due dati in un solo colpo di clock, al termine della fase MEM saranno disponibili, nelle rispettive

celle del registro vettoriale destinazione, i primi due elementi del vettore.

Sfruttando la disponibilità di alcuni elementi del vettore ancor prima che questo sia completamente

caricato nel registro destinazione, è possibile poter eseguire istruzionI che devono elaborare gli elementi,

come questo esempio:

1cc 2cc 3cc 4cc 5cc 6cc 7cc 8cc 9cc

LOADV V2,… IF ID EX MEM WB

LOADV V3,… IF ID EX MEM WB

ADDV V1,V2,V3 stallo IF ID EX MEM WB

STOREV …,V1 IF ID EX MEM WB

(Considerando idealmente che il sommatore abbia una latenza di 1 cc)

L’istruzione ADDV V1,V2,V3 potrà effettuare la somma degli elementi presenti nelle celle dei registri V2,V3

senza dover attendere l’intero caricamento del vettore. Lo stesso vale per la STOREV …,V1 che può

cominciare a memorizzare in memoria gli elementi disponibili nelle celle di V1.

Attenzione, questo calcolo non viene eseguito in circa 5 colpi di clock; poiché per completare l’intera

operazione bisogna attendere che tutti gli elementi del vettore vengano processati. Per cui il

completamento dell’operazione richiesta avverrà dopo un numero di colpi di clock dipendenti dal numero

di elementi che si devono processare.

Tutto questo è possibile poiché, come descritto precedentemente, le unità di calcolo si basano su logica

pipeline.

L’istruzione LVWS I vantaggi che questa CPU offre sono assicurati se gli elementi sono memorizzati in memoria centrale in

maniera sequenziale; infatti in memoria i vettori sono allocati in locazioni consecutive.

Questo non avviene quando ad esempio si estrae da una matrice un qualsiasi vettore colonna, essendo le

matrici generalmente allocate per righe; per questo caso attraverso un’unica istruzione si risolve il

problema: vi è un numero che dirà al famoso modulo simile al DMA di quanto deve saltare per accedere

all’elemento successivo. L’istruzione in esame è: LVWS (Load Vector With Stride).

I registri VLR e MVLR Supponiamo che il vettore da processare sia costituito da un numero di elementi molto inferiore ai 64 che

la CPU in esame mette a disposizione. Il caricamento del vettore avverrà in un unico registro vettoriale

senza nessun tipo di problema, ma con conseguenti elementi inutilizzati; si nota facilmente che processare

questo vettore significherebbe far lavorare la CPU anche su elementi che non hanno nessun significato. Per

evitare ciò la CPU vettoriale ha un registro particolare chiamato VLR (V ector Length Register): questo

registro contiene un numero che il compilatore va ad impostare, in maniera trasparente al programmatore,

quando deve operare sui registri vettoriali; questo numero equivale alla dimensione del vettore da

processare e al massimo può valere (in questo caso) 64.

Page 107: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 107

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

Page 108: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 108

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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;

SCHEMA LOGICO Di seguito è riportato lo schema logico dell’architettura della CPU vettoriale Cray-1.

Osserviamo alcune sue caratteristiche:

- 8 registri vettoriali da 64 elementi

l’uno [V0÷V7];

- 8 registri scalari di tipo S [S0÷S7];

- 8 registri scalari di tipo A [A0÷A7];

- Buffer da 4 istruzioni;

- 3 unità ad aritmentica floating

point;

- 4 unità ad aritmetica intera;

- 2 unità per le operazioni sugli

indirizzi;

- Registro V.Mask;

- Registro V.Lenght;

Si noti che in questa CPU non è presente il divisore: questo è sostituito dall’unità che effettua il reciproco;

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

𝑦

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.

Cray-1 (1976)

Page 109: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 109

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

IDEE ALLA BASE DELLA ORGANIZZAZIONE VETTORIALE REGISTRI:

16 registri scalari;

8 registri vettoriali da 64 elementi

l’uno;

VLR indica da quanti elementi è

costituito il vettore da processare.

OPERAZIONI ARITMETICHE:

Avere a disposizioni tante unità

funzionali per processare

parallelamente ogni elemento del

vettore.

OPERAZIONI LAOD/STORE:

Accesso (load/store) in memoria

tramite gli indici BASE e STRIDE,

permettendo così l’accesso

efficiente a vettori con elementi

non contigui, come ad esempio un

qualsiasi vettore colonna di una matrice memorizzata in memoria per righe.

CODICE VETTORIALE Di seguito è riportato un confronto fra il codice implementato per una cpu scalare e un codice

implementato per la cpu vettoriale. Si noti come risulta molto più breve e semplice utilizzare istruzioni

vettoriali.

L’esempio consiste nell’eseguire una somma fra due vettori.

CODICE SORGENTE, C CODICE CPU SCALARE CODICE CPU VETTORIALE

for (i=0; i<64; i++)

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

LI R4, 64

loop: L.D F0, 0(R1)

L.D F2, 0(R2)

ADD.D F4, F2, F0

S.D F4, 0(R3)

DADDIU R1, 8

DADDIU R2, 8

DADDIU R3, 8

DSUBIU R4, 1

BNEZ R4, loop

LI VLR, 64

LV V1, R1

LV V2, R2

stallo

ADDV.D V3, V1, V2

SV V3, R3

I vantaggi nell’uso di un set con istruzioni vettoriali sono molteplici:

- Compattezza: poche istruzioni per eseguire diverse operazioni; - Indipendenza implicita dei dati, per cui assenza di conflitti di dati; - Uso delle stesse unità funzionali, per cui non sono necessarie particolari unità di calcolo; - Accesso a registri disgiunti, quindi come avviene per le non vettoriali; - Accesso a blocchi di memoria contigui (stride unitario), oppure saltando (stride noto a priori); - Riduzione drastica del collo di bottiglia con la memoria.

Page 110: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 110

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESECUZIONE ARITMETICA DELLE ISTRUZIONI L’unità funzionale che deve eseguire una certa operazione avrà una latenza, definita in fase di

progettazione, la quale permette di avere il risultato dopo un certo numero di colpi di clock. Organizzandola

in maniera tale che le sue unità logiche siano strutturate in pipeline, è possibile migliorare il throughput

(rendimento, cioè la frequenza con cui l’oggetto è in grado di processare i dati) dell’unità di calcolo.

Sulla base di queste considerazioni è chiaro che è possibile migliorare di molto le

prestazioni della singola unità funzionale e quindi dell’intero sistema; i dati saranno

disponibili molto più velocemente. La possibilità di utilizzare questa tecnica è garantita

perché gli elementi di un vettore sono indipendenti.

La figura affianco mostra come viene effettuato il prodotto fra due registri contenti dati

vettoriali, attraverso un moltiplicatore a 6 stadi di pipeline.

Supponendo una latenza di 6 colpi di clock il primo risultato lo si ottiene appunto dopo 6

cc. Il secondo risultato lo si otterrà al cc 7 e così via.

SISTEMA DI MEMORIZZAZIONE DI DATI VETTORIALI NEI REGISTRI VETTORIALI La CPU del Cray-1 disponeva di una memoria a 16 banchi, il cui schema logico è riportato di seguito:

L’accesso ai blocchi avviene in maniera

molto intuitiva; un sommatore genera

l’indirizzo del blocco operando sulla

base e sullo stride.

ESECUZIONE ISTRUZIONI VETTORIALI Si supponga di effettuare una operazione di somma fra due vettori:

ADDV C,A,B

Si possono distinguere due casi:

1°CASO

Una unità funzionale pipeline a 3 stadi

2°CASO

4 o più unità funzionale pipeline a 3 stadi

Aumenta il parallelismo, provocando un aumento

del throughput del sistema; la latenza della singola

unità rimane invariata. Si noti la disposizione con

cui gli elementi entrano nelle unità.

Page 111: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 111

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

STRUTTURA DELLE UNITA’ VETTORIALI La struttura delle unità si basa sulla

creazione di CORSIE le quali sono

organizzate in maniera tale da

ottimizzare al meglio l’operazione

vettoriale da eseguire. Ogni corsia

presenta due unità funzionali che

operano sui registri organizzati in

maniera logica, per ottenere i risultati

in modo consecutivo e il più

velocemente possibile.

Come già detto questa organizzazione

migliora il throughput del sistema.

Di seguito è riportata una immagine reale della struttura del T0 Vector Microprocessor del 1995; esso è

costituito da 16 unità funzionali.

DIFFERENZA FRA ARCHITETTURA MEMORIA-MEMORIA E ARCHITETTURA A REGISTRI VETTORIALI I sistemi basati su architettura memoria-memoria (VMMA – Vector Memory-Memory Architectures)

operano fondamentalmente considerando i vettori residenti in memoria centrale; quindi il prelievo e la

scrittura avviene direttamente in memoria centrale.

I primi sistemi che si basavano esclusivamente su architettura memoria-memoria sono ad esempio CDC

Star-100 (1973) e il TI ASC (1971); la scelta di questa tecnica era dovuta esclusivamente alla indisponibilità

di spazio fisico.

Per cui il codice di una macchina memoria-memoria è di questo tipo:

ADDV C, A, B ;si usano direttamente gli indirizzi

SUBV D, A, B

Cray-1 fu il primo sistema ad utilizzare registri vettoriali; questo implica necessariamente un codice diverso,

poiché bisogna effettuare le operazioni di load e store.

T0 Vector Microprocessor (1995)

Page 112: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 112

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

È possibile quindi evidenziare le differenze fra queste due tipologie di macchine vettoriali:

I sistemi VMMA richiedono una banda maggiore di memoria, perché ogni operando deve essere

sempre letto dalla memoria anche se precedentemente utilizzato, problema non presente con

l’utilizzo di registri vettoriali.

Aumento del rischio di dipendenza fra dati nei sistemi VMMA.

I sistemi VMMA incorrono in una maggiore latenza di avvio.

VETTORIZZAZIONE AUTOMATICA DEL CODICE Si osservi adesso come un codice sorgente, per semplicità consideriamo la somma di due vettori, viene

processato da una macchina con istruzioni scalari e da una con istruzioni vettoriali, e quindi i tempi di

esecuzione delle singole iterazioni.

CODICE SORGENTE

for (i=0; i < N; i++)

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

ISTRUZIONI SCALARI SEQUENZIALI Ipotizzando la

latenza pari a

un colpo di

clock per ogni

singola unità.

ISTRUZIONI VETTORIZZATE

La vettorizzazione permette un parallelismo

maggiore e quindi per lo stesso numero di colpi di

clock una cpu vettoriale riesce a processare più dati.

GESTIONE DI VETTORI CON DIMENSIONE SUPERIORE A MVLR – VECTOR STRIPMINING Vediamo ora come vengono gestiti i casi in cui il vettore da processare è costituito da un numero di

elementi maggiori del valore impostato in Max Vector Length Register.

Questo tipo di problema viene affrontato suddividendo il vettore in un certo numero di sottovettori;

ciascuno di questi sottovettori verrà considerato come un vettore di MVLR elementi o comunque di un

numero minore. Il vettore viene suddiviso quindi in N sottovettori: per rendere il più efficiente possibile il

sistema, N-1 sottovettori avranno la dimensione massima possibile, consentita dai registri vettoriali, quindi

MVLR, mentre un vettore sarà costituito dagli eventuali elementi residui.

È facile capire che se la dimensione del vettore è divisibile per MVLR non vi saranno sottovettori residui e

quindi la gestione si semplifica; se la dimensione del vettore non è divisibile per MVLR, allora bisognerà

gestire al meglio la presenza del vettore residuo.

Page 113: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 113

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Risulta opportuno che il primo sottovettore che deve essere processato sia il sottovettore residuo; in questo

modo al di fuori del loop viene processato il residuo e poi dopo aver modificato VLR si procede con i

restanti vettori.

Questa situazione viene implementata con le seguenti istruzioni:

for (i=0; i<N; i++)

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

1 ANDI R1, N, 63 # N mod 64

2 MTC1 VLR, R1 # Do remainder

3 loop: LV V1, RA

4 DSLL R2, R1, 3 # Multiply by 8

5 DADDU RA, RA, R2 # Bump pointer

6 LV V2, RB

7 DADDU RB, RB, R2

8 ADDV.D V3, V1, V2

9 SV V3, RC

10 DADDU RC, RC, R2

11 DSUBU N, N, R1 # Subtract elements

12 LI R1, 64

13 MTC1 VLR, R1 # Reset full length

14 BGTZ N, loop # Any more to do?

Analizziamo ora alcune istruzioni, fondamentali per gestire la presenza del vettore Remainder.

ISTRUZIONE 1: il valore del residuo viene calcolato attraverso l’istruzione:

ANDI R1, N, 63

Un residuo di una divisione per un divisore che è potenza di 2, come 64, si fa semplicemente

andando a considerare gli ultimi n bit (2𝑛 ). Per cui essendo 64 = 26 si considerano gli ultimi 6 bit

della dimensione del vettore, per ottenere il resto della divisione.

Per esempio N = 187:

(187)10 = (10111011)2 - Bisogna considerare gli ultimi 6 bit, quindi in AND con 63;

𝐴𝑁𝐷 63 10 = 00111111 2

Per cui risulta: (00111011)2 = (59)10

Quindi se la dimensione del vettore da processare è di 187 elementi, ci sarà un vettore Remainder

da 59 elementi e 191

64≅ 2, quindi 2 vettori da 64 elementi.

ISTRUZIONE 2: l’impostazione di VLR, essendo un registro speciale, avviene tramite un’istruzione

speciale:

MTC1 VLR, R1

ISTRUZIONE 4: shift logico verso sinistra di 3 posti, moltiplicando così per 8 il contenuto di R1, ossia

il valore della dimensione del vettore al momento processato;

DSLL R2, R1, 3

In questo modo in R2 è contenuto il valore della dimensione in memoria del sottovettore che si sta

processando e di conseguenza R2 conterrà il valore del salto da effettuare per accedere al

sottovettore successivo. Le istruzioni 5 – 7 – 10 aggiorneranno i rispettivi indirizzi per accedere al

successivo sottovettore.

ISTRUZIONE 14: controlla se il valore di N è maggiore di zero: BGTZ N, loop

Page 114: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 114

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

PARALLELISMO DELLE ISTRUZIONI VETTORIALI Si supponga una unità costituita 8 corsie e 32 elementi per ogni registro vettoriale, e si ipotizzi idealmente

che ogni unità abbia una latenza di 1 colpo di clock; è possibile sovrapporre l’esecuzione di più istruzioni

vettoriali in questo modo: (considerando l’esecuzione su un singolo vettore)

Essendo disponibili 8 corsie verranno caricate nel registro vettoriale i primi 8 elementi del vettore; inoltre

essendo le unità pipeline, al colpo di clock successivo (2) si potranno caricare altri 8 elementi e in parallelo

eseguire con il moltiplicatore, come in questo esempio, l’istruzione successiva che processerà i dati caricati

al colpo di clock 1:

Per cui al colpo di clock successivo (3) saranno caricati altri 8 elementi, e in parallelo oltre al moltiplicatore,

si potranno processare, con ad esempio un sommatore, i dati del colpo di clock precedente (2); per cui si

ottiene la seguente situazione:

In questo caso si sta eseguendo in parallelo, load-mul-add;

Essendo i registri costituiti da 32 elementi, e le corsie disponibili sono 8, la prima istruzione di load

terminerà al 4 colpo di clock; per cui al 5 cc l’unità che effettua operazioni di load/store sarà disponibile per

eventuali altre load/store; quindi è possibile in questo modo avere istruzioni parallele: la seguente figura

evidenzia il parallelismo che si ottiene.

In questo modo si completano 6 istruzioni in soli 10 colpi di clock. Ogni istruzione si completa in 4 colpi di

clock. Quindi nei casi in cui si ha il massimo parallelismo, cioè tutte le unità stanno operando, si eseguono

24 operazioni (8 load – 8 mul – 8 add). Per cui sono evidenti i vantaggi che porta questo tipo di soluzione.

Page 115: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 115

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

PENALITA’ DI AVVIO DELLE CPU VETTORIALI Le componenti che incidono sulla penalità di avvio nelle cpu vettoriali sono essenzialmente due:

1. Latenza delle unità funzionali, e quindi il tempo che trascorre per ottenere un risultato;

2. Tempo morto o tempo di recupero, ossia il tempo che trascorre prima che un altro vettore possa

utilizzare l’unità funzionale, se questa è unica e occupata.

Per chiarire il concetto di tempo morto si consideri la seguente figura:

Un’ipotetica unità funzionale è

occupata nel processore da un

certo vettore (e potrà essere

impegnata da un altro vettore solo

quando avrà terminato di

processato il primo vettore);

essendo questa unità organizzata in

pipeline solamente dopo un certo

numero di colpi di clock, pari alla

sua latenza, darà in uscita il primo

risultato e successivamente tutti gli

altri risultati, per ogni colpo di clock

successivo. Essendo questa unità

unica nel sistema, se un secondo

vettore deve essere processato, questo deve attendere che il primo vettore completi l’intera operazione e

che liberi quindi l’unità funzionale. Il tempo che intercorre si definisce tempo morto (Dead Time).

Per cui questo tempo morto dipende da due fattori:

1. La dimensione del vettore.

2. Il numero di unità funzionali presenti e quindi il numero di corsie.

GESTIONE DELLE CONDIZIONI – USO DEL REGISTRO V.MASK – ISTRUZIONI MASCHERATE L’obiettivo è quello di gestire, attraverso la vettorizzazione, situazioni in cui sono presenti condizioni sugli

elementi del vettore.

Consideriamo l’esempio:

for (i=0; i<N; i++)

if (A[i]>0) then

A[i] = B[i];

Si vuole sostituire tutti gli elementi del vettore A che sono maggiori di zero, con gli elementi di B.

Ad ogni elemento del registro vettoriale viene associato, tramite una particolare istruzione, un elemento

del registro V.MASK; gli elementi del registro V.MASK faranno da flag per gli elementi del vettore. Il flag

permette di identificare se quell’elemento è da processare oppure no.

Per fare questo bisogna impostare, come già detto, il registro V.MASK tramite l’istruzione SGTVS:

SGTVS.D V1, F0

Page 116: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 116

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Questa istruzione confronta gli elementi del vettore V1 con uno scalare e, se la condizione è verificata,

imposta il relativo campo del V.MASK associato al relativo elemento del vettore. Quindi per tutti gli

elementi che verificano la condizione verrà impostato il flag a 1 per indicare che solo quelli saranno

processati successivamente.

Quindi per l’esempio considerato si ha il seguente codice:

CVM # Turn on all elements

LV V1,R1 # Load entire A vector

SGTVS.D V1, F0 # Set bits in mask register where A>0

LV V1, R2 # Load B vector into A under mask

SV R1,V1 # Store A back to memory under mask

Per cui con l’utilizzo delle istruzioni mascherate è possibile ulteriormente ottimizzare l’esecuzione, e quindi

ridurre i tempi; gli elementi verranno processati in questa maniera:

È evidente che la verifica del flag relativo ad ogni elemento deve

essere effettuata a monte dell’unità funzionale, in modo tale da

poter processare solo gli elementi con flag a 1.

L’operazione di mascheramento quindi richiede una fase di

“compressione” dei dati, cioè i soli dati processati vengono

temporaneamente memorizzati in un registro vettoriale,

seguita da un fase di “espansione” in cui i dati vengono

memorizzati nelle relative posizioni del registro destinazione.

Temporary Register

Page 117: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 117

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

RIDUZIONE A OPERAZIONI SCALARI Ci sono operazioni con vettori che non sono definite operazioni vettoriali, poiché creano dipendenza tra i

dati e quindi conflitti nell’esecuzione.

È possibile ridurre queste operazioni ad operazioni di tipo vettoriale; questa tecnica permette dunque di

risolvere questo tipo di problema.

Consideriamo questa situazione:

sum = 0;

for (i=0; i<N; i++)

sum += A[i]; # Loop-carried dependence on sum

Questo codice somma gli elementi del vettore stesso creando però una dipendenza di dati.

Ridurre questa situazione a operazioni vettoriali significa dividere a metà il vettore e trattarlo come due

vettori distinti, per poter eseguire le operazioni vettoriali possibili.

Quindi si sommano i rispettivi elementi per ottenere un terzo vettore; a sua volta questo vettore viene

diviso a metà per operare ancora sui suoi elementi. Quando il numero degli elementi si riduce, diventa

molto piccolo o dispari, allora si trattano gli elementi del vettore come degli scalari.

Schematicamente la situazione è la seguente:

4

12

44

10

𝑉𝐿𝑅

2

48

22

48 𝑉𝐿𝑅

2

4

12

44

10

+ = +

22

= 70

VETTOREA

VETTORE A1

VETTORE A2

VETTORE B SCALARE A

SCALARE B

sum

Page 118: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 118

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESERCIZIO Ottimizzare un loop che calcoli: Y=aX+bY (X e Y vettori, a e b scalari) per una CPU VETTORIALE, cercando di

ridurre al minimo il numero di stalli.

Essendo la dimensione dei registri vettoriali da 64 elementi, ogni vettore sarà spezzettato in un vettore

Remainder da 32 elementi e in un vettore da 64 elementi.

La situazione si può riassumere con la seguente figura:

Supponiamo:

R1, R2: registri contenenti gli indirizzi dei due vettori, A e B;

R3: registro contenente la dimensione (96) dei vettori;

R29, R30: registri contenenti rispettivamente gli scalari “a” e “b”.

Il codice non ottimizzato è il seguente:

1 ANDI R4, R3, 63

2 MTC1 VLR, R4

3 LOOP: LV.D V1, R1

4 DSLL R5, R4, 3

5 DADDU R1, R1, R5

6 LV.D V2, R2

7 DADDU R2, R2, R5

8 MULTSV.D V1, V1, R29

9 MULTSV.D V2, V2, R30

10 ADDV.D V2, V1, V2

11 SV.D V2, R2

12 DADD R3, R3, -R4

13 LI R4, 64

14 MTC1 VLR, R4

15 BGTZ R3, LOOP

Page 119: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 119

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

OTTIMIZZAZIONE

Prima di tutto è possibile, sfruttando la forma base+spiazzamento, utilizzare un unico registro per

l’incremento dei registri R1 e R2 evitando così di utilizzare due istruzioni (5 e 7).

Il registro base conterrà l’indirizzo del primo elemento del vettore, quindi diverso per ogni vettore, mentre

lo spiazzamento, comune per tutti i vettori, conterrà il valore del salto per accedere al blocco di dati

successivo. Per cui è possibile riscrivere le load/store nella seguente maniera:

La sintassi da seguire è: LV.D dest, offset(base)

LV.D V1, R7(R1)

LV.D V2, R7(R2)

SV.D V2, R7(R2)

Dove R7 è il registro contenente lo spiazzamento; per cui basterà incrementarlo per accedere al blocco di

dati successivo; per cui R7 è l’unico indice che opera all’interno del loop. In questo modo è possibile anche

escludere il registro R3 che precedentemente faceva da contatore, ed usare R7 come registro su cui

effettuare il controllo.

Si ricordi che nel caso scalare, il problema veniva affrontato processando il vettore a partire dall’ultimo

elemento fino ad arrivare al primo, con un decremento dell’indice di 8 byte.

Nel caso del processore vettoriale, l’indice non punterà all’ultimo elemento, ma al primo elemento

dell’ultimo sottovettore, che, per una migliore implementazione, è il vettore remainder; per cui l’indice ad

ogni iterazione verrà decrementato di 64 elementi, ossia di 64 ∗ 8 = 512 byte. Il decremento, sottoforma

d’istruzione, è il seguente:

DADDI R7, R7, #-512

Per chiarire quando detto si consideri il seguente esempio:

Si supponga un vettore di 140 elementi; questo vettore sarà diviso in due sottovettori da 64 elementi e un

sottovettore da 12 elementi. Considerando il sottovettore remainder come ultimo blocco, l’indice punterà

al suo primo elemento, per cui attraverso il decremento di 512 byte si avrà accesso al primo elemento del

secondo sottoblocco e successivamente, con un ulteriore decremento al primo elemento del primo

sottoblocco.

Le seguenti figure chiariscono la scelta di porre per ultimo il sottovettore remainder.

Per posizionare R7 bisogna calcolare l’indirizzo del primo elemento del sottovettore remainder. Questo è possibile attraverso l’operazione: 𝑁 − 𝑟𝑒𝑚𝑎𝑖𝑛𝑑𝑒𝑟 ∗ 8.

L’indice punterà al primo elemento

dell’ultimo sottoblocco R7

L’indice punterà al primo elemento del

secondo sottoblocco R7

L’indice punterà al primo elemento del

primo sottoblocco

R7

Page 120: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 120

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Fatte queste considerazioni il codice parzialmente ottimizzato è il seguente:

1 ANDI R4, R3, 63

2 MTC1 VLR, R4

3 DSUBI R7, R3, R4

4 DMULI R7, R7, #8

5 LOOP: LV.D V1, R7(R1)

6 MULTSV.D V1, V1, R29

7 LV.D V2, R7(R2)

8 MULTSV.D V2, V2, R30

9 ADDV.D V2, V1, V2

10 SV.D V2, R7(R2)

11 DADDI R7, R7, #-512

12 MTC1 VLR, #64

13 BGEZ R7, LOOP

Adesso vediamo come è possibile schedulare meglio il loop per eliminare gli eventuali stalli presenti. Dopo le due load ci sarà uno stallo con le successive operazioni di moltiplicazione che utilizzano come sorgenti i registri destinazione delle load.

L’istruzione BGEZ provoca uno stallo: sposto l’istruzione MTC1 VLR, #64 nel delay slot sotto alla BCEZ. Per concludere il codice ottimizzato è il seguente (considerando unitaria la latenza di ciascuna unità funzionale):

1 ANDI R4, R3, 63

2 DSUBI R7, R3, R4

3 MTC1 VLR, R4

4 DMULI R7, R7, #8

5 LOOP: LV.D V1, R7(R1)

6 LV.D V2, R7(R2)

7 MULTSV.D V1, V1, R29

8 MULTSV.D V2, V2, R30

9 ADDV.D V2, V1, V2

10 SV.D V2, R7(R2)

11 DADDI R7, R7, #-512

12 BCEZ R7, LOOP

13 MTC1 VLR, #64

Page 121: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 121

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Analizziamo ora i diagrammi temporali delle istruzioni “fondamentali” per l’operazione da effettuare; si

consideri per semplicità che la cpu vettoriale sia ad una sola corsia e che la banda passante della memoria

dati sia di tre dati per colpo di clock, per cui è possibile effettuare tre accessi in memoria. Inoltre si

consideri la presenza di due moltiplicatori con una latenza di 4 colpi di clock, per cui dopo 4 cc il

moltiplicatore mette a disposizione il primo risultato; due sommatori con una latenza di 2 colpi di clock.

LEGENDA

Disponibilità 1° elemento:

Disponibilità 2° elemento:

Disponibilità elementi successivi:

Disponibilità ULTIMO elemento:

Per il seguente diagramma VLR è impostato al valore 64

COLPI DI CLOCK

ISTRUZIONI↓ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 .

6

7

6

8 .

7

2

7

3

7

4

7

5

7

6

LV.D V1, R7(R1) IF ID EX MEM WB

LV.D V2, R7(R2) IF ID EX MEM WB

MULTSV.D V1, V1, R29 IF ID EX MEM WB

MULTSV.D V2, V2, R30 IF ID EX MEM WB

ADDV.D V2, V1, V2 IF ID STALLO EX MEM WB

SV.D V2, R7(R2) IF ID EX STALLO MEM WB

Bisogna quindi aggiungere le ulteriori istruzioni di gestione; il procedimento da seguire è analogo a quanto

appena fatto. Per cui si completa l’intera operazione Y=aX+bY con vettori da 64 elementi dopo 76 colpi di

clock, senza contare le istruzioni di gestione fuori e dentro al loop.

Chiarito questo, si supponga di avere la stessa cpu vettoriale con la sola differenza che adesso consideriamo

8 corsie. Questo significa che per ogni colpo di clock verranno effettuate 8 operazioni, per ogni istruzione

vettoriale, per cui ad esempio una istruzione di load vettoriale caricherà in un solo colpo di clock 8

elementi.

Per cui si riducono i colpi di clock e ne risulta il seguente diagramma:

LEGENDA

Disponibilità 1° ÷ 8° elemento:

Disponibilità 9° ÷ 16° elemento:

Disponibilità 17° ÷ 56° elemento:

Disponibilità 57° ÷ 64° elemento:

Per il seguente diagramma VLR è impostato al valore 64 COLPI DI CLOCK

ISTRUZIONI↓ 1 2 3 4 5 6 7 8 9 10 11 12 13 14

1

5

1

6

1

7

1

8

1

9

2

0

LV.D V1, R7(R1) IF ID EX MEM WB

LV.D V2, R7(R2) IF ID EX MEM WB

MULTSV.D V1, V1, R29 IF ID EX MEM WB

MULTSV.D V2, V2, R30 IF ID EX MEM WB

ADDV.D V2, V1, V2 IF ID STALLO EX MEM WB

SV.D V2, R7(R2) IF ID EX STALLO MEM WB

Per cui si completa l’intera operazione Y=aX+bY con vettori da 64 elementi dopo 19 colpi di clock.

Page 122: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 122

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Il diagramma completo per l’esercizio assegnato è il seguente: si consideri una cpu a 8 corsie. LEGENDA

Disponibilità 1° ÷ 8° elemento del sottovettore:

Disponibilità 9° ÷ 16° elemento del sottovettore:

Disponibilità 17° ÷ 56° elemento del sottovettore:

Disponibilità 57° ÷ 64° elemento del sottovettore:

COLPI DI CLOCK

ISTRUZIONI↓ 1 2 3 4 5 6 7 8 9

1

0

1

1

1

2

1

3

1

4

1

5

1

6

1

7

1

8

1

9

2

0

2

1

2

2

2

3

2

4

2

5

2

6

2

7

2

8

2

9

3

0

3

1

3

2

ANDI R4, R3, 63 IF ID EX ME

M WB

ANDI R7, R3, R4 IF ID EX ME

M WB

MTC1 VLR, R4 VLR = 32 IF ID EX ME

M WB

DMULI R7, R7, #8 IF ID EX ME

M WB

LV.D V1, R7(R1) IF ID EX ME

M WB

LV.D V2, R7(R2) IF ID EX ME

M WB

MULTSV.D V1, V1, R29 IF ID EX ME

M WB

MULTSV.D V2, V2, R30 IF ID EX ME

M WB

ADDV.D V2, V1, V2 IF ID STALLO EX ME

M WB

SV.D V2, R7(R2) IF ID EX STALLO ME

M WB

DADDI R7, R7, #-512 IF ID EX ME

M WB

BCEZ R7, LOOP IF ID EX ME

M WB

MTC1 VLR, #64 VLR = 64 IF ID EX ME

M WB

LV.D V1, R7(R1) IF ID EX ST

AL

ME

M WB

LV.D V2, R7(R2) IF ID EX STALLO ME

M WB

MULTSV.D V1, V1, R29 IF ID EX ME

M WB

MULTSV.D V2, V2, R30 IF ID EX STALLO ME

M WB

ADDV.D V2, V1, V2 IF ID STALLO EX STALLO M

E

W

B

SV.D V2, R7(R2) ID ID EX STALLO M

E

W

B

DADDI R7, R7, #-512 IF ID EX ME

M WB

BCEZ R7, LOOP IF ID EX ME

M WB

MTC1 VLR, #64 IF ID EX ME

M WB

È possibile sovrapporre alcune fasi, poiché queste utilizzano unità funzionali diverse, o perché si è ipotizzato

che alcune unità, come la memoria, possiedono una banda di dati maggiore.

Essendo i vettori di 96 elementi il loop sarà eseguito due volte, prima con VLR = 32 e poi con VLR = 64; per

eseguire l’operazione richiesta ci vorranno 37 colpi di clock (la tabella non è completa per motivi di spazio).

Page 123: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 123

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ARCHITETTURA MULTICORE Fino ad ora si è visto come potessero essere migliorate le prestazioni di un calcolatore puntando su

architetture ILP (Instruction Level Parallelism), cioè quelle architetture basate sul parallelismo delle

istruzioni che con una serie di accorgimenti, quali pipeline delle unità funzionali, riduzione dei conflitti,

predizione dei salti, ecc., hanno permesso di ottenere la miglior soluzione possibile per l’ottimizzazione

delle prestazioni; inoltre con l’utilizzo di hardware particolari (VLIW, Super Scalare, Vettoriale) si è

contribuito all’aumento delle prestazioni, il tutto utilizzando una sola cpu.

Quello che emerge è che l’aumento delle prestazioni che è possibile ottenere è fortemente legato

all’hardware di controllo, il quale deve gestire al meglio la contemporanea esecuzione delle istruzioni in

maniera da evitare conflitti; non sempre però questo porta ad un effettivo ed evidente miglioramento delle

prestazioni.

Infatti alcune valutazioni hanno evidenziato che insistere in queste direzioni non porta ad avere una

effettiva efficienza (generalmente: 𝐸𝐹𝐹𝐼𝐶𝐼𝐸𝑁𝑍𝐴 =𝑅𝐼𝑆𝑈𝐿𝑇𝐴𝑇𝐼

𝐶𝑂𝑆𝑇𝐼).

Inoltre queste valutazioni hanno evidenziato che è possibile mantenere alta l’efficienza con un numero di

processori maggiori. Seguendo queste valutazioni si è arrivati, grazie alla tecnologia a disposizione, a

realizzare in un singolo chip più di un processore.

Questa tecnologia risulta interessante, poiché ha costi relativamente bassi, in quanto si va replicare il

singolo processore e quindi non richiede una riprogettazione complessa. Quindi invece di rinforzare,

potenziare una singola caratteristica si va a replicare l’intera cpu; il potenziamento di una caratteristica

migliora le prestazioni di quella parte di esecuzione del programma che va ad usare quella componente, e

quindi non vi è un miglioramento globale del sistema.

La seguente figura mostra come l’aumento dei registri, non comporta una miglioramento proporzionale al

potenziamento eseguito.

Passando da 32 a 128 registri, quindi quadruplicandone il numero, non si nota un aumento proporzionale

delle istruzioni parallele, per cui non sempre il potenziamento si traduce in un effettivo miglioramento.

Questo significa che il punto critico è diventato un altro aspetto; analogo discorso si potrebbe avere

analizzando un miglioramento delle predizioni di salto.

Page 124: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 124

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

PARALLELISMO A LIVELLO DI THREAD, MULTI-THREAD Per thread si intende un processo indipendente da un altro processo; indipendente nel senso che può

appartenere allo stesso programma, ma che non è influenzato dagli esiti determinati dagli altri processi che

costituiscono il programma. Ogni thread ha i suoi dati, istruzioni, registri necessari alla sua esecuzione.

Fondamentalmente esistono tre tipi di multithread:

1. SIMULTANEOUS MULTI-THREADING: consideriamo una CPU che permette teoricamente di eseguire

in simultaneo 8 istruzioni, grazie alla presenza di più unità funzionali uguali. L’esecuzione di un

singolo thread potrebbe generare una situazione del genere:

In un colpo di clock dovrebbero essere prelevate 8 istruzioni, ma questo,

come si vede, non avviene, poiché evidentemente non vi sono istruzioni che

usano unità funzionali diverse. Quindi in un colpo di clock saranno

processate poche istruzioni, provocando anche eventuali stalli.

È possibile pensare di utilizzare le unità

funzionali inutilizzate usando istruzioni di un

altro thread; questo perché per definizione i

thread sono indipendenti fra loro, quindi lo

saranno anche i loro dati. Ciò significa che non

vi saranno conflitti di dati: la situazione in

presenza di un altro thread è rappresentata

dalla seguente figura.

Per cui i thread partono simultaneamente sfruttando le unità

funzionali non utilizzate da un altro thread.

2. FINE-GRAINED MULTI-THREADING: (a grana fina) questa tipologia di multithreading prevede che il

processore scambi il thread in esecuzione a ogni ciclo di clock. Questa tipologia di multithreading

dovrebbe rimuovere la dipendenza dai dati dei singoli thread e quindi dovrebbe azzerare o

comunque ridurre gli stalli della pipeline dovuta alla dipendenza dai dati. Dato che ogni thread

dovrebbe funzionare in modo indipendente i singoli thread eseguiranno programmi non correlati e

quindi vi saranno poche probabilità che le istruzioni di un thread necessitino dei risultati elaborati

da un'istruzione di un altro thread in esecuzione in quel momento.

3. COARSE-GRAINED MULTI-THREAD: (a grana grossa) questa tipologia di multithread prevede che il

processore esegua un singolo thread fino a quando questo non viene bloccato da un evento che

normalmente ha una elevata latenza (per esempio un cache miss), in questo caso il processore

provvede a eseguire un altro thread che era pronto per l'esecuzione. Il thread di rimpiazzo rimane

in esecuzione fino a quando termina o viene bloccato da un evento.

Per queste ultime due tipologie di multithread bisogna fare delle considerazioni: il multithreading parte dal

presupposto che il passaggio tra thread avvenga in modo rapido; queste due tecniche effettuano il

passaggio in un ciclo di clock. Al fine di ottenere questo il processore deve replicare alcune componenti per

i due thread come i registri interni, il program counter e alcuni registri di stato. Per cui un cambio di

contesto ottimizzato è fondamentale per avere tempi estremamente bassi.

Page 125: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 125

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Di seguito è riportato uno schema riassuntivo delle varie tecniche di parallelismo.

MEMORIA CONDIVISA E MEMORIA DISTRIBUITA IN SISTEMI MULTICORE

La categoria normalmente utilizzata nelle architetture

multicore è quella a memoria condivisa; N core, ognuno

comprendente una memoria cache, condividono

un’unica memoria centrale.

Un’altra categoria è caratterizzata da

memorie locali per ogni core, che sono

sincronizzate da una particolare

infrastruttura, anche complessa, per

mantenere una certa coerenza fra i dati.

Si utilizza una memoria condivisa quando non è possibile individuare delle aree dati distinte e indipendenti

per ogni singolo thread che ogni core deve eseguire. Per cui questa soluzione è ottimale dal punto di vista

della coerenza fra i dati. Il problema legato a questa categoria è dovuto al fatto che diversi core devono

accedervi contemporaneamente; ma questo non è possibile, o comunque non in elevate quantità, poiché

la memoria possiede una banda passante finita, che limita gli accessi ad essa stessa.

Per cui è evidente che una soluzione a memoria condivisa è effettivamente praticabile quando si utilizza un

numero di core basso. Per superare quindi questo limite è opportuno implementare la categoria a memoria

distribuita; l’implementazione richiede la realizzazione di una efficiente rete di interconnessione, in modo

da ridurre il tempo di comunicazione tra le memorie.

Page 126: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 126

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

IInnddiiccee AAnnaalliittiiccoo

A

ALEE ISTRUZIONI ALU ........................ 31 ISTRUZIONI BRANCH ................. 35 ISTRUZIONI LOAD ...................... 34 RAW - WAW - WAR - RAR ......... 30

Amdahl, legge di ............................ 69 Associativa ........ Vedi Memorie Cache

B

Banchi interlacciati ........................ 78 Banchi paralleli .............................. 78

C

Clean Bit ........................................ 69 COARSE-GRAINED MULTI-THREAD

................................................ 123 Codifica

dell'istruzione ........................... 14 Completamente Associativa ....... Vedi

Memorie cache Componenti del processore No-

Pipeline ......... Vedi Processore No-Pipeline

Control Unit Microprogrammata, Cablata .... 14

Corsie ........................................... 110

D

Dead Time ................................... 114 Delay Slot ....................................... 37 Dirty Bit .......................................... 70 DRAM ............................................ 70

E

EX - Execution ................................ 17

F

FIFO, metodo ......... Vedi Sostituzione FINE-GRAINED MULTI-THREADING

................................................ 123 Finestra dei registri ........................ 62 Floating point

Scheduling istruzioni ................. 87

G

Gerarchia di memoria .................... 62

H

HIT RATE ........................................ 71 HIT TIME ........................................ 71

I

ID - Instruction Decode .................. 16 IF - Instruction Fetch ...................... 16 Indirizzamento diretto Vedi Memorie

cache Istruzioni .......................................... 7

di calcolo ................................... 10 di controllo ................................ 11 di tipo MOV ................................. 9 di trasferimento dei dati ............. 7 Formato delle ............................ 13 fuori ordine ............................... 84 LVWS ....................................... 105 Set, floating point...................... 86 Set, vettoriale .......................... 104 Superscalare ............................ 102 Vettoriali

Parallelismo ........................ 113 VLIW .......................................... 99

Istruzioni di tipo I . Vedi Formato delle istruzioni

Istruzioni di tipo Jump.. Vedi Formato delle istruzioni

Istruzioni di tipo R Vedi Formato delle istruzioni

L

LRU, metodo .......... Vedi Sostituzione

M

MEM - Memory Access .................. 18 Memorie cache .............................. 64

ad indirizzamento diretto ......... 65 Allocazione dei blocchi .............. 64 Completamnte associative ........ 65 Elettronica ................................. 70 Funzionamento logico delle ...... 74 Organizzazione .......................... 80 Prestazioni .......................... 71; 78 Problematiche ........................... 77 Scrittura .................................... 69

set associativa .......................... 65 Memorie Cache

Accesso alla memoria ............... 28 LOAD/STORE disallineata..... 29

MIPS64 Set istruzioni ............................. 12

MISS PENALITY .............................. 71 MISS RATE ..................................... 71 MOTOROLA 68000 ........................ 76 MVLR ..............................Vedi Registri

P

Pipeline ALEE .......................................... 27

Strutturali, di dato ............... 30 da programma .......................... 42 Microistruzioni ......................... 26 Struttura processore ................ 25 Tecnica ..................................... 22

PowerPC ........................................ 74 Prinicipi di località ......................... 63 Processore

Accumulatore ........................... 57 Floating point ........................... 84 Multicore ................................ 122 No-Pipeline ............................... 15 Pipeline ..................................... 25

Ottimizzato .......................... 36 Superscalare ........................... 102 Vettoriale ............................... 103

CRAY 1 ............................... 107 VLIW ......................................... 99

R

Random, metodo ... Vedi Sostituzione Registri ............................................ 9

V.LENGHT ............................... 107 V.MASK ................................... 107 Vettoriali................................. 109 VLR, MVLR .............................. 105

Ricerca e identificazione ............... 66

S

Salto Condizionato, Incondizionato ... 11

Scoreboard .................................... 86 Set, istruzioni................................. 11 Shift, istruzioni

Logico, Aritmetico .................... 11 SIMULTANEOUS MULTI-THREADING

............................................... 123 Sostituzione ................................... 67 SRAM ............................................. 70

Page 127: Dispense Calcolatori Elettronici Con Esercizi

Appunti di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 127

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Stazioni di prenotazione ............. Vedi Tomasulo, algoritmo

Strotolamento ............................... 40

T

Tecnica Speculativa ....................... 38 Tipi di dati ........................................ 7

Floating Point .............................. 7 Interi ........................................... 7

Vettoriali ................................. 103 Tomasulo, algoritmo ...................... 88 Trasparenza dei livelli .................... 62

V

V.LENGHT ....................... Vedi Registri V.MASK .......................... Vedi Registri

uso del registro ....................... 114 VECTOR STRIPMINING ................. 111

VLR .................................Vedi Registri

W

Write Back ..................................... 69 Write Through ............................... 69

BBIIBBLLIIOOGGRRAAFFIIAA

1. JOHN L. HENNESSY, DAVID A. PATTERSON, “Architettura degli elaboratori”, 4a edizione, APOGEO

2. PROF. ING. F. MARINO, G. MASTRONARDI “Supporto Multimediale di Ausilio al Corso di

CALCOLATORI ELETTRONICI”,

3. DAVID A. PATTERSON, “Slide” di alcune lezioni scaricabili dal link:

http://vlsi.cs.berkeley.edu/cs252-s06/index.php/Lectures”, 2006

4. WIKIPEDIA, “L’enciclopedia libera“

Page 128: Dispense Calcolatori Elettronici Con Esercizi

EESSEERRCCIIZZII DDII CCAALLCCOOLLAATTOORRII EELLEETTTTRROONNIICCII

A.A. 2009/2010

A cura di: Fabio Stroppa

Nicola Pietroleonardo

Page 129: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 1

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

IINNDDIICCEE

MICROCODICE DELLE ISTRUZIONI FONDAMENTALI ............................... 2

ESERCIZI MICROCODICE ........................................................................ 3

ESERCIZIO 1 - ADDW R1 R2 R3 ....................................................................................................................... 4

ESERCIZIO 2 - ADDMEM R1 R2 R3 ................................................................................................................. 6

ESERCIZIO 3 – ADD3 R1 R2 R3 ....................................................................................................................... 8

ESERCIZIO 4 – MAC R1,(R2),R3 ...................................................................................................................... 9

ESERCIZIO 5 – SWP R1 R2 ............................................................................................................................ 11

ESERCIZIO 6 – SWX R2 R31 R1 ..................................................................................................................... 13

ESERCIZIO 7 – LL R6 (#100,R3) ..................................................................................................................... 14

ESERCIZIO 8 – SL (#100,R3) R6 ..................................................................................................................... 15

ESERCIZIO 9 – SWPM R1 R2 ......................................................................................................................... 16

ESERCIZI ASSEMBLY ............................................................................ 18

ESERCIZIO 1 – SOMMA DI DUE VETTORI ..................................................................................................... 19

ESERCIZIO 2 – MEDIA DI UN VETTORE ......................................................................................................... 23

ESERCIZIO 3 – MINIMO DI UN VETTORE ...................................................................................................... 25

ESERCIZIO 4 – LOAD DOUBLE NON ALLINEATA ........................................................................................... 28

ESERCIZIO 5 – STORE DOUBLE NON ALLINEATA .......................................................................................... 30

ESERCIZIO 6 – SOMMA DI VETTORI – PIPELINE DA PROGRAMMA .............................................................. 32

ALGORITMO DI TOMASULO ................................................................ 33

ESERCIZIO 1 .................................................................................................................................................. 34

ESERCIZIO 2 .................................................................................................................................................. 40

ESERCIZI ASSEMBLY – PROCESSORI SUPERSCALARI E VLIW .................. 48

ESERCIZIO 1 .................................................................................................................................................. 49

ESERCIZI ASSEMBLY DLXV ................................................................... 55

ESERCIZIO 1 – SOMMA VETTORI DA 64 ELEMENTI ...................................................................................... 56

ESERCIZIO 2 – SOMMA DI VETTORI > 64 ..................................................................................................... 57

ESERCIZIO 3 – SOMMA DI MATRICI CON MxN > 64 ..................................................................................... 59

ESERCIZIO 4 – OPERAZIONE Y = (aX + bY)/c ................................................................................................ 60

ESERCIZIO 5 – PRODOTTO SCALARE TRA VETTORI DI 64 ELEMENTI ............................................................ 62

Page 130: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 2

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

MICROCODICE DELLE ISTRUZIONI FONDAMENTALI

IF IF/ID.IR Mem[PC]; IF/ID.NPC (if ((EX/MEM.opcode == branch)OR(EX/MEM.opcode == jump) & EX/MEM.cond) {(EX/MEM.ALUOutput)} else{PC+4}); ID ID/EX.A Regs[IF/ID.IR[rs]]; ID/EX.B Regs[IF/ID.IR[rt]]; ID/EX.Imm sign-extended(IF/ID.IR[immediate field]); ID/EX.IR IF/ID.IR; ID/EX.NPC IF/ID.NPC; ISTRUZIONE DI DIRAMAZIONE EX EX/MEM.ALUOutput ID/EX.NPC + (ID/EX.Imm << 2); EX/MEM.cond (ID/EX.A == 0); MEM WB ISTRUZIONE ALU R op R EX EX/MEM.IR ID/EX.IR; EX/MEM.ALUOutput ID/EX.A op ID/EX.B; MEM MEM/WB.IR EX/MEM.IR; MEM/WB.ALUOutput EX/MEM.ALUOutput; WB Regs[MEM/WB.IR[rd]] MEM/WB.ALUOutput; ISTRUZIONE ALU R op Imm EX EX/MEM.IR ID/EX.IR; EX/MEM.ALUOutput ID/EX.A op ID/EX.Imm; MEM MEM/WB.IR EX/MEM.IR; MEM/WB.ALUOutput EX/MEM.ALUOutput; WB Regs[MEM/WB.IR[rd]] MEM/WB.ALUOutput; ISTRUZIONE LOAD EX EX/MEM.IR ID/EX.IR; EX/MEM.ALUOutput ID/EX.A + ID/EX.Imm; MEM MEM/WB.IR EX/MEM.IR; MEM/WB.LMD Mem[EX/MEM.ALUOutput]; WB Regs[MEM/WB.IR[rt]] MEM/WB.LMD; ISTRUZIONE STORE EX EX/MEM.IR ID/EX.IR; EX/MEM.ALUOutput ID/EX.A + ID/EX.Imm; EX/MEM.B ID/EX.B; MEM MEM/WB.IR EX/MEM.IR; Mem[EX/MEM.ALUOutput] EX/MEM.B; WB

Page 131: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 3

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESERCIZI MICROCODICE

ESERCIZI MICROCODICE

Page 132: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 4

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 133: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 5

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Al progetto del processore pipeline abbiamo aggiunto tre latch ed un sommatore.

Page 134: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 6

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 135: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 7

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

registro EX/MEM.B: tale operazione può portare a dei conflitti di dati se l’istruzione schedulata tre colpi di clock dopo la ADDMEM è un’operazione di store:

Nella sua fase di EXE, la store scriverà il valore di ID/EX.B in EX/MEM.B per propagare il valore di B, utilizzando quindi il latch EX/MEM.B. Dunque, per evitare problemi di questo tipo, sarebbe consigliabile propagare ulteriormente il valore di B della istruzione di ADDMEM da EX/MEM.B a MEM/WB.B aggiungendo un nuovo registro al latch del processore. In realtà, successivamente scopriremo che l’aggiunta di questo registro nel latch è inutile. EX2 MEM/WB.ALUOutput2 MEM/WB.LMD + MEM/WB.ALUOutput2; MEM/WB.B Regs[M/WB.IR2[rd]; } da svolgere nel secondo semiciclo di clock, lettura da registro MEM3 Mem[MEM/WB.B] MEM/WB.ALUOutput2; L’istruzione viene eseguita in 7 colpi di clock, risparmiandone 2 rispetto alla sua scissione in 4 istruzioni. Ci saranno stalli obbligatori se l’istruzione che segue la nostra ADDMEM è una load o store, che fa uso effettivo nella memoria (che sarà occupata in quel momento). Stesso discorso per l’istruzione schedulata tre colpi di clock dopo la ADDMEM, che cadrà in fase MEM quando la ADDMEM è in MEM3.

In base a quanto detto, la terza operazione dopo la ADDMEM, se è una store, provocherà uno stallo: tornando al discorso in cui si consigliava la presenza del latch MEM/WB.B si nota ora che è possibile utilizzare per tale funzione lo stesso registro EX/MEM.B; spostando infatti lo stallo che si trova dopo la fase EX della store prima della EX stessa, non si avranno problemi di sovrascrittura e di conflitti di memoria.

Page 136: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 8

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 137: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 9

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 138: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 10

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 139: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 11

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 140: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 12

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

MEM2 Mem[MEM/WB.B] MEM/WB.LMD; L’istruzione viene eseguita in 5 colpi di clock, risparmiandone 1 rispetto alla sua scissione in 2 istruzioni. Ci sarà inevitabilmente uno stallo con l’istruzione schedulata un colpo di clock dopo se questa istruzione è una load o una store che fa uso effettivo della memoria.

In alternativa, si poteva utilizzare al posto del nuovo registro MEM/WB.B lo stesso registro MEM/WB.ALUOutput: quando SWP è in fase MEM2 leggerà il contenuto di questo registro all’inizio del primo semiciclo e salverà in memoria LMD (a quell’indirizzo) per tutto il resto del ciclo di clock; se l’operazione successiva alla SWP fosse una ALU starebbe eseguendo la sua fase di MEM in cui ALUOutput viene propagato dai latch EX/MEM e MEM/WB, però MEM/WB.ALUOutput viene scritto solo nel secondo semiciclo. Quindi non c’è problema di sovrascrittura.

Page 141: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 13

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 142: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 14

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 143: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 15

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 144: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 16

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 145: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 17

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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

Page 146: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 18

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESERCIZI ASSEMBLY

ESERCIZI ASSEMBLY

Page 147: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 19

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESERCIZIO 1 – SOMMA DI DUE VETTORI Somma di due vettori in un terzo vettore con processore scalare pipeline MIPS. Si vuole scrivere un programma assembly per un processore MIPS scalare pipeline che sommi due vettori di dati double contenuti in memoria e salvi il risultato in un terzo vettore. Siano A, B e C vettori di N elementi, l’operazione da svolgere è: for(i=0; i<N; i++) { C[i] = A[i] + B[i]; } Il primo risparmio lo si può pensare sui registri: l’utilizzo di un unico registro come indice che scorre all’interno del vettore man mano che vengono svolte le somme riduce il numero di registri in gioco. Si ipotizza dunque di conoscere le locazioni in memoria dei tre vettori, cioè le locazioni in memoria dei primi elementi dei tre vettori: supponiamo A*0+ all’indirizzo 1000, B*0+ all’indirizzo 2000 e C*0+ all’indirizzo 3000.

Utilizziamo il registro R1 come indice, il quale dovrà essere incrementato di 8 (operiamo su vettori double) ad ogni iterazione. In realtà, se si pensa di inizializzare R1 al valore dell’ultimo elemento del vettore, è possibile usare una BGEZ su R1 come condizione per il loop, così che se è verificata (se R1 è maggiore o uguale a 0) si salta all’inizio del loop. In questo modo R1 dovrà essere decrementato di 8 ad ogni iterazione. R1 dovrà dunque essere inizializzato al valore (N-1)*8, essendo questo il valore occupato in memoria da ciascuno dei tre vettori. Dunque le prime tre istruzioni serviranno ad inizializzare il valore di R1 e saranno operazioni esterne al loop.

Page 148: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 20

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

DADDI R1, R0, N DADDI R1, R1, #-1 DMULI R1, R1, #8 Successivamente, scriviamo il loop. All’inizio del loop mettiamo l’etichetta loop per identificare la prima operazioni ove si dovrà saltare se verificata la condizione di salto. Le prime due operazioni saranno due load per caricare gli elementi dei vettori dalla memoria nei registri: supponiamo R2 sia destinato a contenere A ed R3 sia destinato a contenere B. loop: LD R2, R1(1000) LD R3, R1(2000) Procediamo con la somma dei due elementi. Potremmo utilizzare il registro R4 per contenere C, ma risulterebbe un’inutile spreco di registri in quanto sia R2 che R3 non saranno più utilizzati nel corso dell’iterazione. Scegliamo dunque di salvare C in R2. DADDI R2, R2, R3 Salviamo C in memoria. SD R1(3000), R2 Procediamo con il decremento dell’indice di 8 e con la condizione di salto. DADDI R1, R1, #-8 BGEZ R1, loop Il programma in assembly risulta essere:

DADDI R1, R0, N DADDI R1, R1, #-1 DMULI R1, R1, #8

loop: LD R2, R1(1000) LD R3, R1(2000) DADDI R2, R2, R3 SD R1(3000), R2 DADDI R1, R1, #-8 BGEZ R1, loop

Tale listato è decisamente inaccettabile, in quanto ci saranno numerosi stalli. Supponendo che il nostro processore abbia già le modifiche necessarie alla cortocircuitazione dell’ALU, e un sommatore aggiuntivo per effettuare il calcolo del PC dove saltare dopo un’istruzione di brench/jump perdendo solo un colpo di clock, la situazione è la seguente:

Page 149: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 21

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Calcoliamo in quanti colpi di clock viene eseguito questo programma in pipeline. Le istruzioni all’interno del loop sono 6 più 3 stalli, cioè 9 istruzioni. L’esecuzione impiegherà: Numero di colpi di clock per eseguire 1 istruzione + (numero di istruzioni -1) = 5 + (9-1) = 13 colpi di clock. Questi 13 colpi di clock valgono per’un'unica istruzione. Considerando il loop, le 9 istruzioni dovranno essere moltiplicate per il numero di iterazioni, cioè N. Quindi ((9*N)-1)+5. A questi, andranno sommati i colpi di clock necessari per eseguire le tre istruzioni precedenti il loop: Numero di colpi di clock per eseguire 1 istruzione + (Numero di istruzioni precedenti il loop – 1) + 1 istruzione (la prima del loop) - Numero di colpi di clock per eseguire 1 istruzione = = 5 + (3-1) – 5 + 1 = 3 Supponendo vettori di 10 elementi, il programma impiega 3 + 5 + (9*10)-1) = 97 colpi di clock per essere eseguito.

Per ottimizzare il programma è quindi necessario spostare alcune istruzioni utilizzando la tecnica del delay slot. Spostiamo il decremento dell’indice dopo la seconda load, in questo modo anche lo stallo che segue quest’istruzione viene eliminato. Spostiamo inoltre la store dopo la bnez, con l’accortezza di cambiare l’indirizzo da sommare all’indice R1, in quanto R1 è già stato decrementato di 8: dunque, per ottenere lo stesso indirizzo di memoria, si incrementa di 8 l'indirizzo nella store

Page 150: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 22

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

DADDI R1, R0, N DADDI R1, R1, #-1 DMULI R1, R1, #8

loop: LD R2, R1(1000) LD R3, R1(2000) DADDI R1, R1, #-8 DADDI R2, R2, R3 BGEZ R1, loop SD R1(3008), R2

Il loop viene eseguito in 5 + (6 -1) = 10 colpi di clock, quindi supponendo vettori di 10 elementi, il programma viene eseguito in 3 + 5 + ((6*10)-1) = 67 colpi di clock, 30 in meno rispetto a quelli utilizzati per processare il listato con gli stalli.

Page 151: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 23

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESERCIZIO 2 – MEDIA DI UN VETTORE Scrivere la procedura che calcoli la media di un vettore di dimensione N. Suppongo che il vettore A sia contenuto in memoria a partire dall’indirizzo 1000 e alla procedura viene passato questo indirizzo e la dimensione N del vettore che viene considerato come un immediato nel listato. Utilizzo il registro R1 come indice, per contenere la dimensione del vettore in byte e poter scorrere ogni elemento. Utilizzo R2 come registro per contenere la somma degli elementi del vettore, valore che poi verrà restituito dalla procedura (non si richiede una store in memoria). Utilizzo R3 come registro temporaneo per caricare da memoria ogni elemento del vettore A.

DADDI R1, R0, #N DADDI R1, R1, #-1 DMULI R1, R1, #8 DADDI R2, R0, #0

loop: LD R3, R1(1000) DADD R2, R2, R3 DADDI R1, R1, #-8 BGEZ R1, loop DDIVI R2, R2, #N // NB: la DDIVI mi sa che non esiste Analizziamo gli stalli (ipotizzando che il processore abbia già le modifiche per la corto circuitazione dell’ALU).

DADDI R1, R0, #N DADDI R1, R1, #-1 DMULI R1, R1, #8 DADDI R2, R0, #0

loop: LD R3, R1(1000) stallo DADD R2, R2, R3 DADDI R1, R1, #-8 stallo BGEZ R1, loop stallo DDIVI R2, R2, #N Il primo stallo si ha perché uno degli operandi della DADD (R3) è registro di destinazione dell’operazione di load precedente. Il corretto valore di R3 lo si avrà solo quando questo sarà stato salvato in MEM/WB.LMD, quindi dopo la fase di MEM, mentre la somma successiva viene eseguita nella fase di EXE, che non avrà ancora il valore di R3. Il secondo stallo si ha perché il registro su cui verificare la condizione di branch è destinazione dell’operazione precedente, che sarà disponibile in EX/MEM.ALUOutput solo dopo la fase di EX; contemporaneamente la branch starà eseguendo la ID, fase in cui si verifica la condizione e si calcola il nuovo PC ove saltare. Il terzo stallo si verifica in quanto è possibile scoprire dove saltare solo dopo la fase di ID della branch, quindi al secondo colpo di clock; intanto sarà partita l’istruzione successiva che, se il salto si verifica, dovrà essere abortita. Quindi c’è uno stallo.

Page 152: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 24

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Supponendo un vettore di 10 elementi il programma viene eseguito in: loop (5+(7*10)-1)) = 74 colpi di clock 74 + 5 istuzioni fuori dal loop = 79 colpi di clock Per ottimizzare il programma è quindi necessario spostare alcune istruzioni utilizzando la tecnica del delay slot.

DADDI R1, R0, #N DADDI R1, R1, #-1 DMULI R1, R1, #8 DADDI R2, R0, #0 LD R3, R1(1000)

loop: DADDI R1, R1, #-8 DADD R2, R2, R3 BGEZ R1, loop LD R3, R1(1000) DDIVI R2, R2, #N

Supponendo un vettore di 10 elementi il programma viene eseguito in: loop (5+(4*10)-1)) = 44 colpi di clock 44 + 6 istuzioni fuori dal loop = 50 colpi di clock Si noti che dopo l’ultima iterazione, l’operazione di LOAD verrà comunque eseguita e verrà caricato in R3 un valore di memoria non interessante ai fini del programma. Questo, in ogni caso, non comporta gravi errori. Altrimenti, si può abortire l’operazione di load se il salto non si verifica.

Page 153: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 25

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESERCIZIO 3 – MINIMO DI UN VETTORE Scrivere la procedura che calcoli l’elemento minimo di un vettore di dimensione N. Suppongo che il vettore A sia contenuto in memoria a partire dall’indirizzo 1000 e alla procedura viene passato questo indirizzo e la dimensione N del vettore che viene considerato come un immediato nel listato. Utilizzo il registro R1 come indice, per contenere la dimensione del vettore in byte e poter scorrere ogni elemento. Utilizzo R2 come registro per contenere l’elemento più piccolo del vettore, valore che poi verrà restituito dalla procedura (non si richiede una store in memoria). Utilizzo R3 come registro temporaneo per caricare da memoria ogni elemento del vettore A. Utilizzo R4 come registro temporaneo per la sottrazione tra l’elemento i-esimo del vettore A con il minimo memorizzato nel registro R2. Tale operazione è utile al fine di verificare se l’elemento i-esimo è più piccolo dell’elemento finora considerato minimo.

DADDI R1, R0, #N DADDI R1, R1, #-1 DMULI R1, R1, #8

LD R2, R1(1000) loop: LD R3, R1(1000) DSUB R4, R3, R2

DADDI R1, R1, #-8 BGEZ R4, if DADDI R2, R3, #0

if: BGEZ R1, loop Analizziamo gli stalli (ipotizzando che il processore abbia già le modifiche per la corto circuitazione dell’ALU).

DADDI R1, R0, #N DADDI R1, R1, #-1 DMULI R1, R1, #8

LD R2, R1(1000) loop: LD R3, R1(1000) stallo DSUB R4, R3, R2

DADDI R1, R1, #-8 BGEZ R4, if stallo DADDI R2, R3, #0

if: BGEZ R1, loop stallo Il primo stallo si ha perché uno degli operandi della DSUB (R3) è registro di destinazione dell’operazione di load precedente. Il corretto valore di R3 lo si avrà solo quando questo sarà stato salvato in MEM/WB.LMD, quindi dopo la fase di MEM, mentre la somma successiva viene eseguita nella fase di EXE, che non avrà ancora il valore di R3. Il secondo ed il terzo stallo si verificano in quanto è possibile scoprire dove saltare solo dopo la fase di ID della branch, quindi al secondo colpo di clock; intanto sarà partita l’istruzione successiva che, se il salto si verifica, dovrà essere abortita.

Page 154: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 26

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Supponendo un vettore di 10 elementi, possiamo scindere il calcolo dei colpi di clock in due casi:

best case quando il valore minimo del vettore è l’ultimo elemento (e quindi viene schedulato per primo) e i restanti elementi sono tutti maggiori o uguali al primo: in questo caso si risparmia un’istruzione in quanto il branch BGEZ R4, if sarà sempre verificato;

worste case quando il valore minimo del vettore è il primo elemento (e quindi viene schedulato per ultimo) e i restanti elementi sono posizionati nel vettore in ordine decrescente, cosicché ad ogni iterazione l’i-esimo elemento verrà sempre considerato come elemento minimo ed il branch BGEZ R4, if non sarà mai verificato, eseguendo anche l’istruzione DADDI R2, R3, #0 di scambio dei registri.

BEST CASE 8 istruzioni per ogni loop. 5 + (8*10) -1 = 84 colpi di clock + 4 istruzioni fuori dal loop = 88 colpi di clock. WORSTE CASE 8 istruzioni alla prima iterazione (l’ultimo elemento di A è già caricato in R2 prima del loop) e 9 istruzioni per il resto delle iterazioni. 5 + 8 + (9*9)-1 = 93 colpi di clock + 4 istruzioni fuori dal loop = 97 colpi di clock. Per ottimizzare il programma è quindi necessario spostare alcune istruzioni utilizzando la tecnica del delay slot.

DADDI R1, R0, #N DADDI R1, R1, #-1 DMULI R1, R1, #8

LD R2, R1(1000) stallo DADDI R3, R2, #0 loop: DSUB R4, R3, R2

DADDI R1, R1, #-8 BGEZ R4, if DADDI R2, R3, #0

if: BGEZ R1, loop LD R3, R1(1000)

Nello spostare la load nel delay slot dopo l’ultima branch e duplicandola prima del loop, si è preferito utilizzare una DADDI per copiare il valore di R2 in R3 in quanto l’elemento è già stato caricato in memoria. Non è possibile riempire il delay slot dopo la LD R2, R1(1000), ma essendo uno stallo fuori dal loop non la si ritiene una grave perdita di prestazioni. È importante ricordarsi che:

spostando la DADDI R2, R3, #0 nel delay slot dopo la BGEZ R4, if tale istruzione dev’essere abortita nel caso il salto si verifichi;

spostando la LD R3, R1(1000) nel delay slot dopo la BGEZ R1, loop tale istruzione dev’essere abortita nel caso il salto non si verifichi.

Supponendo un vettore di 10 elementi il programma viene eseguito in: BEST CASE = WORSTE CASE i due casi si riducono ad un unico caso in quanto le istruzioni verranno sempre e comunque eseguite tutte, ma alcune verranno abortite nei casi precedentemente illustrati. 6 istruzioni per ogni loop. 5 + (6*10) – 1 = 64 colpi di clock + 6 istruzioni fuori dal loop = 70 colpi di clock.

Page 155: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 27

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Alternativamente, si può procedere in questo modo. Invece di settare R2 (valore massimo) pari al primo elemento schedulato, prima di entrare nel loop, lo si pone uguale al massimo numero rappresentabile con un registro a 64 bit. Considerando la notazione del complemento a due per i numeri negativi, c’è da scartare il primo bit che è il bit di segno. Dunque, con 64 bit a disposizione, il numero maggiore rappresentabile è: 264-1-1= 9223372036854775807. Assumiamo MAX=264-1-1 come un valore immediato.

DADDI R1, R0, #N DADDI R1, R1, #-1 DMULI R1, R1, #8

LD R3, R1(1000) DADDI R2, R0, #MAX loop: DSUB R4, R3, R2

DADDI R1, R1, #-8 BGEZ R4, if DADDI R2, R3, #0

if: BGEZ R1, loop LD R3, R1(1000) Con questa soluzione, il programma viene eseguito in: 6 istruzioni per ogni loop. 5 + (6*10) – 1 = 64 colpi di clock + 5 istruzioni fuori dal loop = 69 colpi di clock.

Page 156: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 28

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESERCIZIO 4 – LOAD DOUBLE NON ALLINEATA Scrivere la procedura che esegua una LOAD double non allineata. Si vuole scrivere una procedura che carichi da memoria un dato double da 64 bit il cui indirizzo non è multiplo di 8. Il caricamento dei dati da memoria a registro o da registro a memoria avviene a blocchi di 64 bit (8 byte) a partire da indirizzi che sono sempre divisibili per 8. In questo caso, si vuole caricare un dato che è contenuto in due blocchi di memoria, allineandolo successivamente poi in un unico registro. Supponiamo che il dato si trovi all’indirizzo di partenza IND passato come parametro alla routine. La prima cosa da fare è verificare effettivamente se questo indirizzo non è il primo di un blocco da 64 che può essere caricato in un registro con una semplice LOAD. Questa caratteristica imporrà all’indirizzo, nel caso sia il primo di un blocco allineato, di essere divisibile per 8. Se non lo è, ovviamente, procediamo con la routine. Tale verifica è eseguibile semplicemente osservando gli ultimi tre bit dell’indirizzo. Se questi sono uguali a zero allora il numero sarà divisibile per 8. Dunque, sarà sufficiente mettere l’indirizzo in AND con il numero binario 7 (111) e verificare se tale risultato è uguale a zero: se lo è, si esce dalla routine e si passa al processo principale; altrimenti, si esegue la load non allineata. Dopo la and bisognerà fare la condizione su R1 per vedere se è uguale a zero. Se lo è, la routine termina. Quindi, prima di far terminare la routine, è necessario aver fatto la load del double nel caso il dato sia allineato. L’indirizzo di partenza non dovrà essere IND, ma IND – R1 essendo R1 lo scostamento dall’indirizzo XXX000 che è il primo del blocco da 64 bit che vogliamo caricare. ANDI R1, IND, #7 DSUB IND, IND, R1 LD R2, #0(IND) BEQZ R1, end Continuando la routine, carichiamo l’altro blocco da 8 byte (8 byte = 64 bit!). LD R3, #8(IND) Caricati I due dati da 8 byte in due registri diversi, bisognerà ora fare lo shift di questi dati rispettivamente verso sinistra per il primo registro R2 e verso destra per il secondo registro R3 per poi infine fare la OR tra i due registri.

Page 157: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 29

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

R2 lo shifteremo di tanti posti quanto è lo scostamento R1 moltiplicato per 8 bit (quindi R1 byte per 8 bit). R3 lo shifteremo di tanti posti quanto è lo scostamento 8 byte – R1 moltiplicato per 8 bit (quindi R1 byte per 8 bit). Infine, si procede con l’OR tra i due registri.

DMULT R4, R1, #8 DSLLV R2, R2, R4 DADDI R4, R0, #8 DSUB R1, R4, R1 DMULT R4, R1, #8 DSRLV R3, R3, R1 OR R2, R2, R3 end Il listato completo è: ANDI R1, IND, #7 DSUB IND, IND, R1 LD R2, #0(IND) BEQZ R1, end LD R3, #8(IND) DMULT R4, R1, #8 DSLLV R2, R2, R4 DADDI R4, R0, #8 DSUB R1, R4, R1 DMULT R4, R1, #8 DSRLV R3, R3, R1 OR R2, R2, R3 End L’unico stallo è quello solito presente dopo la BEQZ, eliminabile spostando la LD R3, #8(IND) nel delay slot. Ovviamente, se la condizione si verifica tale operazione dev’essere abortita. Il programma viene eseguito (considerando il caso in cui la load non sia allineata) in: 12 istruzioni. 5 + (12 – 1) = 16 colpi di clock.

Page 158: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 30

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESERCIZIO 5 – STORE DOUBLE NON ALLINEATA Scrivere la procedura che esegua una STORE double non allineata. Si vuole scrivere una procedura che salvi un dato double da 64 in memoria ad un indirizzo che non è multiplo di 8.

Supponiamo il che il dato da voler scrivere in memoria si trovi nel registro R10 e che la locazione in memoria ove scriverlo, all’indirizzo IND, sia passata come parametro alla routine. ANDI R1, IND, #7 DSUB IND, IND, R1 BEQZ R1, end SD #0(IND), R11 Lo stallo dovuto alla BEQZ viene riempito con la store. Nel caso la BEQZ sia verificata, e l’indirizzo IND sia già allineato in memoria, allora questa store deve essere eseguita; nel caso in cui invece la BEQZ non è verificata e l’indirizzo IND non è un multiplo di 8, questa store deve essere abortita con la perdita di un colpo di clock. Non volendo sovrascrivere il contenuto degli altri indirizzi non interessati alla store, ma che comunque fanno parte dei due blocchi da 64 bit in cui la store dovrà operare, è necessario andare a caricare nei registri tali valori e porli infine in OR con il dato da voler salvare, opportunamente shiftato. Avremo dunque bisogno, oltre che del registro R10 che contiene il dato, la sua copia nel registro R11, in modo tale da shiftare R10 verso destra (parte alta del dato) ed R11 verso sinistra (parte bassa del dato). Saranno questi i registri da porre in OR con R2 ed R3. LD R2, #0(IND) LD R3, #8(IND) Copiamo R10 in R11. DADD R11, R10, R0

Page 159: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 31

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Shift di R10 verso destra. DMULT R4, R1, #8 DSRLV R10, R0, R4 Shift di R11 verso sinistra. DADDI R4, R0, #8 DSUB R1, R4, R1 DMULT R4, R1, #8 DSLLV R11, R11, R1 OR logico. OR R2, R2, R10 OR R3, R3, R10 Store dei dati. SD #0(IND), R2 SD #8(IND), R3 end Il listato completo è: ANDI R1, IND, #7 DSUB IND, IND, R1 BEQZ R1, end SD #0(IND), R11 LD R2, #0(IND) LD R3, #8(IND) DADD R11, R10, R0 DMULT R4, R1, #8 DSRLV R10, R0, R4 DADDI R4, R0, #8 DSUB R1, R4, R1 DMULT R4, R1, #8 DSLLV R11, R11, R1 OR R2, R2, R10 OR R3, R3, R10 SD #0(IND), R2 SD #8(IND), R3 end Il programma viene eseguito (considerando il caso in cui la store non sia allineata) in: 17 istruzioni. 5 + (17 – 1) = 21 colpi di clock.

Page 160: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 32

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESERCIZIO 6 – SOMMA DI VETTORI – PIPELINE DA PROGRAMMA Somma di vettori con il metodo della pipeline da programma. Suppongo che l'indirizzo del primo elemento del vettore A sia 1000, l'indirizzo del primo elemento del vettore B sia 2000, l'indirizzo del primo elemento del vettore C sia 3000. Suppongo che in R1 mi venga passato come parametro alla procedura la dimensione del vettore che userò come indice (dal fondo verso la testa del vettore). Uso R2 ed R3 per salvare gli i-esimi elementi del vettore. Uso R4 ed R5 per salvare gli i-esimi – 1 elementi del vettore (partiamo dalla coda). Uso R6 per salvare gli i-esimi elementi della somma tra i vettori. Uso R7 per salvare gli i-esimi – 1 elementi della somma tra i vettori. Uso R8 come condizione sul branch ponendolo uguale a 8. Quando l’indice arriva a 8 devo uscire dal loop.

DADDI R8,R0, #8 // pongo R8 = 8 DADDI R1, R1, #-1 // mi posiziono all’ultimo elemento (N-1)x8byte DMULI R1, R1, #8 LD R2, R1(1000) // riempimento LD R3, R1(2000) LD R4, R1(992) LD R5, R1(1992) DADD R6, R2, R3

loop: LD R2, R1(984) LD R3, R1(1984) DADD R7,R4,R5 DADDI R4, R2, #0 // scambio dei registri DADDI R5, R3, #0 SD R1(3000), R6 DADDI R6, R7, #0 DADDI R1, R1, #-8 // decremento l'indice BNE R1, R8, loop DADD R7, R4, R5 // svuotamento SD 0(3008), R6 SD 0(3000), R7

Come è facile notare, e come era prevedibile dalla pipeline da programma, non ci sono stalli per via di conflitti di dato. Si considera sempre la corto circuitazione dell’ALU per DADDI R1, R1, #-1 DMULI R1, R1, #8

Page 161: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 33

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ALGORITMO DI TOMASULO

ESERCIZI ALGORITMO TOMASULO

Page 162: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 34

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESERCIZIO 1 Si consideri una CPU con le seguenti unità funzionali:

- 3 Sommatori con latenza di 2 colpi di clock; - 2 Moltiplicatori con latenza di 4 colpi di clock sia per la moltiplicazione che per la divisione; - 3 Accessi a memoria con latenza di 2 colpi di clock.

Eseguire colpo di clock dopo colpo di clock l’algoritmo di Tomasulo per il seguente programma:

LD F6 0+ R1

LD F8 2+ R2

MULTD F4 F8 F2

DIVD F8 F8 F0

ADDD F10 F10 F4

SUBD F2 F8 F0

CLOCK 1

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address

LD F6 0+ R1 1 Load1 Yes 0+R1

LD F8 2+ R2 Load2 No

MULTD F4 F8 F2 Load3 No

DIVD F8 F8 F0

ADDD F10 F10 F4

SUBD F2 F8 F0

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 No

Add2 No

Add3 No

Mult1 No

Mult2 No

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...1 FU Load1

Page 163: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 35

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

CLOCK 2

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address

LD F6 0+ R1 1 Load1 Yes 0+R1

LD F8 2+ R2 2 Load2 Yes 2+R2

MULTD F4 F8 F2 Load3 No

DIVD F8 F8 F0

ADDD F10 F10 F4

SUBD F2 F8 F0

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 No

Add2 No

Add3 No

Mult1 No

Mult2 No

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...2 FU Load1 Load2

CLOCK 3

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address

LD F6 0+ R1 1 3 Load1 Yes 0+R1

LD F8 2+ R2 2 Load2 Yes 2+R2

MULTD F4 F8 F2 3 Load3 No

DIVD F8 F8 F0

ADDD F10 F10 F4

SUBD F2 F8 F0

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 No

Add2 No

Add3 No

Mult1 Yes MULTD R(F2) Load2

Mult2 No

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...3 FU Load1 Load2

Page 164: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 36

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address

LD F6 0+ R1 1 3 4 Load1 No

LD F8 2+ R2 2 4 Load2 Yes 2+R2

MULTD F4 F8 F2 3 Load3 No

DIVD F8 F8 F0 4

ADDD F10 F10 F4

SUBD F2 F8 F0

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 No

Add2 No

Add3 No

Mult1 Yes MULTD R(F2) Load2

Mult2 Yes DIVD R(F0) Load2

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...4 FU Mult1 M(A1) Load2

CLOCK 4: Al monitor dei registri rimane sempre Load2 su F8, perché effettivamente F8 non è ancora

disponibile; al colpo di clock successivo F8 sarà disponibile, e dal CDB va direttamente alle unità funzionali per far si che possono essere eseguite sia la MULTD che la DIVD; quindi queste due operazioni partiranno CONTEMPORANEAMENTE. Per cui il monitor dei registri viene aggiornato al cc successivo con F8: MULTD

CLOCK 5:

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address

LD F6 0+ R1 1 3 4 Load1 No

LD F8 2+ R2 2 4 5 Load2 No

MULTD F4 F8 F2 3 Load3 No

DIVD F8 F8 F0 4

ADDD F10 F10 F4 5

SUBD F2 F8 F0

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 Yes ADDD R(F10) Mult1

Add2 No

Add3 No

4 Mult1 Yes MULTD F8 dal CDB R(F2)

4 Mult2 Yes DIVD F8 dal CDB R(F0)

Register result status:

Clock F0 F2 F4 F6 F8 F10 F125 FU Mult1 M(A1) Mult2 Add1

Page 165: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 37

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

CLOCK 6:

CLOCK 7-8: situazione invariata, decrementati i valori della colonna time

CLOCK 9:

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address

LD F6 0+ R1 1 3 4 Load1 No

LD F8 2+ R2 2 4 5 Load2 No

MULTD F4 F8 F2 3 Load3 No

DIVD F8 F8 F0 4

ADDD F10 F10 F4 5

SUBD F2 F8 F0 6

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 Yes ADDD R(F10) Mult1

Add2 Yes SUBD R(F0) Mult2

Add3 No

3 Mult1 Yes MULTD F8 dal CDB R(F2)

3 Mult2 Yes DIVD F8 dal CDB R(F0)

Register result status:

Clock F0 F2 F4 F6 F8 F10 F126 FU Add2 Mult1 M(A1) Mult2 Add1

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address

LD F6 0+ R1 1 3 4 Load1 No

LD F8 2+ R2 2 4 5 Load2 No

MULTD F4 F8 F2 3 9 Load3 No

DIVD F8 F8 F0 4 9

ADDD F10 F10 F4 5

SUBD F2 F8 F0 6

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 Yes ADDD R(F10) Mult1

Add2 Yes SUBD R(F0) Mult2

Add3 No

0 Mult1 Yes MULTD F8 dal CDB R(F2)

0 Mult2 Yes DIVD F8 dal CDB R(F0)

Register result status:

Clock F0 F2 F4 F6 F8 F10 F129 FU Add2 Mult1 M(A1) Mult2 Add1

Page 166: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 38

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

CLOCK 10:

CLOCK 11: situazione invariata, decrementati i valori della colonna time

CLOCK 12:

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address

LD F6 0+ R1 1 3 4 Load1 No

LD F8 2+ R2 2 4 5 Load2 No

MULTD F4 F8 F2 3 9 10 Load3 No

DIVD F8 F8 F0 4 9 10

ADDD F10 F10 F4 5

SUBD F2 F8 F0 6

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

2 Add1 Yes ADDD R(F10) M(A3)

2 Add2 Yes SUBD M(A4) R(F0)

Add3 No

Mult1 No

Mult2 No

Register result status:

Clock F0 F2 F4 F6 F8 F10 F1210 FU Add2 M(A3) M(A1) M(A4) Add1

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address

LD F6 0+ R1 1 3 4 Load1 No

LD F8 2+ R2 2 4 5 Load2 No

MULTD F4 F8 F2 3 9 10 Load3 No

DIVD F8 F8 F0 4 9 10

ADDD F10 F10 F4 5 12

SUBD F2 F8 F0 6 12

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

0 Add1 Yes ADDD R(F10) M(A3)

0 Add2 Yes SUBD M(A4) R(F0)

Add3 No

Mult1 No

Mult2 No

Register result status:

Clock F0 F2 F4 F6 F8 F10 F1212 FU Add2 M(A3) M(A1) M(A4) Add1

Page 167: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 39

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

CLOCK 13:

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address

LD F6 0+ R1 1 3 4 Load1 No

LD F8 2+ R2 2 4 5 Load2 No

MULTD F4 F8 F2 3 9 10 Load3 No

DIVD F8 F8 F0 4 9 10

ADDD F10 F10 F4 5 12 13

SUBD F2 F8 F0 6 12 13

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 No

Add2 No

Add3 No

Mult1 No

Mult2 No

Register result status:

Clock F0 F2 F4 F6 F8 F10 F1213 FU M(A5) M(A3) M(A1) M(A4) M(A6)

Page 168: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 40

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESERCIZIO 2

Si consideri una CPU con le seguenti unità funzionali:

- 3 Sommatori con latenza di 2 colpi di clock;

- 2 Moltiplicatori con latenza di 4 colpi di clock per la moltiplicazione e 10 colpi di clock per la

divisione;

- 3 Accessi a memoria con latenza di 2 colpi di clock.

-

Eseguire colpo di clock dopo colpo di clock l’algoritmo di Tomasulo per il seguente programma:

DIVD F0 F2 F4

ADDD F6 F0 F4

SD F6 0+ R1

SUBD F8 F10 F14

MULTD F6 F10 F14

CLOCK 1

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address Val

DIVD F0 F2 F4 1 Store1 No

ADDD F6 F0 F4 Store2 No

SD F6 0+ R1 Store3 No

SUBD F8 F10 F14

MULTD F6 F10 F14

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 No

Add2 No

Add3 No

10 Mult1 Yes DIVD F2 F4

Mult2 No

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...1 FU Mult1

Page 169: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 41

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

CLOCK 2

CLOCK 3

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address Val

DIVD F0 F2 F4 1 Store1 No

ADDD F6 F0 F4 2 Store2 No

SD F6 0+ R1 Store3 No

SUBD F8 F10 F14

MULTD F6 F10 F14

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 Yes ADDD R(F4) Mult1

Add2 No

Add3 No

9 Mult1 Yes DIVD R(F2) R(F4)

Mult2 No

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...2 FU Mult1 Add1

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address Val

DIVD F0 F2 F4 1 Store1 Yes 0+R1 Add1

ADDD F6 F0 F4 2 Store2 No

SD F6 0+ R1 3 Store3 No

SUBD F8 F10 F14

MULTD F6 F10 F14

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 Yes ADDD R(F4) Mult1

Add2 No

Add3 No

8 Mult1 Yes DIVD R(F2) R(F4)

Mult2 No

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...3 FU Mult1 Add1

Page 170: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 42

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

CLOCK 4

CLOCK 5: l’istruzione MULTD può partire senza problemi, anche se il destinazione F6 effettivamente non è

stato ancora calcolato dalla precedente istruzione ADDD, la quale attende il termine della DIVD. Questo è possibile perché la Store1 attenderà il valore non dal registro F6 ma direttamente dal sommatore Add1 (attraverso il CDB); quindi non vi è la necessità di scrivere il risultato prima in F6 e poi di effettuare la store. Detto questo l’istruzione MULTD può tranquillamente effettuare la sua operazione e scrivere il risultato in F6, senza provocare incoerenza di dati. Per cui nel monitor dei registri è possibile indicare Mult2 ad F6.

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address Val

DIVD F0 F2 F4 1 Store1 Yes 0+R1 Add1

ADDD F6 F0 F4 2 Store2 No

SD F6 0+ R1 3 Sotre3 No

SUBD F8 F10 F14 4

MULTD F6 F10 F14

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 Yes ADDD R(F4) Mult1

2 Add2 Yes SUBD R(F10) R(F14)

Add3 No

7 Mult1 Yes DIVD R(F2) R(F4)

Mult2 No

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...4 FU Mult1 Add1 Add2

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address Val

DIVD F0 F2 F4 1 Store1 Yes 0+R1 Add1

ADDD F6 F0 F4 2 Store2 No

SD F6 0+ R1 3 Store3 No

SUBD F8 F10 F14 4

MULTD F6 F10 F14 5

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 Yes ADDD R(F4) Mult1

1 Add2 Yes SUBD R(F10) R(F14)

Add3 No

6 Mult1 Yes DIVD R(F2) R(F4)

4 Mult2 Yes MULTDR(F10) R(F14)

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...5 FU Mult1 Mult2 Add2

Page 171: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 43

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

CLOCK 6

CLOCK 7

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address Val

DIVD F0 F2 F4 1 Store1 Yes 0+R1 Add1

ADDD F6 F0 F4 2 Store2 No

SD F6 0+ R1 3 Store3 No

SUBD F8 F10 F14 4 6

MULTD F6 F10 F14 5

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 Yes ADDD R(F4) Mult1

0 Add2 Yes SUBD R(F10) R(F14)

Add3 No

5 Mult1 Yes DIVD R(F2) R(F4)

3 Mult2 Yes MULTDR(F10) R(F14)

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...6 FU Mult1 Mult2 Add2

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address Val

DIVD F0 F2 F4 1 Store1 Yes 0+R1 Add1

ADDD F6 F0 F4 2 Store2 No

SD F6 0+ R1 3 Store3 No

SUBD F8 F10 F14 4 6 7

MULTD F6 F10 F14 5

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 Yes ADDD R(F4) Mult1

Add2 No

Add3 No

4 Mult1 Yes DIVD R(F2) R(F4)

2 Mult2 Yes MULTDR(F10) R(F14)

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...7 FU Mult1 Mult2 M(A1)

Page 172: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 44

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

CLOCK 8: situazione invariata, decremento colonna timer CLOCK 9

CLOCK 10

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address Val

DIVD F0 F2 F4 1 Store1 Yes 0+R1 Add1

ADDD F6 F0 F4 2 Store2 No

SD F6 0+ R1 3 Store3 No

SUBD F8 F10 F14 4 6 7

MULTD F6 F10 F14 5 9

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 Yes ADDD R(F4) Mult1

Add2 No

Add3 No

2 Mult1 Yes DIVD R(F2) R(F4)

0 Mult2 Yes MULTDR(F10) R(F14)

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...9 FU Mult1 Mult2 M(A1)

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address Val

DIVD F0 F2 F4 1 Store1 Yes 0+R1 Add1

ADDD F6 F0 F4 2 Store2 No

SD F6 0+ R1 3 Store3 No

SUBD F8 F10 F14 4 6 7

MULTD F6 F10 F14 5 9 10

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 Yes ADDD R(F4) Mult1

Add2 No

Add3 No

1 Mult1 Yes DIVD R(F2) R(F4)

Mult2 No

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...10 FU Mult1 M(A2) M(A1)

Page 173: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 45

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

CLOCK 11

CLOCK 12

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address Val

DIVD F0 F2 F4 1 11 Store1 Yes 0+R1 Add1

ADDD F6 F0 F4 2 Store3 No

SD F6 0+ R1 3 Store3 No

SUBD F8 F10 F14 4 6 7

MULTD F6 F10 F14 5 9 10

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 Yes ADDD R(F4) Mult1

Add2 No

Add3 No

0 Mult1 Yes DIVD R(F2) R(F4)

Mult2 No

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...11 FU Mult1 M(A2) M(A1)

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address Val

DIVD F0 F2 F4 1 11 12 Store1 Yes 0+R1 Add1

ADDD F6 F0 F4 2 Store2 No

SD F6 0+ R1 3 Store3 No

SUBD F8 F10 F14 4 6 7

MULTD F6 F10 F14 5 9 10

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

2 Add1 Yes ADDD M(A3) R(F4)

Add2 No

Add3 No

Mult1 No

Mult2 No

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...12 FU M(A3) M(A2) M(A1)

Page 174: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 46

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

CLOCK 13: situazione invariata, decremento colonna timer

CLOCK 14

CLOCK 15

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address Val

DIVD F0 F2 F4 1 11 12 Store1 Yes 0+R1 Add1

ADDD F6 F0 F4 2 14 Store2 No

SD F6 0+ R1 3 Store3 No

SUBD F8 F10 F14 4 6 7

MULTD F6 F10 F14 5 9 10

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

0 Add1 Yes ADDD M(A3) R(F4)

Add2 No

Add3 No

Mult1 No

Mult2 No

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...14 FU M(A3) M(A2) M(A1)

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address Val

DIVD F0 F2 F4 1 11 12 2 Store1 Yes 0+R1

Add1

dal

CDB

ADDD F6 F0 F4 2 14 15 Store2 No

SD F6 0+ R1 3 Store3 No

SUBD F8 F10 F14 4 6 7

MULTD F6 F10 F14 5 9 10

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 No

Add2 No

Add3 No

Mult1 No

Mult2 No

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...15 FU M(A3) M(A2) M(A1)

Page 175: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 47

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

CLOCK 16: situazione invariata, decremento del timer della Store1

CLOCK 17: la store si completa, non bisogna attendere nessun risultato; il buffer Store1 viene liberato al

colpo di clock successivo per poter essere eventualmente utilizzato.

Instruction status: Exec Write

Instruction j k Issue Comp Result Busy Address Val

DIVD F0 F2 F4 1 11 12 0 Store1 Yes 0+R1

Add1

dal

CDB

ADDD F6 F0 F4 2 14 15 Store2 No

SD F6 0+ R1 3 17 Store3 No

SUBD F8 F10 F14 4 6 7

MULTD F6 F10 F14 5 9 10

Reservation Stations: S1 S2 RS RS

Time Name Busy Op Vj Vk Qj Qk

Add1 No

Add2 No

Add3 No

Mult1 No

Mult2 No

Register result status:

Clock F0 F2 F4 F6 F8 F10 F12 ...17 FU M(A3) M(A2) M(A1)

Page 176: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 48

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESERCIZI ASSEMBLY – PROCESSORI SUPERSCALARI E VLIW

ESERCIZI ASSEMBLY PROCESSORI SUPERSCALARI E VLIW

Page 177: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 49

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESERCIZIO 1 Scrivere il codice srotolato di un programma che faccia il prodotto tra due vettori. Scrivere il codice per una CPU SCALARE, per una CPU VLIW e per una CPU SUPERSCALARE limitandosi prima a 20 registri e poi a 32 registri, riportando in quale caso si ha un miglioramento delle prestazioni (in percentuali). Si consideri un processore con registri a 32 bit e bus a 32 bit. Ogni CPU ha le seguenti caratteristiche: UNITA’ FUNZIONALI:

2 unità di accesso a memoria;

2 moltiplicatori/divisori;

1 sommatore/sottrattore;

LATENZA UNITA’:

LOAD: 2 colpi di clock

MOLTIPLICATORE: 10 colpi di clock

DIVISORE: 20 colpi di clock

SOMMATORE: 5 colpi di clock

Per la CPU VLIW si consideri il seguente formato istruzioni:

2 accessi a memoria;

2 operazioni FP;

1 operazione intera/branch

Page 178: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 50

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

Si ipotizzi A*0+ all’indirizzo 1000, B*0+ all’indirizzo 2000, C*0+ all’indirizzo 3000.

Si posiziona R1, l’indice, all’ultimo elemento del vettore ((N-1)x8).

CPU SCALARE CON 20 REGISTRI FP

1 LOOP: L.D F0,R1(1000)

2 L.D F2,R1(2000)

3 L.D F4,R1(992) ;1000 – 8 byte = 992

4 L.D F6,R1(1992) ;2000 – 8 byte = 1992

5 L.D F8,R1(984) ;1000 – 16 byte = 984

6 L.D F10,R1(1984) ;2000 – 16 byte = 1984

7 L.D F12,R1(976) ;1000 – 24 byte = 976

8 L.D F14,R1(1976) ;2000 – 24 byte = 1976

9 L.D F16,R1(968) ;1000 – 32 byte = 968

10 L.D F18,R1(1968) ;2000 – 32 byte = 1968

11 MUL.D F0,F0,F2

12 MUL.D F4,F4,F6

13 MUL.D F8,F8,F10

14 MUL.D F12,F12,F14

16 MUL.D F16,F16,F18

17 DADDI R1,R1,#-40

18 STALLO

19 STALLO

20 STALLO

21 STALLO

22 S.D R1(3040),F0

23 S.D R1(3032),F4

24 S.D R1(3024),F8

25 S.D R1(3016),F12

26 BGEZ R1,LOOP

28 S.D R1(2968),F16

5 risultati in 28 colpi di clock, oppure 5.6 colpi di clock per iterazione.

Page 179: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 51

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

CPU VLIW CON 20 REGISTRI FP

Mem Reference1 Mem Reference2 FP op1 FP op2 Int/branch

1 LOOP: L.D F0,R1(1000) L.D F2,R1(2000) noop noop noop

2 L.D F4,R1(992) L.D F6,R1(1992) noop noop noop

3 L.D F8,R1(984) L.D F10,R1(1984) MUL.D F0,F0,F2 noop noop

4 L.D F12,R1(976) L.D F4,R1(1976) MUL.D F4,F4,F6 noop noop

5 L.D F16,R1(968) L.D F18,R1(1968) MUL.D F8,F8,F10 noop noop

6 noop noop MUL.D F12,F12,F14 noop DADDI R1,R1,#-40

7 noop noop MUL.D F16,F16,F18 noop noop

8 STALLO

9 STALLO

10 STALLO

11 STALLO

12 STALLO

13 S.D R1(3040),F0 noop noop noop noop

14 S.D R1(3032),F4 noop noop noop noop

16 S.D R1(3024),F8 noop noop noop noop

17 S.D R1(3016),F12 noop noop noop BGEZ R1,LOOP

18 S.D R1(2968),F16 noop noop noop noop

5 risultati in 18 colpi di clock, oppure 3.6 colpi di clock per iterazione.

CPU SUPERSCALARE CON 20 REGISTRI FP

1 LOOP: L.D F0,R1(1000) noop

2 L.D F2,R1(2000) noop

3 L.D F4,R1(992) noop

4 L.D F6,R1(1992) MUL.D F0,F0,F2

5 L.D F8,R1(984) noop

6 L.D F10,R1(1984) MUL.D F4,F4,F6

7 L.D F12,R1(976) noop

8 L.D F14,R1(1976) MUL.D F8,F8,F10

9 L.D F16,R1(968) noop

10 L.D F18,R1(1968) MUL.D F12,F12,F14

11 DADDI R1,R1,#-40 noop

12 noop MUL.D F16,F16,F18

13 STALLO

14 S.D R1(3040),F0 noop

16 S.D R1(3032),F4 noop

17 S.D R1(3024),F8 noop

18 S.D R1(3016),F12 noop

19 BGEZ R1,LOOP noop

20 S.D R1(2968),F16 noop

5 operazioni in 20 colpi di clock, oppure 4 colpi di clock per iterazione.

Page 180: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 52

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

CPU SCALARE CON 32 REGISTRI FP

1 LOOP: L.D F0,R1(1000)

2 L.D F2,R1(2000)

3 L.D F4,R1(992) ;1000 – 8 byte = 992

4 L.D F6,R1(1992) ;2000 – 8 byte = 1992

5 L.D F8,R1(984) ;1000 – 16 byte = 984

6 L.D F10,R1(1984) ;2000 – 16 byte = 1984

7 L.D F12,R1(976) ;1000 – 24 byte = 976

8 L.D F14,R1(1976) ;2000 – 24 byte = 1976

9 L.D F16,R1(968) ;1000 – 32 byte = 968

10 L.D F18,R1(1968) ;2000 – 32 byte = 1968

11 L.D F20,R1(960) ;1000 – 40 byte = 960

12 L.D F22,R1(1960) ;2000 – 40 byte = 1960

13 L.D F24,R1(952) ;1000 – 48 byte = 952

14 L.D F26,R1(1952) ;2000 – 48 byte = 1952

15 L.D F28,R1(944) ;1000 – 56 byte = 944

16 L.D F30,R1(1944) ;2000 – 56 byte = 944

17 MUL.D F0,F0,F2

18 MUL.D F4,F4,F6

19 MUL.D F8,F8,F10

20 MUL.D F12,F12,F14

21 MUL.D F16,F16,F18

22 MUL.D F20,F20,F22

23 MUL.D F24,F24,F26

24 MUL.D F28,F28,F30

25 DADDI R1,R1,#-64

26 STALLO

27 S.D R1(3064),F0

28 S.D R1(3056),F4

29 S.D R1(3048),F8

30 S.D R1(3040),F12

31 S.D R1(3032),F16

32 S.D R1(3024),F20

33 S.D R1(3016),F24

34 BGEZ R1,LOOP

35 S.D R1(2944),F24

8 risultati in 35 colpi di clock, oppure 4.3 colpi di clock per iterazione.

Page 181: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 53

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

CPU VLIW CON 32 REGISTRI FP

Mem Reference1 Mem Reference2 FP op1 FP op2 Int/branch

1 LOOP: L.D F0,R1(1000) L.D F2,R1(2000) noop noop noop

2 L.D F4,R1(992) L.D F6,R1(1992) noop noop noop

3 L.D F8,R1(984) L.D F10,R1(1984) MUL.D F0,F0,F2 noop noop

4 L.D F12,R1(976) L.D F14,R1(1976) MUL.D F8,F8,F10 noop noop

5 L.D F16,R1(968) L.D F18,R1(1968) MUL.D F12,F12,F14 noop noop

6 L.D F20,R1(960) L.D F22,R1(1960) MUL.D F16,F16,F18 noop noop

7 L.D F24,R1(952) L.D F26,R1(1952) MUL.D F20,F20,F22 noop noop

8 L.D F28,R1(944) L.D F30,R1(1944) MUL.D F24,F24,F26 noop noop

9 noop noop MUL.D F28,F28,F30 noop DADDIR1,R1,#-64

10 STALLO

11 STALLO

12 STALLO

13 S.D R1(3064),F0 noop noop noop noop

14 S.D R1(3056),F4 noop noop noop noop

15 S.D R1(3048),F8 noop noop noop noop

16 S.D R1(3040),F12 noop noop noop noop

17 S.D R1(3032),F16 noop noop noop noop

18 S.D R1(3024),F20 noop noop noop noop

19 S.D R1(3016),F24 noop noop noop BGEZ R1,LOOP

20 S.D R1(2944),F24 noop noop noop noop

8 risultati in 20 colpi di clock, oppure 2.5 colpi di clock per iterazione.

Page 182: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 54

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

CPU SUPERSCALARE CON 32 REGISTRI FP

1 LOOP: L.D F0,R1(1000) noop

2 L.D F2,R1(2000) noop

3 L.D F4,R1(992) noop

4 L.D F6,R1(1992) MUL.D F0,F0,F2

5 L.D F8,R1(984) noop

6 L.D F10,R1(1984) MUL.D F4,F4,F6

7 L.D F12,R1(976) noop

8 L.D F14,R1(1976) MUL.D F8,F8,F10

9 L.D F16,R1(968) noop

10 L.D F18,R1(1968) MUL.D F12,F12,F14

11 L.D F20,R1(960) noop

12 L.D F22,R1(1960) MUL.D F16,F16,F18

13 L.D F24,R1(952) noop

14 L.D F26,R1(1952) MUL.D F20,F20,F22

15 L.D F28,R1(944) noop

16 L.D F30,R1(1944) MUL.D F24,F24,F26

17 DADDI R1,R1,#-64 noop

18 S.D R1(3064),F0 MUL.D F28,F28,F30

19 S.D R1(3056),F4 noop

20 S.D R1(3048),F8 noop

21 S.D R1(3040),F12 noop

22 S.D R1(3032),F16 noop

23 S.D R1(3024),F20 noop

24 S.D R1(3016),F24 noop

25 BGEZ R1,LOOP noop

26 S.D R1(2944),F24 noop

8 operazioni in 26 colpi di clock, oppure 3.25 colpi di clock per iterazione.

Page 183: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 55

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESERCIZI ASSEMBLY DLXV

ESERCIZI ASSEMBLY DLXV

Page 184: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 56

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESERCIZIO 1 – SOMMA VETTORI DA 64 ELEMENTI Somma di due vettori da 64 elementi 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 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. DADDI R1, R0, #64 MTC1 VLR, R1 LV V1, 0(R2) LV V2, 0(R3) ADDV.D V1, V1, V2 SV 0(R4), V1 L’utilizzo di V1 come registro destinazione per contenere il vettore C è solo una forma di risparmio in registri. In alternativa all’istruzione DADDI R1, R0, #64 si può utilizzare l’istruzione LI R1, #64. Il programma presenterà uno stallo dopo l’ultima load perché la sua destinazione è operando della add che le succede: la prima delle 64 fasi di EX della ADDV processerà gli elementi V1[0] e V2[0], ma in V2[0] non sarà ancora stato ospitato l’effettivo valore B*0+ presente in memoria in quanto questo viene posto nel registro LDM solo dopo la fase di mem di LV, e successivamente nel registro vettoriale V2. DADDI R1, R0, #64 MTC1 VLR, R1 LV V1, 0(R2) LV V2, 0(R3) stallo ADDV.D V1, V1, V2 SV 0(R4), V1

Page 185: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 57

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

ESERCIZIO 2 – SOMMA DI VETTORI > 64 Somma di due vettori con un numero di elementi >64 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.

Page 186: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 58

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

MTC1 VLR, R10 DSUB R10, R1, R10 DMUL R10, R10, #8 Ora si può iniziare il loop. loop: LV V1, R10(R2)

LV V2, R10(R3) ADDV.D V1, V1, V2 SV 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 è: ANDI R10, R1, #63

DADDI R5, R0, #64 MTC1 VLR, R10 DSUB R10, R1, R10 DMUL R10, R10, #8

loop: LV V1, R10(R2) LV V2, R10(R3) stallo ADDV.D V1, V1, V2 SV R10(R4), V1 DADDI R10, R10, #-512 MTC1 VLR, R5 BGEZ R10, loop stallo

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.

Page 187: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 59

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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. DMUL R1, R1, R6

ANDI R10, R1, #63 DADDI R5, R0, #64 MTC1 VLR, R10 DSUB R10, R1, R10 DMUL R10, R10, #8

loop: LV V1, R10(R2) LV V2, R10(R3) ADDV.D V1, V1, V2 SV R10(R4), V1 DADDI R10, R10, #-512 BGEZ R10, loop MTC1 VLR, R5

Page 188: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 60

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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.

ANDI R10, R1, #63 DADDI R5, R0, #64 MTC1 VLR, R10 DSUB R10, R1, R10 DMUL R10, R10, #8

loop: LV V1, R10(R2) stallo MULVS.D V1, V1, F2

LV V2, R10(R3) stallo MULVS.D V2, V2, F4 ADDV.D V2, V1, V2 DIVVS.D V2, V2, F0 SV R10(R3), V2 DADDI R10, R10, #-512 MTC1 VLR, R5 BGEZ R10, loop

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

ANDI R10, R1, #63 DADDI R5, R0, #64 MTC1 VLR, R10 DSUB R10, R1, R10 DMUL R10, R10, #8

loop: LV V1, R10(R2) LV V2, R10(R3)

MULVS.D V1, V1, F2 MULVS.D V2, V2, F4 ADDV.D V2, V1, V2

Page 189: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 61

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

DIVVS.D V2, V2, F0 SV R10(R3), V2 DADDI R10, R10, #-512 BGEZ R10, loop MTC1 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!

ANDI R10, R1, #63 DADDI R5, R0, #64 MTC1 VLR, R10 DSUB R10, R1, R10 DMUL R10, R10, #8 DIV.D F2, F2, F0 DIV.D F4, F4, F0

loop: LV V1, R10(R2) LV V2, R10(R3)

MULVS.D V1, V1, F2 MULVS.D V2, V2, F4 ADDV.D V2, V1, V2 SV R10(R3), V2 DADDI R10, R10, #-512 BGEZ R10, loop MTC1 VLR, R5

Page 190: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 62

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

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 R1, R0, #64 MTC1 VLR, R1 LV V1, 0(R2) LV V2, 0(R3) MULV.D V1, V1, V2 SV 0(R2), V1 Impostiamo le costanti 1 e 2: DADDI R4, R0, #1 DADDI 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 R1, R1, R5 MTC1 VLR, R1 DMULI R6, R1, #8 LV V1, 0(R2) LV V2, R6(R2) ADDV.D V1, V1, V2

Page 191: Dispense Calcolatori Elettronici Con Esercizi

Esercizi di Calcolatori Elettronici A.A. 2009/2010

CALCOLATORI ELETTRONICI Pagina 63

Pietroleonardo Nicola A.A. 2009/2010 Stroppa Fabio

SV 0(R2), V1 BNE R1, R4, loop Lo scalare c sarà salvato all’indirizzo di memoria R2, che inizialmente conteneva il primo elemento del vettore. Il listato completo è:

DADDI R1, R0, #64 MTC1 VLR, R1 LV V1, 0(R2) LV V2, 0(R3) stallo MULV.D V1, V1, V2 SV 0(R2), V1 DADDI R4, R0, #1 DADDI R5, R0, #2

loop: DDIV R1, R1, R5 MTC1 VLR, R1 DMULI R6, R1, #8 LV V1, 0(R2) LV V2, R6(R2) stallo ADDV.D V1, V1, V2 SV 0(R2), V1 BNE R1, R4, loop stallo 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.

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

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