Sei sulla pagina 1di 25

ESERCIZIO 1

Il set di istruzioni del DLX viene esteso con le seguenti due istruzioni

FOR Ri, Rx, Ry NEXT Ri, IMM

Che verranno sempre utilizzate in coppia come mostrato nel seguente frammento di codice

ADDI

R4, R0, 4

FOR

R1, R0, R4

LW

R4, 1000H(R1)

SW

2000H(R1), R4

NEXT

R1, 4

Queste due nuove istruzioni devono comportarsi come segue:

FOR Ri, Rx, Ry Ri Rx e R29 Rx (indici per il ciclo for) R30 Ry (il significato di Ry è spiegato nell’istruzione NEXT. Si suppone che valga la relazione Rx < Ry e che Rx 0) R31 PC + 4 (indirizzo dell’istruzione successiva all’istruzione FOR)

NEXT Ri, IMM Ri Ri + IMM (IMM è un operando immediato senza segno) R29 R29 + 1 Confronta il valore di R29 aggiornato col valore di R30. Se (R29 R30) allora l’esecuzione del programma continua con l’istruzione che segue l’istruzione NEXT. Se (R29 < R30) allora la prossima istruzione da eseguire sarà l’istruzione successiva all’istruzione FOR (l’indirizzo di tale istruzione si trova già in R31).

NB: Si suppone inoltre che le istruzioni presenti tra un’istruzione FOR e la corrispondente NEXT non modifichino i registri Ri, R29, R30 e R31.

Si indichi una possibile codifica binaria nel linguaggio macchina del DLX delle due nuove istruzioni.

Per l’istruzione FOR serve il formato con tre registri, cioè il formato R.

FOR

Rx

Ry

Ri

Op. code

Per l’istruzione NEXT serve un formato che abbia l’operando immediato, cioè il formato I.

NEXT

Ri

R29

IMMEDIATE

Con riferimento all’implementazione sequenziale del DLX, si disegni il diagramma degli stati delle istruzioni FOR e NEXT.

FOR

IR M[PC]

A (c’è Rx)

B (c’è Ry) (incremento contatore)

Rx

Ry

PC PC + 4*

C A

Ri C

Ri Rx

R29 C C B R29 Rx

R30 C

C PC

R30 Ry

R31 C R31 PC + 4*

NEXT

IR M[PC]

A Ri

B R29

PC PC + 4

C A + (0) 16 ## IR 150

Ri Ri + IMM Ri C

C B

+ 1

R29 R29 + 1 R29 C

A R29

B R30

C A – B

A R31

((R29 R30) per C maggiore o uguale a zero, salta a dopo la NEXT)

PC A Se (R29 < R30) allora la prossima istruzione da eseguire sarà l’istruzione successiva all’istruzione FOR (l’indirizzo di tale istruzione si trova già in

R31)

Considerando il frammento di codice riportato all’inizio del testo, si mostri con un esempio quale risultato si ottiene dall’esecuzione di detto codice.

ADDI

R4, R0, 4

Si inizializza R4 a 4

FOR

R1, R0, R4

Viene invocata la FOR con parametri R1, R0, R4.

 

0

viene messo in Ri.

0

viene messo in R29.

LW

R4, 1000H(R1)

R4 (= 4) viene messo in R30. In R31 viene messo l’indirizzo dell’istruzione successiva al FOR. In R4 viene messo M[R1+1000H]

SW

2000H(R1), R4

Viene caricato in M[R1+2000H] il valore appena spostato.

NEXT

R1, 4

Viene invocata la NEXT con parametri R1 e 4. R1 viene incrementato di 4. In R29 viene aggiunto 1 (quindi si va a 0+1 = 1).

Si confronta R29 con R30: se sono uguali, o se R29 è maggiore, si salta a dopo NEXT. Altrimenti si ricomincia dalla LW.

Vengono

all’indirizzo 2000H.

in pratica

spostate

4

word

(4

x

4

byte)

dall’indirizzo

1000H

Si indichi il numero di periodi di clock necessari ad eseguire le istruzioni nell’ipotesi che la memoria richieda 2 stati di wait per ogni accesso.

FOR = 7 + wait = 9

NEXT = (taken)

8 + wait = 10

(not-taken) 7 + wait = 9

Nelle ipotesi del punto 4, supponendo una frequenza di clock di 100 Mhz, quale valore occorre assegnare ad N affinché l’esecuzione del frammento di codice che segue avvenga in un tempo il più prossimo possibile a 20 nsec.

ADDI

R3, R0, N

FOR

R1, R0, R3

NEXT

R1, 1

ESERCIZIO 1

Come si potrebbe codificare l’istruzione utilizzando uno dei tre formati che ci mette a disposizione il DLX?

Non è difficile accorgersi che, nella nuova istruzione, fanno la loro comparsa 3 registri:

Rx, Ry, Rz. Dunque, l’unica codifica possibile è quella di tipo R:

LBUR

Ry

Rz

Rx

LBUR

L’istruzione che abbiamo definito trasferisce in Rx il dato di tipo unsigned-byte situato all’indirizzo di memoria ottenuto sommando i registri Ry e Rz.

FETCH:

DECODE:

MEMORY:

WRITE BACK:

IR M[PC]

PC PC + 4

A RS1 (che sarebbe Ry)

B RS2 (che sarebbe Rz)

MAR A + B

MDR M[MAR]

C MDR 0

RD C

7

## (0) 24

stati di wait

accesso in memoria (wait)

si inserisce tutto in C

Vengono utilizzati 6 + altri 2 aggiuntivi dovuti agli accessi alla memoria

Nell’ipotesi di voler aggiungere all’indirizzo di memoria usato dall’istruzione LBUR anche una costante con segno (cioè accedere alla cella M[Ry + Rz + IMMEDIATE]) e si indichi come dev’essere modificata la codifica precedente. Quale ulteriore accorgimento dovrebbe essere adottato nella codifica per rendere la LBUR distinguibile senza ambiguità dalle altre istruzioni codificate nello stesso formato.

LBUR

Ry

Rz

Rx

IMMEDIATE

Ad IMMEDIATE vengono riservati 11 bit, quindi può essere codificato con un range di [-1024, 1023].

Per poter distinguere questa codifica dalle altre senza generare confusione, l’unico campo che può essere modificato è quello del codice operativo LBUR. Si deve infatti modificare affinché sia diverso da quello di tutte le altre istruzioni di tipo R.

ESERCIZIO 2

Si consideri la seguente sequenza di istruzioni del DLX

ADDI R1, R0, 400H

CICLO:

LBU

R2, 0(R1)

