calcolatori 21

Upload: vittorio-troise

Post on 21-Feb-2018

213 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/24/2019 Calcolatori 21

    1/8

    Cosa cambia nel momento in cui vogliamo considerare un processore che fa anche elaborazione

    su dati fp, tenendo presente che un dato fp ha un'aritmeticacompletamentediversa da quella che

    avviene sui dati interi.

    Il floating point fa spostare la virgola in modo da averla posizionata a sinistra( anche a destrapi

    frequente) della cifra pi significativa, dopo di che il numero moltiplicato per un certo esponente

    che va, necessariamente, anche lui scritto nel numero. Alla fine ho un numero che comprende uncampo che si chiama esponente, l'altro mantissa pi il bit di segno che mi dice se il numero

    positivo o negativo. Abbiamo un bit di segno esplicito per la mantissa ed implicito per lesponente

    ( sar un numero complemento a 2, la mantissa in binario puro). Se dobbiamo fare una

    moltiplicazione tra questi dati bisogna fare la somma degli esponenti dei due fattori e fare il

    prodotto delle due mantisse, dopo di che dobbiamo normalizzare le mantisse. Se questo prodotto

    genera dei bit di over flow, non saranno persi, saranno considerati, ma diminuir i bit per il prodotto

    degli esponenti. Quindi vediamo come fare unoperazione del genere comporta un certo costo

    Somma, prodotto, devo fare una logica; per la divisone analoga. Invece per la somma non devo

    fare la somma tra le 2 mantisse, ma vanno prima allineate allo stesso esponente. Si confrontano

    gli esponenti, la differenza degli esponenti, il numero con exp minore si shifta a destra della

    differenza degli esponenti, sommeremo le 2 mantisse dopo averle allineate e osserveremo come

    esponente quello del maggiore. Se poi nella somma c stato un over flow o under flow, quindi

    sono scomparse delle cifre significative, potr spostare il numero a sinistra diminuendo

    lesponente. Una somma o differenza si fa confrontando gli esponenti, shiftando la mantissa del

    numero che ha exp minore e poi loperazione tra le mantisse. Questa logica leggermente pi

    complessa di quella vista sino ad ora e, se volessimo realizzarla in hardware, avremmo delle

    latenze differentiDevo integrare in un processore che vuole fare operazioni fp, una parte che

    faccia calcoli sui fp e posso ragionare in 2 maniere diverse. O un unico blocco che presenta al suo

    interno una serie di blocchetti ( la nostra ALU), oppure nella seguente maniera ( diverso da prima):

    Se dovessi fare un oggetto che integra il disegno sopra non tra le migliori scelte. Se c una

    coppia che vuole fare un prodotto, lo fa ma blocca tutto fin quando non arriva unaltra coppia che

    vuole fare qualcosaltro, questo per fare fin quando non arriva dura pi di un colpo di clock

    L'operazione fp dura pi di un colpo di clock. Siccome un calcolo fp, essendo pi lento rispetto

    quello fatto su aritmetica intera e dura di pi possiamo o ragionare nel modo tale che il colpo di

    clock diventa lungo quanto la latenza massima di questo tipo di operazioni. Se il divisore fp 20

    volte pi lento dellALU, possiamo prender il colpo di clock e farlo durare 20 in modo tale che la

    divisione verr fatta in un solo colpo di clock, anche se tutte le altre cose verranno fatte in colpi di

    clock molto pi lunghi di quelli strettamente necessari. Ogni fase durer 20 secondi. Allora

    decidiamo di procedere in unaltra maniera: manteniamo il colpo di clock per quella durata che

    andava bene a risolvere le problematiche legate alla pipeline di un processore a virgola fissa, e

    quando avremo caricato le virgole mobili, faremo si che quel dato duri pi colpi di clock.

    Si comincia a pensare a delle operazioni che hanno una fase EX multicicloIl colpo di clock

    rimasto lo stesso, ma siccome per forza di cose necessito di pi tempo allora durer pi colpi di

    clock. Nelle operazioni dove non abbiamo a che fare con op fp potremo continuare il nostro lavorocon dei colpi di clock in tempi contenuti e completare quelle istruzioni. Nel momento n cui un

    processore deve fare unoperazione che divisione tra 2 fp, ci sar la fase EX che durer 20 colpi

  • 7/24/2019 Calcolatori 21

    2/8

    di clock. Questo fa pensare che tenere gli oggetti bloccati ( se ne sto usando uno gli altri non posso

    sfruttarli) non una cosa intelligente: se dura 20 colpi di clock non ha senso, in caso di

    moltiplicazione, se la dovessi fare non potrei. A livello di aritmetica fp gli elementi di calcolo sono

    tra loro svincolati, ognuno fa vita a se. Se devi fare una divisione, inizio e se la prossima vuole fare

    un prodotto pu usare il moltiplicatore e non come prima che troviamo lALU impegnata. Possiamo

    pensare un processore fp, dove gli elementi di calcolo sonosvincolati, e se lo sono, dobbiamoavere un sistema di accesso che permetta un uso svincolato di questi elementi. Per cui non posso

    avere un latch uscita ALU, un latch A, un latch B, ma avr un BUS che porter 2 operandi a uno

    dei 2 oggetti e l'uscita, con un meccanismo di BUS, andr a scriversi nel registro indicato durante

    la fase di WB.

    Abbiamo un certo numero di elementi, la lorolatenza( tempo che perdo a fare il calcolo) sar

    diversa. Rinunciando all'approccio semplicistico di dilatare il colpo di clock dituttoil sistema, in

    base alla latenza pi lenta di questi elementi che ci porterebbe ad andare in maniera sottoutilizzata

    su tutte le altre parti del processore, continuiamo a tenere 1 colpo di clock per quello che avevamo

    trovato ( latenza memoria al posto dellALU) e ,in base a questo colpo di clock, strutturiamo

    l'hardware per operare con un numero di colpi di clock maggiore.

    Questo numero sar differente secondo le operazioni. Le operazioni multiciclo (hanno

    lunghezza e durata diversa) creano delle complicazioni non banali: se ho un'istruzione che

    produce X = Y + Z ( dati fp) piuttosto che una funzione che produce X= Y/Z (dati non fp), le

    operazioni sono diverse nel momento in cui il valore di X deve essere usato da un'istruzione

    successiva. Il risultato sar disponibile 4 colpi di clock o 24 ( se ipotizziamo che la durata

    delloperazione fp sia 24 e laltra 4) della sua fase di EX. Mentre con le operazioni che calcolavano

    dei risultati con l'ALU, come abbiamo sempre visto, e i risultati usati venivano prodotti da altre

    istruzioni, che poi cortocircuitavamo allingresso dell'ALU e non avevamo problemi di alcun tipo,

    l'unico si presentava quando il dato lo dovevamo prendere dalla memoria ( ricordiamo che questo

    era disponibile solo a partire della fine della fase MEMDovevo necessariamente inserire uno

    stallo). In una situazione del genere ( processore fp), il dato verr prodottosolodopo 24 colpi di

    clock, il che implicanecessariamenteil presentarsi di un problemaAbbiamo una gestione degli

    stalli per conflitto di dati estremamente pi complicata, perch la nostra X la avremodisponibiledopo un tot di colpi di clock. Diventa importante, quando si fa uso delle istruzioni fp, avere delle

    istruzioni che, nel momento in cui c' una particolare istruzione che produce X, e una che la

  • 7/24/2019 Calcolatori 21

    3/8

    consuma, farebbe comodo avere tra queste 2 istruzioni per completare il calcolo dell'istruzione( la

    X) stessa.

    Se queste istruzioni non ci sono, dovr necessariamente stallare il sistema. Vedremo, comunque,

    che ci saranno delle tecniche di schedulazioneper aiutareil processore a non stallarsi ( attuate

    dal compilatore con il solo scopo di trovare delle istruzioni da inserire per non far stallare il

    processore). Se la schedulazione non possibile il processore si dovr stallare.Dal momento in cui abbiamo una situazione in cui ho supposto che devo stallare, c la possibilit

    di stallare unistruzione e, di conseguenza, tutte quelle successive ( se le altre fossero andate

    avanti e si stallava solo quella che creava lo stallo, avrei avuto:1un conflitto strutturale e2un

    problema legato allutilizzo dei dati a partire dalle istruzioni successivi). Questo ragionamento

    appena esposto vale anche per i fp ma potrebbe essere dannoso dal punto di vista delle

    prestazioni(se dura 20 colpi di clock e blocco tutte le successive sto bloccando il calcolo per un

    lasso di tempoconsiderevole) del sistema. Laltra possibilit stallare la singola istruzione che

    crea problema e, difatti, quello che avverr a livello di gestione di un processore fp. Si avr la

    possibilit di stallare l'istruzione, masolamentelei.

    Quando abbiamo parlato di uno stallo in aritmetica fissa, abbiamo visto che dovevamo stallare

    anche tutte quelle che seguivanoLe fasi si trovavano in conflitto strutturale. E bene osservare

    che, quello che stavo bloccando, era un sistema basato su 1 solo colpo di clock. Ora la situazione

    tale che il blocco che viene effettuato, potrebbe essere anche di 20 colpi di clock, che hanno

    unimportanza ben diversa rispetto 1 colpo di clock e, per questa motivazione, si pensa di stallare

    una sola istruzione e non tutte le altre. Se si riesce a fare ci, abbiamo che il programma va avanti.

    Ovviamente c' un costo, perch devo valutare che non ci siano altre istruzioni, nel caso in cui ne

    abbia bloccato una e voglia andare avanti, che usano il risultato dell'istruzione che sto stallando In

    quel caso anche quelle dovranno essere stallate. Dovremo anche fare in modo che, se l'istruzione

    sta producendo X e l'istruzione che sto stallando produrr Z, se esiste unistruzione che usa A e B (per esempio) per produrre qualcosa che dovr essere sovrascritto in Z, anche lei dovr essere

    stallata se no rischia di: finire prima, calcolare Z, scriverlo e poi il Z, che sar a rigore di logica pi

    recente verr sovrascritto quando laltra istruzione terminer. Dobbiamo avere, perci, un

    meccanismo che permetta che le istruzioni vengano completate in manierafuori ordine

    Nellaritmetica intera, quando bloccavo unistruzione, bloccavo tutte le altre e quando riprendeva,

    riprendevano le altre terminandole nellordine in cui mi arrivavano. Qui, stallando solo una

    particolare istruzione, pu verificarsi che una di queste, termini dopo che una iniziata dopo di lei.

    (pu avvenire anche in assenza di stalli). Il tutto porta ad una gestione degli operandi con un

    algoritmo che prende il nome di algoritmo di Tomasulo.Cosa fa?Usa una serie di tabelle,

    all'interno del processore,( per essere pi precisi si trovano dentro la CU del processore) che

    gestiscono, come semafori,l'accesso ai dati e alle risorse.Sostanzialmente se un'istruzione

    vuole usare il moltiplicatore e, per usare il moltiplicatore necessita di 2 operandi di cui uno deve

    essere prodotto dall'istruzione precedente, non ha senso farla entrare e bloccare il processore, ma

    converr farla entrare solamente quando i suoi operandi sarannodisponibili.

    Se unistruzione deve fare una moltiplicazione e si trova nella fase M2 pu utilizzarsi il

    moltiplicatore da parte di unaltra istruzione?( riferito a immagine sopra)Le unit per il calcolo

    possono, anche loro, essere gestite in pipeline e se un'altra coppia le vuole usare potr

    tranquillamente farlo: l'unico vincolo presente all'ingresso e all'uscita ( il BUS). Solo queste due

    operazioni ( accesso e uscita)non sono simultanee.

  • 7/24/2019 Calcolatori 21

    4/8

    Dal punto di vista dell'architettura non basta "aggiungere" i blocchi, ma servono anche dei registri

    che permettano di contenere i dati fp. In manierasuperficialesi pu pensare di avere gi i registri

    che al posto di contenere 32 dati interi conterranno, a seconda delloccorrenza, 21 dati intera e 11

    fp ( per esempio). In realt ci non ha molto senso, perch avevamo che quei registri, che

    conosciamo, sono collegati tramite il latch A e B allALU. Se abbiamo che uno qualsiasi di questi

    registri pu essere mandato sia in A che in B, e iniziamo a dire che uno qualsiasi di questi registri

    pu contenere un dato fp che deve essere mandato sul BUS che va in ingresso al

    moltiplicatore/divisore/ecc. fp, siamo facendo qualcosa che appesantisce inutilmente larchitettura.

    Per esempio se dico che R6 pu contenere, a seconda dellesigenza, un dato fp o intero, deve

    avere una logica per andare a destra, ma anche sotto ( nella figura sopra ) tenendo presente che

    uno di quei dati, o meglio una certa variabile, nella sua vita, non potr essere intera e fp

    contemporaneamente. Una variabile, in un programma, nasce in una maniera e cos muore. Non

    ha senso che un fp user A e B per un calcolo intero, cosi come un intero non user sommatore,

    moltiplicatore, ecc. fp.Quando faccio una customizzazione della variabile, di fatto ne sto

    creando unaltra( la variabile di rango maggiore viene customizzata a fp). Ha pi senso pensare

    a un banco di registri fp collegato alle sue unit di calcolo fp, mentre il banco dei registri sarcollegato allALU. Ci sar la possibilit di conversare tra i 2 registri, perch, alle volte, sono

    necessarie delle conversioni di dati. Se vogliamo fare unoperazione di questo genere, dovremo:

    leggere da qualche parte nel registro R quanto vale lintero X e convertirlo in fp; la sua versione fp

    sar copiata in uno dei registri fp e da li si acceder allelemento. Esiste, tra i due mondi, una

    specie di dogana. Dal punto di vista strutturale, un processore che usa aritmetica fp, avr dei

    registri che possono contenere fp, connessi con un meccanismo di BUS ad una struttura che fa le

    operazioni. Questa struttura mantenuta in maniera dicotomica (no fp) da una parte e individuale

    (fp) nellaltra.

    In questo sistema descritto, abbiamo la necessit di gestire una serie di problematiche: stalli che

    non avevamo nellaritmetica intera ( quelli che avevamo indicato come: RAW, WAR, WAW, RAR).

    Avevamo visto che, lunico che causava problemi, era la RAW, (non potevamo aspettare che

    listruzione precedente lo scrivesse nella WB, perci lo si andava a prendere, per risparmiare

    tempo, in ALUoutput o LMD) ma ora anche WAW pu causare dei problemi: se abbiamo 2

    istruzioni come una divisione che vuole scrivere X, unaltra che vuole scrivere X come somma, e

    se la somma vienedopola divisione, lei, se le cose non sono soggette a controllo, andr a

    scrivere X prima che, quella prima di lei, labbia scritta. Vediamo i vari casi con esempi:

    WAW: Se X= Y*Z avviene prima di X= A+B, la prima dura 24 colpi di clock e non ci sono altre

    istruzioni tra loro 2, allora la 2 scriver prima della 1 operazione.

    WAR: Y= X+Q, se Q deve essere ancora prodotto stallo listruzione. Nel frattempo, X= A+B,continua e quando finisce scriver X. Quindi, se stallo la 1 dovr stallare anche l'altra.

  • 7/24/2019 Calcolatori 21

    5/8

    RAW: Esisteva gi nel caso intero e continua a esistere nel caso fp. Abbiamo un'istruzione che

    scrive X= Y+Q e un'altra Q= X/B. Siccome questultima deve leggere X dopo che una precedente

    lha scritto, dovr aspettare.

    Infine abbiamo laRAR: falso problema anche in questo casoNessuno dei due modifica niente.

    Con problematiche di questo genere lo studio degli stalli inizia a essere delicato. Nell'aritmeticaintera conflitti strutturali non se ne avevano mai. Conflitti di dato, qualche volta, ma con la corto

    circuitazione si creava lo stallosoloin fase di LOAD. Ora abbiamo visto esserci conflitti di memoria

    (prelevo un dato o istruzione, non la trovo in cache) e una serie di stalli legati alle operazioni, dove

    queste operazioni sono diverse anche dal punto di vista della penalizzazione.In che senso?

    Abbiamo una penalizzazione legata alle operazioni di somma, sottrazione conversione; una

    penalizzazione legata ai confronti, ma si differenziano specialmente quelle legate a moltiplicatori e

    divisori.

    Le divisioni sono la causa del maggior numero di stalli e a seguire la moltiplicazione. Non

    dobbiamo pensare solo al fatto che la divisione pi lenta; fortunatamente anche l'operazione

    meno frequente negli algoritmi rispetto alla somma o prodotto.

    Queste sono le fasi che intervengono nel momento in cui abbiamo la gestione del processore fp in

    cui la fase di fetch dellistruzione e quella di accesso ai dati sono a sua volta suddivise in una serie

    di sotto fasiSto cercando di ridurre il colpo di clock al minimo, si ridotto mantenendosi integro

    nel calcolo intero, mentre nella MEM e memoria istruzioni sono state un po dilatate.

    Vediamo l'accesso agli elementi strutturali.

    E direttamente connesso al banco dei registri (fp). Abbiamo una serie di elementi, tra cui 2

    moltiplicatori, un divisore, un sommatore, ununit di calcolo intera.Come avviene il meccanismo di

    accesso a questi elementi?I dati vengono inviati in ingresso agli oggetti che ne fanno il calcolo, i

    risultati vanno a scriversi nel banco dei registri e abbiamo un elemento di logica che controlla i

    registri nel senso se quei registri contengono effettivamente il dato che si aspetta che essi

    contenganoNon sono dei registri che non contengono ancora il risultato perch deve essereancora prodotto. Lelemento di logica si chiamascoreboard. Perch abbiamo 2 moltiplicatori?Per

    ottimizzare il numero di stalli che si avrebbe nel sistema stesso. Se voglio ottimizzare le

  • 7/24/2019 Calcolatori 21

    6/8

    prestazioni, e ho spazio nel processore, aggiungo dell'hardware. Potrei mettere il divisore dato che

    abbiamo detto che sono queste le operazioni pi lente, ma non convenire perch sono meno

    frequenti e gli stalli strutturali delle divisioni sono pochi. In pi, dal punto di visto hardware, il pi

    complesso e costoso. Il sommatore veloce e presenta un hardware molto semplice, non c

    bisogno di aggiungerne altri. Rimane, e conviene, il moltiplicatore che ha una hardweristica pi

    semplice ed pi frequente

    Ha senso, quindi, affiancare 2 moltiplicatori.

    Schedulazione

    Dal momento in cui abbiamo la necessit di reperire istruzioni da schedulare tra ,unistruzione che

    produce un risultato, e unaltra che la va a usare, c' bisogno di trovare, nel listato, le istruzioni che

    si possono intermezzare tra chi produce il risultato e chi lo usa. Se queste istruzioni, in numero

    devono essere considerevoli, un algoritmo scritto in maniera classica difficilmente d agio al

    compilatore di trovare queste istruzioni. Esistono 2 tecniche: una di queste lo srotolamento del

    loop (loop unrolling). Supponiamo di voler fare il prodotto di 2 vettori: abbiamo il vettore X e il

    vettore Y che, moltiplicati, danno Z che verr, a sua volta, scritto in memoria.

    Supponiamo che X caricato in memoria a partire dall'indirizzo 1000, Y a partire 2000 e Z dovr

    essere scritto a partire dall'indirizzo 3000. ( In blu ci che aggiungo dopo leggendo sotto)

    ADDI R1 800 Ro

    LOAD F1 R1 1000

    LOAD F2 R1 2000

    MULT F3 F1 F2

    STORE F3 R1 3000

    ADDI R1 R1-8

    BNEZ R1-6

    Supponiamo di avere 100 elementi per ognuno dei 2 risultati. Bisogna impostare un controllo inmaniera tale che, quando abbiamo finito il nostro lavoro, dobbiamo uscire dal loop. Generalmente i

    loop sono gestiti in manieradecrescente. O parto da R1 che va da 0 a 99, e confronto R1 alla

    fine con 99 per vedere se sono arrivato alla fineE pi costoso dal punto di vista del tempo

    piuttosto che confrontare R1 con 0. Per questo si fa in modo che R1 punti allultimo elemento del

    vettore e, mano a mano, si decrementa e quando punta a 0 ho la condizione di uscita. Quando R1

    punter a 0, devo far si di stare fuori dal mio vettore, da 1 a 100 dentro il loop, 0 fuori per poter

    impostare cos un loop del tipo BNEZ R1. L'ultimo elemento del vettore, che il 1 di memoria,

    sar qualcosa ottenuta con R1 > 0 dove R1 non passa di 1 in 1, ma se sono dati di 8 byte andr di

    8 in 8. Il primo elemento sar caricato allindirizzo 1000, il 2 1008, il 3 1016 fino allindirizzo 1792.

    Avremo la memoria occupata da 1000 a 1800 ( 100 elementi da 8 byte) dove lultimo elemento, da

    8 byte, parte da 1792. Ciascuno skippa di 8 byte in memoria, quindi R1 verr incrementato ( nel

    nostro caso decrementato )di 8 e quando arriver a 0, dovr puntare fuori dal vettore e uscire.

    Come mi costruisco la struttura?Faccio si che loffset ( quello che ho scritto pari a

    1000,2000,3000) al posto di 1000 vada 992, al posto di 2000 1992 e al posto di 3000 2992.

    R1 partir da 800 e via via si decrementer in modo tale che 800 +992 = 1792Ultimo elemento.

    Poi incremento. Quando R1 vale 8 ho 992+8=1000, lo decremento, R1 vale 0, BNEZ non

    soddisfatta e sono uscito dal loop. Lalgoritmo : R1 parte da 800, quindi posso fare un ADDI ( in

    blu). Devo decrementare il mio R1 di 8 ( sommo limmediato -8), se R1 non 0 salto e conto 6

    istruzioni ( il compilatore prender limmediato -6 aggiunger due 00 e avr -24). Questo il mioloop.E scritto bene?Dal punto di vista della logica e del funzionamento scritto bene, ma dal

    punto di vista delle prestazioni non il massimo, perch gi nella 2 LOAD ho uno stallo( prodotto

  • 7/24/2019 Calcolatori 21

    7/8

    fa uso di F2), dopo la MULT ho 7 stalli. Facciamo la STORE, decrementiamo e facciamo la BNEZ

    ma avr 1 stallo anche qua perch la BNEZ si basa su R1 e questo R1 non stato ancora

    calcolato. Per ridurre gli stalli potrei spostare un po le istruzioni mettendo l ADDI dopo la LOAD,

    eliminando lo stallo di prima e anche quello che stava dopo ADDI. Siccome i due R1( uno pi

    piccolo dellaltro di 8, per questo quello che stato tolto a uno lo possiamo regalare allimmediato

    delloperazione dopo) lavorano con un immediato, so con che cosa sto trattando e quindi nel casodella STORE faccio 3008. Ci possibile perch ho delle quantit note come gli immediati, se ci

    fosse stato un registro al posto dell'immediato non avrei potuto fare ci.

    Da un loop che dura 6 istruzioni, in totale ne dura 10Quasi raddoppio il tempo per eseguire

    questo loop. Interveniamo ( compilatore) allora con ci che avevamo detto essere lo srotolamento

    del loop. Supponiamo che in uniterazione del loop non lavoro soltanto su un elemento del vettore,

    ma sul 1,2,3,4,5 poi faremo unaltra iterazione del loop e lavoreremo dal 6 al 10 elemento.

    Ogni volta che prendiamo uniterazione, stiamo lavorando 5 elementi del vettore. Questo fa si che

    le iterazioni saranno quel numero diviso 5. Attenzione, per, che ogni iterazione far un

    determinato lavoro. Vediamo cosa succede se organizzo lo srotolamento in 4;

    ADDI R1 800 R1

    LOAD F1 992 R1

    LOAD F2 1992 R2

    MULT F3 F1 F2

    STORE F3 2992 R1

    ADDI//momentaneamente la tolgo, procedo con la carica del 2 elemento

    Questo il gruppo che fa loperazione sul 1 elemento del vettore. Non faccio lincremento di 8,

    altro loop e incremento di -8 perch se no farei 4 volte il decremento. Vado con la carica dellaltro

    elemento e faccio man mano il decremento di 8. R1 rimasto non decrementato e allora possofare 992-8.

    LOAD F1 984 R1

    LOAD F2 1984 R1

    MULT F3 F1 F2

    STORE F3 2984 R1

    Lo faccio altre 2 volte. Dopo aver srotolato 4 volte, decremento R1, per devo decrementare R1 e

    la prossima volta devo puntare a 960+800 e, siccome devo fare 992 + 800, allora devo

    decrementare R1 di 32. Dopo 968 ho ADDI R1 R1-32. Sostanzialmente questo decremento vale

    quello che faccio in un loop, -8, moltiplicato il numero delle repliche che ho messo nel loop

    srotolato. Ne ho messe 4, quindi 8x4= 32 e decrementer di 32. Il codice cos scritto corretto ma

    non massimo. Qualche miglioramento c, perch avr una sola ADDI e una sola BNEZ.

    Abbiamo srotolato per ridurre gli stalli tra la MULT e la STORE. Ci accorgiamo che continuano a

    esistere questi stalli. Se prima avevamo 6 stalli, anche ora li ho. Ho 4 gruppi di 6 stalli; sembra che

    non ho risolto molto. Attenzione: fare la STORE dopo la MULT non indispensabile, qualche

    istruzione tra la MULT e la STORE si pu cercare e mettere, per esempio, la 2 MULT sotto se ho

    messo le altre 2 LOAD sotto e via dicendo.Che cosa avviene se metto tutte le LOAD insieme, tuttele MULT insieme?Il codice viene scritto nel seguente modo:

    L X1

  • 7/24/2019 Calcolatori 21

    8/8

    L Y1

    L X2

    L Y2

    L X3

    L Y3

    L X4L Y4

    M Z1

    M Z2

    M Z3

    M Z4

    S Z1

    S Z2

    S Z3

    S Z4

    Se suppongo che la MULT duri 3 colpi di clock, vediamo che non ho problemi di stallo. Pago il fatto

    che la MULT, che usa Z1, usa X1 e Y1. Se usassi gli stessi registri, sovrascriverei quelli della prima

    coppia. (Se la MULT avesse latenza per 6 srotolerei per 6). Ho un loop con pi istruzioni e sono

    riuscito a evitare del tutto gli stalli. Per ogni coppia devo usare una coppia differenteSto usando

    pi registri. Quando faccio ci ho 2 costi: un costo che, in memoria programma, ho un codice

    pi lungo avendo pi istruzioni, ma un costo abbastanza trascurabile. Quello pi critico , come

    gi detto, l'utilizzo di pi registriQuesto il vero costo che si paga.