LB

R3, 0(R2)

SB

0(R1), R3

ADDI R1, R1, 1

SLTI

BNEZ R2, CICLO

R2, R1, 500H

Si indichi il numero totale di cicli di bus relativo rispettivamente al “fetch” e all’esecuzione delle istruzioni.

Anzitutto esaminiamo il codice:

 

ADDI

R1, R0, 400H

R1 viene a messo 400H (cioè 1024)

CICLO:

LBU

R2, 0(R1)

Viene messo in R2 il contenuto di M[R1]

LB

R3, 0(R2)

Viene messo in R3 il contenuto di M[R2]

SB

0(R1), R3

Viene messo in R1 il contenuto di M[R3]

ADDI

R1, R1, 1

R1 viene incrementato di 1

SLTI

R2, R1, 500H

Se R1 è < 500H (cioè 1280) allora R2 viene

BNEZ R2, CICLO

messo a 1, altrimenti a 0 Se R2 è diverso da zero ciclo

Dunque questo mini-programmino assembler mette 400H In R1 in R2 in R3 Poi R1 viene incrementato di uno e si controlla se è minore di 500H: in tal caso si ricomincia da CICLO.

Si esegue dunque il blocco CICLO (di 6 istruzioni) 1280 – 1024 = 256 volte; per questo motivo la fase di fetch viene invocata 1 (per la prima ADDI) + 256 6 = 1537 volte. Questo numero è pari a quello delle volte in cui dev’essere invocato il ciclo di BUS relativo al Fetch (1 volta/istruzione).

Per quanto riguarda l’esecuzione delle istruzioni, solo le prime 3 (in rosso) prevedono l’accesso alla memoria: quindi il numero totale di accessi è di 2563 = 768.

Si consideri la struttura sequenziale del DLX ed, ipotizzando che tutti gli accessi in memoria siano completati in 2 clock, si calcolino il numero totale di cicli di clock necessario all’esecuzione della sequenza ed il CPI-medio.

Vengono fatte:

256 + 1

ALU

(6 clock ciascuna)

256 2

LOAD (6+2 clock ciascuna)

256

STORE (5+2 clock ciascuna)

256

SET (5 clock ciascuna)

255

BRANCH (not-taken) (3+2 clock ciascuna)

1

BRANCH (taken) (4 clock)

Il numero totale di periodi di clock è quindi 10501. Il CPI medio, di conseguenza, risulta pari a 10501/1537 = 6,83

ESERCIZIO 1

Si supponga di voler estendere il set di istruzioni del DLX con l’istruzione:

BNEQ++ (Rx), (Ry), IMMEDIATE

Dove gli operandi Rx, Ry rappresentano due registri generali ed IMMEDIATE è una costante signed a 16 bit. L’istruzione confronta la word situata in memoria all’indirizzo Rx con la word situata in memoria all’indirizzo Ry: se i valori risultano diversi somma la costante IMMEDIATE al valore corrente del PC. Inoltre, indipendentemente dall’esito del confronto, l’istruzione incrementa il registro Ry (sommando il valore +4). Una possibile descrizione RTL delle operazioni svolte dalla nuova istruzione è data da

If

Ry Ry + 4

(M[Rx] ≠ M[Ry)

then

PC PC + IMMEDIATE

Si mostri come potrebbe essere codificata la nuova istruzione utilizzando il più idoneo fra i 3 formati delle istruzioni DLX.

Il formato più idoneo è quello di tipo I, perché abbiamo a disposizione lo spazio per due registri e per l’operando immediato.

BNEQ++

Rx

Ry

IMMEDIATE

Con riferimento al datapath del DLX sequenziale visto a lezione si disegni il diagramma degli stati che controlla l’esecuzione della nuova istruzione inserendo anche gli stati necessari al fetch ed alla decodifica.

1) FETCH

IR M[PC]

1) FETCH IR M[PC] Accesso in memoria

Accesso in memoria

2) DECODE

PC PC + 4

(le solite due fasi)

A RS1 (Rx)

B RS2 (Ry)

3) MEMORY

MAR B (Ry)

 

4)

MDR M[MAR]

Accesso in memoria

C

MAR + 4

Approfittiamone per farlo (bisogna effettuare questa operazione in ogni caso)

5)

TEMP MDR RS2 C

 

Ry (com’era all’inizio) è in TEMP, mentre l’Ry aggiornato viene deposto in B

6)

MAR A

Ora è necessario andare a prendere l’altro registro per effettuare il confronto

7)

MDR M[MAR]

L’accesso (solito) in memoria

SE è TRUE

9a)

PC PC + (IR15) 16 ## (IR15

0)

Aggiorniamo il PC con l’immediato (16 bit)

SE è FALSE --)

Si torna daccapo

Nell’ipotesi che tutti gli accessi alla memoria possano essere completati in 2 clock, si calcoli il numero di cicli di clock (CPI) necessari per l’esecuzione dell’istruzione.

CASO Branch-TAKEN (risposta TRUE al punto 8) CPI = 6 + 2 (IF) + 2 (MEM1) + 2 (MEM2) = 12

CASO Branch-NOT-TAKEN (risposta FALSE al punto 8) CPI = [caso precedente] – 1 = 11

Utilizzando la nuova istruzione BNEQ++ si scriva un frammento di codice assembler DLX che, dato un vettore V1 di 10 word (32 bit) memorizzato a partire dell’indirizzo 200H ed una variabile alfa memorizzata all’indirizzo 4000H, ritorna nel registro R1 il numero di elementi di V1 che risultano uguali ad alfa e memorizza in ordine crescente in un secondo vettore (V2, adiacente al primo in memoria) gli indirizzi di tali elementi.

ADD

R1, R0, R0

ADDI R2, R0, 200H ADDI R3, R0, 228H

ADDI R4, R0, 4000H

Inizializziamo R1: è il contatore degli elementi uguali ad alfa Inizializziamo R2 a 200H (dove inizia V1) Inizializziamo R3 a 228H (distante 40 celle da 8 bit da 200H, ovvero le celle dove contenere le 10 word). Qui inizia il secondo vettore, che è adiacente al primo. Mettiamo in R4 l’indirizzo della variabile alfa

LOOP:

BNEQ++ (R4), (R2), SKIP

Se V[i] è diverso da alfa, vai a SKIP

ADDI

R1, R1, 1

Aggiungiamo 1 ad R1: abbiamo trovato una word uguale ad alfa

SUBI

R5, R2, 4

Mettiamo, in R5, R2 – 4; esso è l’indice di V1 aggiornato

SW

0(R3), R5

Memorizziamo nel secondo vettore (R3 ne è l’indice)

ADDI

R3, R3, 4

l’indirizzo di V1 aggiornato. Incrementiamo l’indice di V2 (sempre R3)

SKIP:

SEQI

R5, R2, 228H

Se R2 è uguale a 228H, allora metti R5 a 1

BEQZ

R5, LOOP

R5 è uguale a zero? Vuol dire che non abbiamo finito di scorrere il vettore: si ritorna a loop.

Sempre con riferimento al DLX sequenziale si calcoli il CPI medio del codice scritto al punto precedente nell’ipotesi che il numero di elementi di V1 che risultano uguali ad alfa sia pari all’ultima cifra del proprio numero di matricola. Per l’istruzione BNEQ++ si utilizzi il CPI precedentemente calcolato e per le altre istruzioni i valori visti a lezione e deducibili dai diagrammi degli stati del controllo (si mantenga l’ipotesi che ogni accesso alla memoria richieda 2 clock).

IPOTESI: Numero di elementi di V1 uguali ad alfa = 7 [ultima cifra del numero di matricola].

Dividiamo il codice in tre fasi:

1) INIZIALIZZAZIONE (4 istruzioni)

Si tratta di 4 ALU

4 + 2 (wait)

24 clock

2) UGUALE AD ALFA (5 istruzioni)

Ci

sono 3 ALU

4 + 2 (wait)

18 clock

C’è una STORE

3 + 2 + 2 (wait)

7 clock

La

BNEQ++

TAKEN

12 clock

 

NOT-TAKEN

11 clock

3) FINALE / DIVERSO DA ALFA (2 istruzioni)

C’è la SET

6 clock

4 + 2 (wait) TAKEN

NOT-TAKEN

Infine, la BRANCH L’inizializzazione si fa una volta sola.

5 clock

4 clock

Poi, se si verifica che l’elemento del vettore è uguale ad alfa allora si fanno sia la fase 2 (con la BNEQ++ “Not-taken”) che la fase 3. Altrimenti si fa solo la BNEQ++ “Taken” e la 3.

La BRANCH finale si fa sempre not-taken tranne l’ultima volta.

Per 7 volte ci troviamo nella prima situazione, per 3 volte nella seconda.

Numero totale di clock: 24 + (3 x [12+6+5+4]) + (7 x [11 + 7 + 18 + 6 + 5]) – 1 = 433 (il -1 è per l’ultima branch, che è not-taken). Numero totale di operazioni: 4 + (3 x 3) + (7 x 7) = 62

CPI MEDIO = 433/62 = 6,78

ESERCIZIO 1

Si supponga di voler estendere il set di istruzioni del DLX con l’istruzione:

BNEQ++ (Rx), (Ry), IMMEDIATE

Dove gli operandi Rx, Ry rappresentano due registri generali ed IMMEDIATE è una costante signed a 16 bit. L’istruzione confronta la word situata in memoria all’indirizzo Rx con la word situata in memoria all’indirizzo Ry: se i valori risultano diversi somma la costante IMMEDIATE al valore corrente del PC. Inoltre, indipendentemente dall’esito del confronto, l’istruzione incrementa il registro Ry (sommando il valore +4). Una possibile descrizione RTL delle operazioni svolte dalla nuova istruzione è data da

If

Ry Ry + 4

(M[Rx] ≠ M[Ry)

then

PC PC + IMMEDIATE

Si mostri come potrebbe essere codificata la nuova istruzione utilizzando il più idoneo fra i 3 formati delle istruzioni DLX.

Il formato più idoneo è quello di tipo I, perché abbiamo a disposizione lo spazio per due registri e per l’operando immediato.

BNEQ++

Rx

Ry

IMMEDIATE

Con riferimento al datapath del DLX sequenziale visto a lezione si disegni il diagramma degli stati che controlla l’esecuzione della nuova istruzione inserendo anche gli stati necessari al fetch ed alla decodifica.

1) FETCH

IR M[PC]

1) FETCH IR M[PC] Accesso in memoria

Accesso in memoria

2) DECODE

PC PC + 4

(le solite due fasi)

A RS1 (Rx)

B RS2 (Ry)

3) MEMORY

MAR B (Ry)

 

4)

MDR M[MAR]

Accesso in memoria

C

MAR + 4

Approfittiamone per farlo (bisogna effettuare questa operazione in ogni caso)

5)

TEMP MDR RS2 C

 

Ry (com’era all’inizio) è in TEMP, mentre l’Ry aggiornato viene deposto in B

6)

MAR A

Ora è necessario andare a prendere l’altro registro per effettuare il confronto

7)

MDR M[MAR]

L’accesso (solito) in memoria

SE è TRUE

9a)

PC PC + (IR15) 16 ## (IR15

0)

Aggiorniamo il PC con l’immediato (16 bit)

SE è FALSE --)

Si torna daccapo

Nell’ipotesi che tutti gli accessi alla memoria possano essere completati in 2 clock, si calcoli il numero di cicli di clock (CPI) necessari per l’esecuzione dell’istruzione.

CASO Branch-TAKEN (risposta TRUE al punto 8) CPI = 6 + 2 (IF) + 2 (MEM1) + 2 (MEM2) = 12

CASO Branch-NOT-TAKEN (risposta FALSE al punto 8) CPI = [caso precedente] – 1 = 11

Utilizzando la nuova istruzione BNEQ++ si scriva un frammento di codice assembler DLX che, dato un vettore V1 di 10 word (32 bit) memorizzato a partire dell’indirizzo 200H ed una variabile alfa memorizzata all’indirizzo 4000H, ritorna nel registro R1 il numero di elementi di V1 che risultano uguali ad alfa e memorizza in ordine crescente in un secondo vettore (V2, adiacente al primo in memoria) gli indirizzi di tali elementi.

ADD

R1, R0, R0

ADDI R2, R0, 200H ADDI R3, R0, 228H

ADDI R4, R0, 4000H

Inizializziamo R1: è il contatore degli elementi uguali ad alfa Inizializziamo R2 a 200H (dove inizia V1) Inizializziamo R3 a 228H (distante 40 celle da 8 bit da 200H, ovvero le celle dove contenere le 10 word). Qui inizia il secondo vettore, che è adiacente al primo. Mettiamo in R4 l’indirizzo della variabile alfa

LOOP:

BNEQ++ (R4), (R2), SKIP

Se V[i] è diverso da alfa, vai a SKIP

ADDI

R1, R1, 1

Aggiungiamo 1 ad R1: abbiamo trovato una word uguale ad alfa

SUBI

R5, R2, 4

Mettiamo, in R5, R2 – 4; esso è l’indice di V1 aggiornato

SW

0(R3), R5

Memorizziamo nel secondo vettore (R3 ne è l’indice)

ADDI

R3, R3, 4

l’indirizzo di V1 aggiornato. Incrementiamo l’indice di V2 (sempre R3)

SKIP:

SEQI

R5, R2, 228H

Se R2 è uguale a 228H, allora metti R5 a 1

BEQZ

R5, LOOP

R5 è uguale a zero? Vuol dire che non abbiamo finito di scorrere il vettore: si ritorna a loop.

Sempre con riferimento al DLX sequenziale si calcoli il CPI medio del codice scritto al punto precedente nell’ipotesi che il numero di elementi di V1 che risultano uguali ad alfa sia pari all’ultima cifra del proprio numero di matricola. Per l’istruzione BNEQ++ si utilizzi il CPI precedentemente calcolato e per le altre istruzioni i valori visti a lezione e deducibili dai diagrammi degli stati del controllo (si mantenga l’ipotesi che ogni accesso alla memoria richieda 2 clock).

IPOTESI: Numero di elementi di V1 uguali ad alfa = 7 [ultima cifra del numero di matricola].

Dividiamo il codice in tre fasi:

1) INIZIALIZZAZIONE (4 istruzioni)

Si tratta di 4 ALU

4 + 2 (wait)

24 clock

2) UGUALE AD ALFA (5 istruzioni)

Ci

sono 3 ALU

4 + 2 (wait)

18 clock

C’è una STORE

3 + 2 + 2 (wait)

7 clock

La

BNEQ++

TAKEN

12 clock

 

NOT-TAKEN

11 clock

3) FINALE / DIVERSO DA ALFA (2 istruzioni)

C’è la SET

6 clock

4 + 2 (wait) TAKEN

NOT-TAKEN

Infine, la BRANCH L’inizializzazione si fa una volta sola.

5 clock

4 clock

Poi, se si verifica che l’elemento del vettore è uguale ad alfa allora si fanno sia la fase 2 (con la BNEQ++ “Not-taken”) che la fase 3. Altrimenti si fa solo la BNEQ++ “Taken” e la 3.

La BRANCH finale si fa sempre not-taken tranne l’ultima volta.

Per 7 volte ci troviamo nella prima situazione, per 3 volte nella seconda.

Numero totale di clock: 24 + (3 x [12+6+5+4]) + (7 x [11 + 7 + 18 + 6 + 5]) – 1 = 433 (il -1 è per l’ultima branch, che è not-taken). Numero totale di operazioni: 4 + (3 x 3) + (7 x 7) = 62

CPI MEDIO = 433/62 = 6,78

ESERCIZIO 1

Si supponga di voler estendere il set di istruzioni del DLX con l’istruzione:

SCANVW

Rx, Ry, Rz

Dove gli operandi Rx, Ry, Rz, rappresentano tre registri generali. L’istruzione confronta la word situata in memoria all’indirizzo Rx con il valore di Ry: se i valori risultano uguali il registro Rz viene posto a 1, viceversa viene posto a 0. Effettuato il confronto, l’istruzione incrementa il registro Rx (sommando il valore +4). Una possibile descrizione RTL delle operazioni svolta dalla nuova istruzione è data da:

if (M[Rx] = Ry)

then

Rz 1

else Rz 0 Rx Rx + 4

Si mostri come potrebbe essere codificata la nuova istruzione utilizzando il più idoneo fra i tre formati delle istruzioni del DLX.

Senza troppo scervellarci: ci sono tre registri, dunque la codifica appropriata è quella di tipo R.

SCANWV Rx,Ry,Rz

Ry

Rx

Rz

Con riferimento al datapath del DLX sequenziale (cioè non-pipelined) visto a lezione si disegni il diagramma degli stati che controlla l’esecuzione della nuova istruzione inserendo anche gli stati necessari al fetch e alla decodifica.

FETCH

IR M[PC]

(stati di wait)

DECODE

A RS1 (Ry)

B RS2 (Rx)

PC PC + 4

MAR B

(mettiamo in MAR l’indirizzo del registro da confrontare)

MDR M[MAR]

(stati di wait)

MDR == A ?

(confronto: e qui discriminiamo)

di wait) MDR == A ? (confronto: e qui discriminiamo) SI C 1 C B +
di wait) MDR == A ? (confronto: e qui discriminiamo) SI C 1 C B +

SI

C 1

C B + 4 RD C

RS2 C

NO

C 0

(dobbiamo incrementare Rx)

Nell’ipotesi che tutti gli accessi alla memoria possano essere completati in 3 clock, si calcoli il numero di cicli di clock (CPI) necessari per l’esecuzione delle istruzioni.

CPI = 6 + 3 (FETCH) + 3 (MEMORY) = 12

Utilizzando la nuova istruzione SCANVW si scriva un frammento di codice assmebler DLX che, dato un vettore di 256 word (32 bit) memorizzato a partire dall’indirizzo 0000 0400H, ritorna nel registro R1 l’indirizzo di memoria del primo elemento del vettore che risulta uguale a 100 (se nessun elemento del vettore è uguale a 100 in R1 deve essere ritornato il valore 0).

Inizializziamo la variabile R2 (indirizzo del vettore)

ADDI

R2, R0, 0400H

Valore confrontando

ADDI

R3, R0, 100

Contatore delle iterazioni

ADDI

R4, R0, 256

Usiamo l’istruzione SCANVW

SCANWV

R3, R2, R1

(NEXT)

Se l’elemento è uguale a = R3 allora salta alla label FOUND

BNEZ R1, FOUND

Decremento del contatore delle iterazioni

SUBI

R4, R4, 1

Se il contatore delle iterazioni è diverso da 0, salta a NEXT

BNEZ

R4, NEXT

Se arriviamo qui significa che nessun elemento del vettore è R3, quindi azzeriamo R2

ADDI

R2, R0, 4

Se abbiamo trovato un elemento = 100 allora R1 = indirizzo di tale elemento. Altrimenti R1 = 0

SUBI

R1, R2, 4

(FOUND)

Quindi:

R2 400H R3 100 R4 256

M[400H] è = 100 ? Se sì R1 1

Altrimenti R1 0

(NEXT)

In ogni caso R2 404H

R1 è diverso da 0 (abbiamo trovato un valore = 100)?

Se sì, salta a FOUND

Altrimenti prosegui.

R4 255

R4 è diverso da 0 (abbiamo finito)?

Se no, torna a NEXT.

Altrimenti, prosegui.

Nessun elemento del vettore è = 3. Dunque R2 4

Abbiamo trovato un elemento = 100 R1 404H – 4H = 400H

(FOUND)

Sempre con riferimento al DLX sequenziale (cioè non-pipelined), si calcoli il CPI medio del codice scritto al punto precedente nell’ipotesi che l’unico elemento del vettore che risulta uguale a 100 sia il decimo (cioè quello di indice 9). Per l’istruzione SCANVW si utilizzi il CPI precedentemente calcolato e per le altre istruzioni i valori visti a lezione e deducibili dai diagrammi degli stati del controllo (si mantenga l’ipotesi che ogni accesso alla memoria richieda 3 clock).

L’inizializzazione consiste in 3 ALU (4 + 3 = 7 clock ciascuna). L’unico elemento = 100 è il decimo, quindi dopo queste prime tre istruzioni di inizializzazione vengono eseguiti 9 loop costituiti dalle istruzioni che vanno da SCANVW alla BNEZ-R4 (con BNEZ-R1 not-taken e BNEZ-R4 taken). La decima volta

si fa invece dalla SCANVW alla successiva BNEZ-R1 (taken), quindi si salta alla FOUND. QUINDI

9 volte:

SCANVW

12 clock

BNEZ-R1 (n.t.)

5 clock

SUBI

7 clock

BNEZ-R4 (t.)

6 clock

1

volta:

SCANVW

12 clock

BNEZ-R1 (t.)

6 clock

FOUND (SUBI)

7 clock

NUMERO TOTALE DI ISTRUZIONI: 3 (init) + 4 x 9 + 2 x 1 + 1 = 42 NUMERO TOTALE DI CLOCK: 13 x 7 (ALU) + 10 x 12 (SCANVW) + 10 x 6 (BRANCH TAKEN) + 9 x 5 (B. NOT TAKEN) = 316

CPI medio: 316 / 42 = 7,5 circa

ESERCIZIO 1

Si supponga di voler estendere il Set di Istruzioni del DLX con la seguente istruzione

NEG IMMEDIATE(Rx)

Dove Rx è un registro generale ed IMMEDIATE è una costante di 16 bit con segno. L’istruzione deve eseguire il cambiamento del segno della word (32 bit) situata all’indirizzo di memoria Rx + IMMEDIATE.

Si mostri come potrebbe essere codificata la nuova istruzione utilizzando uno dei 3 formati delle istruzioni DLX.

C’è soltanto

un

registro

di

cui

tenere conto (Rx),

dunque è largamente

sufficiente la codifica I:

 

NEG

 

Rx

indifferente

IMMEDIATE (16 bit)

Con riferimento al datapath del DLX sequenziale (cioè non-pipelined) visto a lezione si disegni il diagramma degli stati che controlla l’esecuzione della nuova istruzione inserendo anche gli stati necessari al fetch ed alla decodifica.

IR M[PC]

A RS1 (Rx)

B RS2 (nulla) PC PC + 4

(stati di wait)

MAR A + (IR 15 ) 16 ## IR 15

0

(sommiamo A all’operando immediato)

MDR M[MAR]

(stati di wait)

MDR 0 – MDR

M[MAR] MDR

(creiamo in questo modo il complemento a due)

(stati di wait, depositiamo il nuovo valore dove stava prima)

Nell’ipotesi che tutti gli accessi alla memoria possano essere completati in 2 clock, si calcoli il numero di cicli di clock (CPI) necessari per l’esecuzione dell’istruzione.

CPI: 3 + 2 (fetch) + 2 (primo accesso in memoria) + 2 (secondo accesso) = 9

ESERCIZIO 2

Si consideri il codice della seguente procedura in Assembler DLX.

PROC:

SUBUI R30, R30, 4

SW

0(R30), R31

LOOP:

NEG

0(R1)

ADDI

R1, R1, 4

SUBI

R2, R2, 1

BNEZ R2, LOOP

LW

ADDUI R30, R30, 4

JR

R31, 0(R30)

R31

Che fa uso dell’istruzione NEG definite nell’esercizio precedente.

Si spieghi

in modo preciso

e

sintetico qual è l’operazione svolta dalla

procedura.

Si sottrae 4 dal registro R30 Si deposita R31 in R30

Viene cambiato di segno di ciò che c’è nel registro R1

Viene aggiunto 4 ad R1 (si cerca la prossima word) Viene sottratto 1 da R2 R2 è uguale a zero? Se sì torna a LOOP, sennò prosegui.

Viene messo in R31 ciò che viene preso in R30 Si aggiunge 4 ad R30 Si salta ad R31

R30 R30 - 4 R30 R31

( LOOP) R1 -R1 R1 R1 + 4 R2 R2 - 1

R31 R30 R30 R30 + 4 Salta

Cosa fa questo benedetto programmino? All’interno del loop (eseguito R2 volte) cambia segno a ciò che c’è nel registro R1 poi, a scalare, negli altri elementi del vettore che parte – appunto – da R1.

Si consideri la struttura sequenziale del DLX. Ipotizzando che tutti gli accessi in memoria siano completati in 2 clock e che prima di trasferire il controllo alla procedura il registro R2 sia stato posto al valore 1000, si calcolino il numero totale di cicli di clock necessario per l’esecuzione della procedura ed il relativo CPImedio.

Se R2 è stato posto a 1000 significa che il LOOP (testo in verde) verrà eseguito

1000 volte.

Il numero totale di istruzioni è dunque:

2

(inizializzazione)

+

4

x 1000 (loop)

+

3

(fine)

=

4005 ISTRUZIONI

TIPO DI ISTRUZIONE

QUANTE E QUANDO

CLOCK

Load

1 (fine)

8

Store

1 (init)

7

Alu

1 (init) + 2000 (loop) + 1 (fine)

6

Jump

1 (fine)

4

Branch (taken)

999 (loop)

5

Branch (not-taken)

1 (loop)

4

Neg

1000 (loop)

9

TOTALE = 8 + 7 + 6 x 2002 + 4 + 5 x 999 + 4 + 9 x 1000 = 20630

CPI medio = 26030 / 4005 = 6,5

Si mostri come dovrebbe essere modificato il codice della procedura al fine di garantire che essa non alteri il contesto del chiamante (cioè non modifichi alcun registro ad eccezione di quelli eventualmente utilizzati per restituire dei risultati).

Cosa bisogna fare? Prima di entrare nel loop è necessario salvare i valori dei registri R1 ed R2, perché durante la procedura questi verranno modificati. Poi, all’uscita dal loop, dovranno essere ripristinati. Dobbiamo quindi introdurre una SW preceduta da una SUBUI (all’inizio) e una LW seguita da una ADDUI (alla fine), in più.

PROC:

SUBUI R30, R30, 4

SW

SUBUI R30, R30, 4

0(R30), R31

 

SW

0(R30), R2

LOOP:

NEG

0(R1)

ADDI

R1, R1, 4 R2, R2, 1

SUBI

BNEZ R2, LOOP

LW

ADDUI R30, R30, 4

LW

R31, 0(R30)

R31, 0(R30)

ADDUI R30, R30, 4

JR

R31

ESERCIZIO 1

Si supponga di voler estendere il Set di Istruzioni del DLX con la seguente istruzione:

ADDM IMMEDIATE(Rx), Ry

Dove Rx, Ry sono due registri generali e IMMEDIATE è una costante a 16 bit con segno. L’istruzione deve eseguire la somma fra la word (32 bit) situata all’indirizzo di memoria Rx + IMMEDIATE ed il registro Ry e poi scrivere il risultato nuovamente all’indirizzo di memoria Rx + IMMEDIATE (cioè, in notazione RTL, eseguire l’operazione:

M[Rx + IMMEDIATE] M[Rx + IMMEDIATE] + Ry

Si mostri come potrebbe essere codificata la nuova istruzione utilizzando uno dei tre formati delle istruzioni DLX.

Usiamo, in virtù della presenza dei due registri, il formato I.

ADDM

Rx

Ry

IMMEDIATE (16 bit)

Con riferimento al datapath del DLX sequenziale (non-pipelined) visto a lezione si disegni il diagramma degli stati che controlla l’esecuzione della nuova istruzione inserendo anche gli stati necessari al fetch ed alla decodifica.

IR M[PC]

A RS1 (Rx)

B RS2 (Ry)

PC PC + 4

MAR A + (IR 15 ) 16 ## IR 15

MDR M[MAR]

MDR MDR + B

M[MAR] MDR

0

(fase di FETCH, stati di wait)

(fase di DECODE)

(aggiungiamo l’IMMEDIATE)

(stati di wait)

(aggiungiamo Ry)

(stati di wait)

Nell’ipotesi che tutti gli accessi alla memoria possano essere completati in 3 clock, si calcoli il numero di cicli di clock (CPI) necessari per l’esecuzione dell’istruzione.

Numero di clock: 3 + 3 (fetch) + 3 (memory 1) + 3 (memory 2) = 12

ESERCIZIO 2

Si consideri la seguente sequenza di istruzioni DLX

 

ADDI

R1, R0, R0

CICLO:

LW

R2, V1(R1)

LW

R3, V2(R1)

ADD

R2, R2, R3

SW

V1(R1), R2

ADDI

R1, R1, 4

SLTI

R2, R1, 1000H

BNEZ R2, CICLO

Dove V1 e V2 sono due costanti che rappresentano gli indirizzi di base (cioè l’indirizzo del primo elemento) di due vettori di word (32 bit).

Cosa fa questo codice?

ADDI

R1, R0, R0

Inizializziamo R1 a 0

CICLO: LW

R2, V1(R1)

Si carica in R2 il valore in V1[R1]

LW

R3, V2(R1)

Si carica in R3 il valore in V2[R1]

ADD

R2, R2, R3

Si somma: R2 R2 + R3

SW

V1(R1), R2

Si mette R2 in V1[R1]

ADDI

R1, R1, 4

Togli 4 da R1

SLTI

R2, R1, 1000H

Se R1 < 1000H allora R2 1 (0 altrimenti)

BNEZ

R2, CICLO

Se R2 non è uguale a zero, vai a CICLO

loro gli elementi

V1[i]+V2[i], poi si pone il risultato in posizione V1[i]. Si compie questa operazione 400H = 1024 volte.

Il programma scorre due vettori

(V1

e

V2),

somma fra

Si consideri la struttura sequenziale del DLX ed, ipotizzando che tutti gli accessi in memoria siano completati in 3 clock, si calcolino il numero totale di cicli di clock necessario per l’esecuzione della sequenza ed il CPI medio.

TIPO DI ISTRUZIONE

QUANTE E QUANDO

CLOCK

ALU

1 (init.) + 1024 x 2 (ciclo)

7

LOAD

1024 x 2 (ciclo)

10

STORE

1024 x 1 (ciclo)

9

SET

1024 x 1 (ciclo)

8

BRANCH (taken)

1023 x 1 (ciclo)

6

BRANCH (not-taken)

1 (ciclo)

5

N° DI ISTRUZIONI ESEGUITE IN TOTALE: 1 + (1024 x 7) = 7169

N° CLOCK IN TOTALE: 2049 x 7 + 2048 x 10 + 1024 x 9 + 1024 x 8 + 6 x 1023 + 5 =

58374

CPI medio = 58374 / 7169 = 8,14

Si riscriva la precedente sequenza di istruzioni impiegando l’istruzione ADDM IMMEDIATE(Rx), Ry definita nell’Esercizio 1 al fine di sommare gli elementi corrispondenti dei due lettori V1 e V2.

ADDI

R1, R0, R0

Inizializziamo R1 a 0

CICLO: LW

R2, V1(R1)

Si carica in R2 il valore in V1[R1]

ADDM V1(R1), R2

1 istruzione al posto di tre

ADDI

R1, R1, 4

Togli 4 da R1

SLTI

R2, R1, 1000H

Se R1 < 1000H allora R2 1 (0 altrimenti)

BNEZ

R2, CICLO

Se R2 non è uguale a zero, vai a CICLO

Sempre considerando la struttura sequenziale del DLX ed ipotizzando che tutti gli accessi in memoria siano completati in 3 clock, si calcolino per la nuova sequenza il numero totale di cicli di clock necessario per l’esecuzione ed il CPI medio.

TIPO DI ISTRUZIONE

QUANTE E QUANDO

CLOCK

ALU

1 (init.) + 1024 x 1 (ciclo)

7

LOAD

1024 x 1 (ciclo)

10

ADDM

1024 x 1 (ciclo)

12

SET

1024 x 1 (ciclo)

8

BRANCH (taken)

1023 x 1 (ciclo)

6

BRANCH (not-taken)

1 (ciclo)

5

N° DI ISTRUZIONI ESEGUITE IN TOTALE: 1 + (1024 x 5) = 5121

N° CLOCK IN TOTALE: 1025 x 7 + 1024 x 10 + 1024 x 12 + 1024 x 8 + 6 x 1023 + 5 =

44038

CPI medio = 44038 / 5121 = 8,59

Come si nota, il CPI medio si è alzato. Tuttavia, ciò non significa che il nuovo codice sia più lento: abbiamo infatti un risparmio totale di 14336 cicli di clock.

Considerando sia la struttura sequenziale sia quella “pipelined”, si discutano vantaggi e svantaggi dell’eventuale introduzione nell’ISA DLX della nuova istruzione ADDM IMMEDIATE(Rx), Ry.

Semplicemente, non possiamo eseguire tale programma sulla pipeline a 5 stadi del DLX: la nuova istruzione è di tipo CISC.

ESERCIZIO 1

Si scriva in Assembler DLX una procedura che calcola il massimo di un vettore di unsigned word (32 bit). La procedura deve ricevere come parametri di ingresso l’indirizzo del vettore sul registro R1 e la dimensione del vettore (cioè il numero dei suoi elementi) sul registro R2. La procedura deve restituire il massimo del vettore sul registro R3.

PROC:

ADD

R3, R0, R0

Inizializziamo R3: qua dentro ci finirà il massimo

LOOP:

LW

R4, 0(R1)

appena lo troveremo all’interno del vettore. Carichiamo ciò che c’è in R1 su R4.

SGTU

R5, R4, R3

Se R4 > R3 allora R5 = 1 (se, cioè, abbiamo

BEQZ

R5, SKIP

trovato un massimo, altrimenti R5 = 0. Non abbiamo trovato un nuovo massimo. Salta.

ADD

R3, R4, R0

Aggiornamento di R3 col nuovo massimo.

SKIP:

ADDI

R1, R1, 4

Si prosegue nel vettore (nota l’operando immediato

SUBI

R2, R2, 1

4, dovuto all’elaborazione di word). Decrementiamo il contatore.

BNEZ

R2, LOOP

Se non abbiamo finito, ricominciamo da LOOP.

JR

R31

Se abbiamo finito, ritorniamo al programma chiamante.

Si scriva il codice Assembler DLX necessario ad invocare la procedura scritta al punto precedente in maniera tale che essa calcoli il massimo di un vettore di 10 elementi allocato all’indirizzo 8000H.

Dobbiamo mettere in R1 l’indirizzo 8000H

ADDUI

R1, R0, 8000H

Dobbiamo mettere il contatore a 10

ADDI

R2, R0, 10

Chiamiamo la procedura

JAL

PROC

Si faccia riferimento alla struttura pipelined del DLX (con presenza di Forwarding Unit e Register File che ritorna il nuovo valore in caso lettura e scrittura simultanee sullo stesso registro) e si assuma che i “branch” siano gestiti con politica “predict-not-taken”. Nell’ipotesi che la procedura scritta sia invocata su un vettore di 10 elementi tutti nulli, si calcoli il CPI medio relativo all’esecuzione della procedura utilizzando la formula CPI medio = 1 + s

Dimensione del vettore

Tutti gli elementi sono nulli quindi la BEQZ è sempre taken, mentre la politica adottata è quella di not-taken.

10 elementi

Numero di istruzioni: 6 (in rosso) x 2 + 2 = 62.

Ora esaminiamo gli stalli:

ISTRUZIONE

STALLI

TOTALE STALLI

LW

R4, 0(R1)

Uno stallo solo, per ritardare la fase di execute della SGTU.

10

BEQZ

R5, SKIP

Siamo nel caso predict not-taken. Siccome,

3

x 10 = 30

 

in realtà, la branch

è

sempre

taken

 

dobbiamo introdurre ogni volta 3 stati di stallo.

BNEZ

R2, LOOP

Nelle prima 9 operazioni è taken. Quando abbiamo terminato il nostro processo, invece, essa diventa not-taken.

3

x 9 = 27

JR

R31

Nella jump si fanno sempre 3 stalli

 

3

Numero di stalli = 10 + 30 + 27 + 3 = 70 Stalli / istruzione = 70 / 62 = circa 1.13

ESERCIZIO 1

Si supponga di voler estendere il set di istruzioni del DLX con l’istruzione

CMPS Rx, Ry, Rz

Dove gli operandi Rx, Ry, Rz rappresentano tre registri generali. L’istruzione CMPS (CoMPareString) confronta il dato di tipo unsigned byte situato in memoria all’indirizzo Rx con il dato dello stesso tipo situato in memoria agli indirizzi Ry: se i due dati risultano uguali il registro Rz viene posto a 1, altrimenti viene posto a 0. Una possibile descrizione RTL delle operazioni svolte dalla nuova istruzione è data da:

if(M[Rx] = M[Ry]) then Rz 1 else Rz 0

Si mostri come potrebbe essere codificata la nuova istruzione utilizzando il più idoneo fra i formati delle istruzioni del DLX.

Ci sono tre registri, dunque siamo obbligati ad usare il formato R

CMPS Rx, Ry, Rz

Rx

Ry

Rz

Non importanti

Rx

Primo registro sorgente

Ry

Secondo registro sorgente

Rz

Registro destinazione

Con riferimento al datapath del DLX sequenziale visto a lezione, si disegni il diagramma degli stati che controlla l’esecuzione della nuova istruzione inserendo anche gli stati necessari al fetch ed alla decodifica.

IR M[PC]

A

RS1

(cioè Rx)

B

RS2

(cioè Ry)

PC

PC + 4

MAR A

MDR M[MAR]

TEMP (0) 24 ## MDR 0

7

MAR B

MDR M[MAR]

TEMP == (0) 24 ## MDR 0

7

Abbiamo messo in TEMP (dobbiamo infatti caricare l’altro valore e dobbiamo disporre di MAR e MDR liberi) ciò che c’è in M[Rx] (è un byte, quindi 8 bit).

In temp c’è il valore di M[Rx], in MDR quello di M[Ry] Sono uguali?

C 1

Mettiamo o 1

No

C 0

oppure 0 in Rz

RD

C

Nell’ipotesi che tutti gli accessi alla memoria possano essere completati in 2 clock, si calcoli il numero di cicli di clock (CPI) necessari per l’esecuzione dell’istruzione.

In fucsia le fasi in cui dobbiamo accedere alla memoria.

CLOCK TOTALI: 7 + 2 x 3 = 13

Utilizzando la nuova istruzione CMPS si scriva un frammento di codice assembler DLX che confronta due stringe di 100 caratteri, memorizzate rispettivamente agli indirizzi 1000H e 2000H, e ritorna nel registro R3 il risultato del confronto (R3 = 1 se le stringe sono uguali, R3 = 0 se le stringhe sono diverse).

ADDI

R1, R0, 1000H

Indirizzo del primo vettore

ADDI

R2, R0, 2000H

Indirizzo del secondo vettore

ADDI

R4, R0, 100

Contatore dei caratteri

LOOP: CMPS

R1, R2, R3

Confronta gli elementi

BEQZ

R3, SKIP

Al primo elemento diverso, si salta a SKIP

ADDI

R1, R1, 1

Incremento del puntatore della prima stringa

ADDI

R2, R2, 1

Incremento del puntatore della seconda stringa

SUBI

R4, R4, 1

Decremento del contatore

BNEZ

R4, LOOP

Controllo del prossimo elemento

SKIP: …

Sempre con riferimento al DLX sequenziale (cioè non-pipelined), si calcoli il CPImedio del codice scritto al punto precedente nell’ipotesi che le due stringhe siano uguali. Per l’istruzione CMPS si utilizzi il CPI precedentemente calcolato e per le altre istruzioni i valori visti a lezione e deducibili dai diagrammi degli stati del controllo (si mantenga l’ipotesi che ogni accesso alla memoria richieda 2 clock).

ISTRUZIONE

QUANDO

CLOCK

ALU

Nell’inizializzazione (3 ALU); nel loop (300 ALU)

303 x 6 = 1818

BRANCH (taken)

99 volte la BNEZ R4, LOOP

99 x 5 = 495

BRANCH (not-taken)

100 volte la BEQZ R3, SKIP Perché tutti gli elementi sono uguali

101 x 4 = 404

1 volta la BNEZ

R4, LOOP

 

Per quando avremo finito il confronto

 

CMPS

100 volte nel loop

100 x 13 = 1300

CLOCK TOTALI = 1818 + 495 + 404 + 1300 = 4017 N° ISTRUZIONI TOTALI = 303 + 99 + 101 + 100 = 603

CPI MEDIO = 4017 / 603 = circa 6.66

ESERCIZIO 2

Con riferimento al datapath del DLX sequenziale (cioè non-pipelined) visto a lezione, si consideri la micro-operazione:

MAR A

Si specifichi quelli sono i segnali di controllo che devono essere attivati dal Controller per far sì che il Datapath esegua la micro-operazione precedente.

Si disegnino le forme d’onda dei segnali di controllo nell’ipotesi che il datapath esegua nel clock i la micro-operazione precedente e nel clock i+1 la micro-operazione

C A + MAR

ESERCIZIO 1

Si supponga di voler estendere il set di istruzioni del DLX con l’istruzione

SWAP_RM Rx, IMMEDIATE (Ry)

Dove Rx, Ry rappresentano due registri generali ed IMMEDIATE una costante signed a 16 bit. La nuova istruzione scambia fra loro il contenuto del registro Rx e della word situata in memoria all’indirizzo (Ry + IMMEDIATE).

Si mostri come potrebbe essere codificata la nuova istruzione utilizzando il più idoneo fra i tre formati delle istruzioni del DLX.

Il formato più idoneo è quello di tipo I

SWAP_RM

Rx

Ry

IMMEDIATE

Con riferimento al datapath del DLX sequenziale visto a lezione si disegni il diagramma degli stati che controlla l’esecuzione della nuova istruzione inserendo anche gli stati necessari al fetch e alla decodifica.

IR M[PC]

A RS1

(cioè Rx)

B RS2

(cioè Ry)

PC PC + 4

MAR B + (IR 15 ) 16 ## IR 15.0

MDR M[MAR]

C MDR

STATI DI WAIT

Ora in C abbiamo M[Ry+Immediate] STATI DI WAIT

MDR A RS1 C

Mettiamo in MDR il registro Rx Mettiamo Ry in Rx

M[MAR] MDR

Mettiamo in M[Ry+Immediate] Rx STATI DI WAIT

Nell’ipotesi che tutti gli accesi alla memoria possano essere completati in 2 clock, si calcoli il numero di cicli di clock (CPI) necessari per l’esecuzione dell’istruzione.

CPI = 4 + 3 x 2 = 10 Clock

Si scriva la sequenza di istruzioni appartenenti all’ISA DLX studiato a lezione che consente di eseguire un’operazione il più possibile simile a quella svolta dalla SWAP_RM Rx, IMMEDIATE(Ry). In cosa differiscono le due operazioni?

ADD

Rx, Rx, R0

Salvataggio di Rx in Rz

LW

Rx, IMMEDIATE(Ry)

Trasferimento di memoria da M[Ry+IMMEDIATE] a Rx

SW

IMMEDIATE(Ry), Rz

Trasferimento da Rz a memoria

Le due istruzioni differiscono per l’uso del registro Rz, che resta modificato al termine della sequenza.

ESERCIZIO 2

Si scriva il codice assembler DLX necessario all’esecuzione della seguente operazione descritta in un linguaggio di alto livello

For (i = 0; i < 100, i++) V1[i] = V2[V1[i]]

Dove V1 e V2 sono due vettori di unsigned-byte allocati rispettivamente all’indirizzo 400H ed all’indirizzo 0.

ADDI

R1, R0, 400H

Indice del vettore V1

ADDI

R3, R0, 100

Contatore delle iterazioni

LOOP: LBU

R2, 0(R1)

R2 è ora l’indice del vettore V1, cioè V1[i]

LBU

R2, 0(R2)

Ora mettiamo in R2 il contenuto riferito

SW

0(R1), R2

dall’indice trovato precedentemente Mettiamo ora tutto nel primo vettore

ADDI

R1, R1, 1

Incremento dell’indice di V1

SUBI

R3, R3, 1

Decremento del contatore iterazioni

BNEZ

R3, LOOP

Se non abbiamo ancora finito, continuiamo a looppare

Con riferimento al DLX sequenziale

all’esecuzione del codice scritto al punto precedente nell’ipotesi che ogni accesso alla memoria richieda 4 cicli di clock.

relativo

si

calcoli

il

CPI medio

Calcolo del CPI MEDIO:

ISTRUZIONE

QUANDO

 

CLOCK

 

ALU

2 (inizializzazione) + 2 x 100 (ciclo)

8 x 202 = 1616

LOAD

2 x 100 (ciclo)

12

x 200 = 2400

STORE

100 (ciclo)

11

x 100 = 1100

BRANCH (taken)

99 (ciclo)

 

7 x 99 = 693

BRANCH (not-taken)

1 (ciclo)

 

6 x

1 =

6

CLOCK TOTALI = 1616 + 2400 + 1100 + 693 + 6 = 5815 N° ISTRUZIONI TOTALI = 202 + 200 + 100 + 99 + 1 = 602 CPI MEDIO = 5815 / 602 = 9.66 circa