calcolatori 22

Upload: vittorio-troise

Post on 21-Feb-2018

220 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/24/2019 Calcolatori 22

    1/12

    Bisogna gestire ci che avviene, evitando gli stalli che, nella struttura pipeline a virgola fissa, non

    avvenivano didefault. Larchitettura prevede questa strategia: abbiamo, all'interno del processore,

    inframezzando la parte di input, che si trova tra la CU e i registri, quello che chiamiamostazioni di

    prenotazione.Sostanzialmente gestiremo lesecuzione dellistruzione attraverso queste, che sono

    dei buffer dove, ogni volta che un'istruzione vuole andare ad allocare una risorsa (tipo un

    sommatore, moltiplicatore, ecc.) vengono impegnate da delle informazioni legate all'istruzione

    stessa. Il buffer prende il nome dicoda di istruzioni. Una volta che unistruzione viene caricata, la

    sua esecuzione viene suddivisa in 3 macrofasi, legate alla possibilit che ci siano risultati di

    istruzioni precedenti che producono, a loro volta, risultati di input liberi. Poi parte l'esecuzione e

    infine si ha l'aggiornamento del risultato finale. Avremo unincodamentodelle istruzioni in questo

    buffer; da questo buffer, queste istruzioni, si verranno a prenotare a una stazione, a seconda di

    quello che devono fare, e, una volta prodotto il risultato, oltre a fare il WB nel registro fp, questa

    retroazione del risultato viene, cortocircuitata per andare eventualmente a impegnare (e

    aggiornare) il valore di uno dei campi delle stazioni di prenotazione. Dentro le caselle di

    quest'ultime, ci sono delle informazioni che sono il tipo di operazione. Nella casella, la pi stretta, il

    campo viene aggiornato da uninformazione che proviene dalla coda delle istruzioni. Poi abbiamo i

    2 operandi che normalmente vengono scritti dai registri, alle volte possono essere prelevati dal

    bus: ilcommon data bus. I dati prodotti dalle unit possono essere messe in comune sia con icampi dei registri fp, sia con la stazione di prenotazione.

    Possiamo avere la circostanza di una particolare istruzione che fa uso di alcuni dati, non ancora

    pronta perch un dato non stato ancora prodotto, e unaltra istruzione che occupa un altro posto

    della stazione di prenotazione ed gi prontaPu essere gi inserita nellunit. E quello che

    abbiamo chiamato, nella lezione precedente, gestione fuori ordine delle istruzioni.

    Vediamo le 3 macrofasi che identificano l'esecuzione dell'istruzione:

    1)Emissione: in questa macrofase un'istruzione, che la 1 che si trova nella coda delle

    istruzioni, ( gestite con FIFOIn ordine almeno in fase di emissione) viene estratta da quella

    coda e, a seconda che gli operandi siano disponibili o meno, (pi che a un conflitto di dati sipensa a conflitto strutturale) se c' un posto libero nella stazione di prenotazione nell'unit

    funzionale di quell'istruzione, l istruzione viene emessa e inserita nella coda di prenotazione

  • 7/24/2019 Calcolatori 22

    2/12

    dell'unit funzionale dell'istruzione. Per capirlo meglio, abbiamo la 1 istruzione in coda della

    coda delle istruzioni, supponiamo che una MULT. Il moltiplicatore, tra le sue stazioni di

    prenotazione, (possono essere 2-3-4 a seconda della capienza del buffer stazione di

    prenotazione),ha un posto libero dove mettere questa istruzione?Si? Allora viene tolta dalla

    coda delle istruzioni e impegna un posto nella coda di prenotazione dellunit funzionale che lei

    deve usare. La 1 istruzione in coda , per esempio una somma, se c una stazione liberaviene inserita dentroE emessa, esce dalla coda e prenota la sua unit funzionale.

    L'istruzione per essere attiva, ed entrare in esecuzione, deve avere la disponibilit

    dell'hardware , ma anche la disponibilit degli operandi sorgente. Se alcuni di questi non

    sono disponibili, l'istruzione che sta in quella coda di prenotazione, si mette a osservare, un po

    con un meccanismo di snoopy, il common data BUS. Questo un bus, scritto dalle unit

    funzionali, che poi va o nel banco dei registri o nelle stazioni di prenotazioni( solo quando

    serve). Supponiamo di avere unistruzione che vuole usare un registro come input, che non

    pronto. Supponiamo che listruzione voglia usare F8; ci serve sapere se il registro F8 pronto,

    ovvero se il valore di F8 nel banco dei registri effettivamentequello, oppure se F8 il

    risultato di unistruzione che deve essere ancora completataServe una struttura per capire

    ci. Supponiamo che da questa struttura, nella coda di prenotazione, sia evidente che

    listruzione che vuole usare F8, voglia usare un registro non ancora pronto. Nel momento in cui

    unistruzione, in coda di prenotazione, si accorge di questo, sa che non pu iniziare fin quando

    non ha loperando sorgente disponibile. Per, pi che aspettare che loperando sorgente

    disponibile venga scritto nel banco dei registri e poi da li venga a lei, si mette a osservare il

    common data bus. Nel momento in cui lunit funzionale, che deve produrre quel dato, lo ha

    prodotto, lui se ne va in F8 ma, mentre se ne va, loprelevoeaggiornoil contenuto del

    particolare campo della stazione di prenotazione che vuole usare F8. Se latro input era F6,

    che era gi disponibile, posso iniziare il lavoro. L'esecuzione parte quando tutti i risultati dinputsono disponibili e, ovviamente, ho a disposizione l'unit funzionale.

    Si noti che pi istruzioni possono diventare eseguibili per una stessa unit funzionale nel

    medesimo ciclo di clock. Supponiamo 2istruzioni nella stessa stazione di prenotazione che

    vogliono entrambe usare il moltiplicatore. Una aspetta F6 e laltra F8. F8 prodotto dal

    moltiplicatore e F6 dal sommatore, che aveva iniziato il suo lavoro un po pi tardi. A questo

    punto lesecuzione pu essere eseguita in maniera casualeNel momento in cui listruzione

    stata messa nella stazione di prenotazione hapari prioritcon le altre istruzioni. Non

    importante chi inizier prima. Se entrambe hanno i risultati pronti, potrebbero iniziare entrambe

    prima dell'altra, senza alcun problema. Nel momento in cui viene eseguita listruzione, questa

    viene a completarsi quando l'istruzione viene scritta nell'apposito registro e passa nel common

    data bus e, se viene intercettato perch ha un dato input di unaltra istruzione, il dato usato

    per aggiornare sia l'operando input di una certa istruzione, che per essere scritto nel registro

    sorgente.

    Quali sono i campi della stazione di prenotazione?

    I campi in figura sono 3 ma nella realt sono 7:

    Op: Viene aggiornato dalla coda delle istruzioni e viene segnata listruzione che l'unita

    funzionale deve fare. Supponiamo che siamo nella situazione della memoria e

    dobbiamo fare una somma o differenza, lo devo specificare e via dicendo.

    Qj & Qk: Sono 2 campi che fanno riferimento alle eventuali unit funzionali che stannoproducendo i 2 input, J 1 input, K 2 input. Nellipotesi in cui questa particolare

    istruzione deve usare come input un registro che non pronto, in Qj o Qk, a seconda

  • 7/24/2019 Calcolatori 22

    3/12

    delloperando, scriveranno un codice che identifica quali sono le unit funzionali dalle

    quali uscir il valore di Vj e Vk. Se questultimi sono pronti, Qj e Qk valgono 0. Se i dati

    non sono pronti, Qj e Qk indicano un codice che specificada doveverranno prodotti

    quei dati. Quindi starattento a intercettare quei dati, prodotti da quelleventuale

    modulo, sul common data bus.

    Vj & Vk: Sono 2 campi che hanno senso solo se Qj e Qk valgono 0 perch in Vj e in Vkstanno scritti gli operandi. Quando unistruzione entra in una stazione di prenotazione,

    che vuole usare F6 e F8, se F6 disponibile allora in Vj, dal banco dei registri viene

    prelevato F6 e si va a scrivere in quel campo. ( copiato in Vj e in Qj viene messo 0). Se

    non disponibile in Qj viene inserito 3, per esempio, e il valore di Vj ha un qualcosa che

    non ha valore. Lo stesso dicasi per k.

    A: Viene usato nel momento in cui parliamo di stazione di prenotazione, dove un

    hardware dedicato ha calcolato lindirizzo di memoria stesso e, nellipotesi di una LOAD

    o STORE, quel campo stato inizializzato dallindirizzo che viene calcolato da una unit

    funzionale specificatamente preposta a questo. Nello schema, lunit di indirizzamento,

    calcola lindirizzo.Come?Preleva listruzione; questa conterr limmediato, al suo

    interno viene estesa in segno, avr una porta di ingresso al banco dei registri interi, far

    la somma e calcoler lindirizzo inserendolo nel buffer di LOAD o STORE. Quello di

    STORE contiene, oltre lindirizzo, anche il dato fp che deve essere inserito in memoria.

    La stazione di prenotazione della memoria funziona con un campo che

    semplicemente lindirizzo per le istruzioni di LOAD, mentre per le STORE c anche un

    altro campo prelevato o dal common bus o dal campo dei registri.

    Busy: Indica se la stazione di prenotazione occupata oppure no; nel senso che, nel

    momento in cui devo emettere un'istruzione, devo controllare se una casella della

    stazione di prenotazione disponibile. Questo si fa vedendo un bit associato aciascuna riga/casella di quella stazione di prenotazione. Una volta impegnata una delle

    righe, prendo una riga in cui il bit 0, scrivo le informazioni imponendo quel busy bit

    uguale a 1 e, quando completo l'istruzione legata a quella casella, ritorner a mettere 0

    al bit busy.

    Qi:Legato a ciascuno dei registri. Rappresenta il meccanismo per far capire se un

    registro pronto oppure no. Abbiamo una tabella che ha tante caselle quanti sono i

    registri fp, se un'istruzione, che entrata in una stazione di prenotazione, deve

    calcolare F6 (per esempio), essendo stata inserita nella stazione di prenotazione di

    ununit funzionale unistruzione che deve calcolare F6, il suo contenuto non ha alcun

    valore ( nel campo dei registri). In questa tabella, alla casella associata a F6 vado a

    scrivere qual l'unit funzionale che deve produrre F6. In fase transitoria, in cui nulla

    deve essere prodotto, le Qi sono tutte uguali a 0 ad indicare chenessunaunit

    funzionale sta producendo il particolare valore di quel registro.

    2)Scrittura

    3)Esecuzione

    4)Conferma o consolidamento:Quando un dato arrivato nel buffer di riordino e quel dato

    proviene da unistruzione che stata confermata, allora viene consolidato e se ne va in

    memoria se serviva per fare una STORE o nel banco dei registri se era un WB.

  • 7/24/2019 Calcolatori 22

    4/12

    Vediamo meglio lultimo registro.

    Qi=0 significa che quel registro disponibile; Qi uguale a un certo numero significa che il registro

    associato a Qi, per esempio Q19, nel senso che F19. Se vale 5, significa che lunit funzionale 5

    sta producendo questo F19. Se Q19 vale 0, F19 significativo. Ritornando al discorso della

    stazione di prenotazione che viene impegnata da unistruzione: nel momento in cui listruzione

    viene emessa e vuole fare uso dellinput F5 e F6, si va a vedere Q5 e Q6. Se valgono 0, dal bancodei registri fp vengono presi F5 e F6 e vengono inseriti nel campo Vj e Vk. Se Q5 vale 0 e Q6 vale

    1, allora F5 disponibile ed preso dal banco dei registri e messo in V5; in V6 non scrivo niente

    perch non ha alcun significato, ma in Qk scrivo lo stesso numero che trovo scritto nella tabella del

    banco dei registri.

    Abbiamo la coda della stazione di prenotazione di una particolare unit funzionale, che deve fare

    loperazione di cui questistruzione si occupa: MULT. Vado nella coda della stazione di

    prenotazione del moltiplicatore. Lei vuole fare F6*F8 = F10. Per ciascuno dei registri abbiamo il

    campo Qi. Nel momento in cui listruzione arriva, listruzione fa si che si scriva che F10 prodotta

    da questa unit funzionale e, se qualcuno lo chiede, non va dato (F10). Il moltiplicatore associato

    al numero 1, per dire che F10 non ha valore, anche se non ho ancora iniziato. Questa cosa

    avvenuta nella seguente maniera: se poco fa qualche istruzione richiedeva F10, essendo stata

    emessa dalla coda di istruzioni, listruzione prima di lei stata emessa, ha trovato 0 e listruzioneha preso dal banco dei registri F10. Se viene messa dopo di questa unaltra istruzione che vuole

    usare F10, non la andr a prendere dal banco dei registri, ma osserver il common data bus in

    attesa che qualcuno produca F10.Cosa succede su F6 e F8?Voglio usarli come input, trovo 0 a

    F6E disponibile. Qj viene messo a 0 perch ho disponibile il dato ( copiato rispetto la tabella a

    destra); in Vj, dal banco dei registri, copio F6. Poi vedo F8: vado nella tabella e ha come campo Q

    il valore 2. Quindi in Qk copio 2 e non prendo F8 perch non ha alcun valore. Questistruzione

    attender che, dal common data bus, venga prodotto, dallunit funzionale 2, il risultato, in maniera

    tale che, una volta prodotto, andr nel banco dei registri e durante il viaggio lo catturer, lo

    metter dentro e porr a 0 il campo. Solo dopo aver avuto i 2 operandi potr continuare il mio

    lavoro ( nel moltiplicatore) e produrre F10. Dal common data bus andr nel banco dei registri,

    scriver 0, e chi voleva F10 lo intercetter.

    La tabella a destra mi dice lunit funzionale che sta usando quel dato ( direttamente associato a

    un particolare registro), le caselle non sono legate al registri ma al 1 e 2 operando.

    Abbiamo un codice in cui c una moltiplicazione che fa un calcolo e unaltra che ne fa unaltra.

    Entrambe sono arrivate nella stazione di prenotazione e entrambe hanno il diritto di essere

    eseguite. Posso procedere eseguendo quella che entrata prima, ma potrebbe capitare che il

    risultato di questa, usata dopo, usata in unaltra istruzione e quindi se eseguivo laltra potevo farpartire quella di dopo. Non ho nessun elemento per sapere se meglio eseguire una o laltra

    perch limportante che, una volta arrivate, vengano eseguite. In coda non detto che vengano

  • 7/24/2019 Calcolatori 22

    5/12

    eseguite nellordine in cui arrivano. In pi non c alcun controlloAltrimenti non sarebbero

    arrivate.

    Vediamo un esempio in cui abbiamo il seguente programma:

    1.L.D F6, 32(R2)2.L.D. F2, 44(R3)

    3.MUL.D F0, F2, F4

    4.SUB.D F8, F2, F6

    5.DIV.D F10, F0, F6

    6.ADD.D F6, F8, F2

    Nel momento in cui abbiamo una LOAD, il campo dellistruzione prevede, come nella LOAD intera,

    un immediato, un codice che identifica un registro e un codice che identifica un destinazione.

    Attenzione che rispetto alla LOAD intera, il campo degli operandi identico. Se avessimo una

    LOAD intera con 6 2 32 stiamo facendo la load di 32+ R2 in R6, per il codice operativo di quella

    LOAD diverso da quello della L.D. Il codice operativo della L.D specifica che quel 6 non R6 ma

    F6 mentre 2 sempre R2 perch lindirizzo calcolato da un immediato e da un registro intero.

    Cosa vuole fare questo codice?

    Vuole caricare F6 e F2, eventualmente F4 era gi disponibile per quello che vuole fare la

    moltiplicazione prendere F2 e moltiplicarlo per F4. Il risultato della moltiplicazione sar F0.

    Sempre F2 usato come input nella SUB che vuole usare come input F6 a produrre F8. Poi una

    DIV che vuole usare F6 output della prima LOAD e F0 che loutput della moltiplicazione. Ci sono

    una serie di dipendenze. Viene prodotto F10 e infine, F2, con F8, risultato della SUB, dovr essere

    usato dalla ADD per produrre F6 che sovrascriver lF6 precedentemente trovato.

    Queste istruzioni sono state tutte emesse, ma in un particolare istante sono entrate in esecuzione

    solo le 2 LOAD. Perch non le altre?Perch stata completata solo la 1 LOAD come si vede in

    tabella. La 2 LOAD stata messa in esecuzione, per nel momento in cui la 1 stata completata

    e la 2 sta per essere completata, gioco forza nessuna di queste pu entrare in esecuzione. Nella

    MULT F4 pronto, per non vuole usare F6 che gi disponibile, ma vuole usare F2 che non

    stato ancora scritto e quindi non entra in esecuzione ( si trova nella stazione di prenotazione e sta

    ascoltando il common data bus in attesa che esca F2). La SUB sta anche lei aspettando che esca

    F2. La DIV ha disponibile F6, ma F0 non pu prenderlo dal banco dei registri perch la Qi di F0

    dice che quellF0 deve essere prodotto dalla MULT che deve ancora iniziareNon disponibile.

    Non avendo pronti nessuno degli oggetti la DIV e la ADD finale devonoaspettare.Le immaginiche seguono mostrano ci che accade nelle stazioni di prenotazione e nello stato del registro.

  • 7/24/2019 Calcolatori 22

    6/12

    LOAD 1 non Busy perch stata completata, la LOAD 2 e tutte le altre sono busy. La ADD3 non

    busy perch ha una coda di prenotazione con 3 stazioni per il sommatore. In realt ne abbiamo

    occupate solo 2, una per la SUB e una per la ADD, la 3 stazione disponibile. Poi abbiamo le 2

    stazioni del moltiplicatore e divisore ( hanno parte dellhardware in comuneUnico blocco che

    riesce a fare ambo le cose). Fintanto che dalla coda delle istruzioni non vieneprontaunistruzione

    che vuole fare una LOAD o ADD, restano bloccate nella coda di istruzioni. Nel campo Op abbiamo

    lindicazione delloperazione che dobbiamo fare. Vj, in questo caso, contiene qualcosa che non ha

    significato, perch? Per quanto riguarda queste operazioni di calcolo Qj diverso da 0 e mi indica

    da dove prendere loperando. Lo stesso vale per Qk. Gli unici campi pieni sono quelli che indicano

    che Vk preso dal banco dei registri o dalla memoria con loperazione della 1 LOAD. Il campo A

    mi dice qual lindirizzo dove andare a pescare la LOADIn quel particolare momento questa

    la stazione di prenotazione.

    Vediamo i registri Qi. Hanno una serie di 0, ma anche una serie di codici diversi da 0 che mi dicono

    che F0 non posso prenderlo perch sar prodotto da MULT1, F2 non lo posso prendere perch

    sar prodotto da LOAD 2, ecc.Situazione in un particolare momento.

    Passaggio Importante:Se una istruzione ha gli operandi liberi nella coda di istruzioni, la posso

    avviare?Il codice che abbiamo visto inizialmente mi d un ordine di esecuzione delle istruzioni

    ( LOAD, LOAD, MULT, SUB, DIV, ADD) In realt, questo fatto di eseguire queste cose nel seguente

    ordine garantito dal fatto che queste istruzioni sono entrare nella coda delle istruzioniUnica

    struttura di tipo FIFO. Poi le stazioni di prenotazione non sono di tipo FIFO, appena una ha i 2

    operandi sorgente vado in esecuzione. Non faccio casini perch nel momento in cui emessa

    unistruzione( supponiamo la 1 LOAD), questa va subito a marcare F6, il Q di F6 viene marcato.

    Se eseguo unaltra istruzione che vuole usare F6 e magari trova tutto libero, quellistruzione non

    partir perch F6 non disponibile. E il modo in cui queste istruzioni che sono state emesse e

    hanno marcato il territorio sullo stato dei registri che impedir che la ADD venga eseguita prima

    della DIV. Ci non succeder mai, o se verr eseguita e scrive F6, la DIV F6 non lo andr a

    leggere da F6 ma lo andr a leggere dal common data BUS. Nel momento in cui viene emessa

    unistruzione, nellordine logico con cui le istruzioni devono essere eseguite, queste vanno amarcare cosa stanno producendo e anche il Qj e Qk da dove arriva il dato. Quindi vediamo cosa

    succede attraverso la seguente immagine:

  • 7/24/2019 Calcolatori 22

    7/12

    Mander in esecuzione la ADD prima della DIV. Non ho un problema, perch? LADD, quando

    stata mandata in esecuzione, aveva disponibili F8 (prelevato dal common data BUS prodotto dalla

    SUB) e F2 ( preso dal common data BUS della LOAD), la DIV sta aspettando F0 dalla MULT. In unparticolare momento abbiamo: completato la LOAD, scritto F2 quindi la MULT, che voleva F4 e F2,

    stata avviata. Non ancora completata perch richiede qualche colpo di clock. La SUB che

    voleva F2 e F6 stata avviata contemporaneamente. F6 serve alla SUB e DIV ed disponibile

    perch completata dalla 1 LOAD. La MULT F4 lo ha gi preso dal banco dei registri, la SUB ha

    preso F6 sul common data BUS. Subito dopo la 1 LOAD viene completata anche la 2 LOAD, F2

    arriva sul common data BUS e viene prelevato dalla MULT, SUB e ADD. Contemporaneamente,

    nello stesso istante, sia la MULT che la SUB hanno entrambi i 2 operandi. Perch entrambi

    contemporaneamente? Entrambi avevano gi F4 e F6 e quando arriva F2 sul common data BUS

    diventano operativi, per la SUB pi corta come latenza ed gi terminata. La MULT non

    ancora terminata. Nel frattempo termina la SUB e produce F8. La ADD, che aveva preso F2 dal

    common data BUS, prende anche F8 dal common data BUS, viene eseguita e completata.Chi

    rimasta?La DIV che sta aspettando F0, non neanche in esecuzione, la MULT che in

    esecuzione non ancora terminata. Quando terminer metter F0 sul common data BUS e cosi

    finalmente la DIV, che aveva gi prelevato F6, ricever F0 e tra un tot di colpi di clock terminer. E

    bene notare che il programma stato eseguito in maniera disordinata, ma senza la presenza di

    conflitti di dati, proprio perch se ci fossero stati, unistruzione avrebbe trovato nel suo campo Qj o

    Qk: Il risultato lo devi aspettare da quellunit funzionaleNon sarebbe partita.

    ( Al di fuori della tabella sopra) Supponiamo unistruzione generica che vuole produrre F8, unaltra

    che vuole usare F8 e poi c unistruzione generica che produce F8. Queste sono emesse in

    questordine: quando la 1 viene emessa, in Q8 viene scritto A; viene emessa quella che vuole

    usare F8, vado a leggere e trovo A e scrivo nella mia Q, A. Poi viene messa quella che produce F8

    e allora scrivo C. Se arriva unaltra istruzione che vuole usare F8 trova scritto C. La chiave nel

    fatto che lemissione avviene FIFO e quando una emessa vedo quello che sar, come se tutto

    quello che stato prima di me stato completato. Se stato completato trover 0 e lo andr a

    prendere, se non stato completato trovo scritto chi mi deve produrre quel dato e lo aspetto.

  • 7/24/2019 Calcolatori 22

    8/12

    Qui non abbiamo una serie di busy, tutte le unit che hanno completato il loro lavoro, marcando

    busy = no, indicano il fatto che se vuole arrivare una LOAD dalla coda delle istruzioni c una

    casella ( in questo caso 2) liberi nella stazione di prenotazione della memoria. Se voglio usare

    operazioni di somma e sottrazione ho 3 caselle libere. Ho problemi, ovviamente, nella coda di

    prenotazione della MULT per moltiplicazioni e divisioni ma tra un attimo la moltiplicazione finir e si

    liberer quel busy. E infatti nella tabella sotto, sugli stati, F0 e F10 sono quelli che mancano diversi

    da 0. Se ora viene emessa unistruzione che vuole usare F10, lei nel suo Qk copier questo

    valore. Se unistruzione vuole usare F6, copier 0 in Qk e prelever dal banco dei registri F6.

    Vediamo adesso il caso di un loop:

    L.D F0, 0(R1)

    MUL.D F4, F0 F2

    S.D F4, 0(R1)

    DADDIU R1, R1, -8

    BNE R1 R2 Loop; salta se R1 diverso da R2

    Essendo un ciclo abbiamo una serie di istruzioni che usano glistessi registri.

    Prima per, vediamo una tabella che riassume un po quello che ci siamo detti sino ad ora:

  • 7/24/2019 Calcolatori 22

    9/12

    La tabella divisa a seconda delloperazione che dobbiamo fare.

    Voglio emettere unistruzione fin quando non trovo vuota una stazione di riservazione. Non

    potendola emettere, metto in stallo la coda delle istruzioni. Quando una stazione di prenotazione si

    libera, la emetto e faccio ci che si vede in alto a destra della tabella.

    Abbiamo per quellistruzione un rs e un rt. Si va nello stato dei registri, si vede se lo stato dei

    registri del particolare registro rs, vuole usare F8 e vedo se Qi di questo F8 diverso da 0. Se

    diverso da 0, qualcuno sta producendo quellinput, vado nella RS, vado al campo Qj e scrivo ci

    che trovo scritto.Quel Qi diverso da 0, vale 5?Scrivo 5 a significare che Qj vale 5Formalismo

    per descrivere ci che abbiamo detto. Altrimenti se Qi 0, loperando disponibile. Vado in Vj e

    prendo il contenuto del banco dei registri, stiamo parlando di F8? Vado al banco dei registri F8 e lometto in Vj ma metto 0 nel mio Qj. Stesso procedimento per il 2 registro sorgente rt, questa volta

    con Qk e Vk.Ho impegnato la stazione di riservazione?In busy devo mettere busy yes e devo

    anche fare unaltra cosafondamentale: venire nel registro stato a marcare il mio registro

    destinazione. Questo ci che faccio nel momento in cui ho emesso unistruzione fp.

    Cosa succede se devo fare una LOAD o STORE?Devo avere il buffer vuoto. Voglio fare, per

    esempio, la LOAD di F8; devo verificare se F8 diverso 0, o meglio se F8 libero. Se F8 libero,

    Qi diverso da 0, prender dal banco dei registri F8 e lo metter in Vj. Se devo fare una STORE

    devo verificare che il mio sorgente, che devo scrivere in memoria, sia disponibile. Se lo significa

    che Qi uguale a 0 e quindi else prendo rt e lo metto in Vk. Altrimenti se diverso da 0, devomettere in Vk chi mi sta producendo il dato. Se devo fare una LOAD, loperazione pi semplice

  • 7/24/2019 Calcolatori 22

    10/12

    perch devo andare nel registro di stato e dire: Sto facendo la LOAD di F8, in F8 scriver r in

    maniera tale che chi vuole usare F8, quando viene qua, legge la LOAD1 che lo vuole produrre.

    Nella fase di esecuzione abbiamo da attendere che entrambi gli operandi siano disponibili.

    Sostanzialmente sia Qj che Qk, in AND, devono essere uguali a 0. Quando lo sono, eseguo il

    calcolo usando gli operandi Vj e Vk. Se Qj= 0 ed allinizio della coda di LOAD STORE, il registro

    sorgente, con cui vado a calcolare lindirizzo, mi calcolo limmediato pi sorgente per ottenerelindirizzo. Dopo aver calcolato lindirizzo, vado in memoria a fare la lettura e prendendo il campo A

    della stazione di riservazione. Questo per quanto riguarda lesecuzione.

    Se sto facendo la fase di scrittura, ho completato la mia operazione e bisogna prendere il dato che

    va sul common data BUS. Nel momento in cui un dato viaggia sul common data BUS, ciascuna

    istruzione, che nella stazione di riservazione X, si chiede se la stazione r, che ha completato,

    coincide col proprio Qi. Se c una particolare istruzione che tiene Qi = LOAD2 e sta arrivando sul

    common data BUS qualcosa prodotto da LOAD2, si prende il risultato e si mette nel banco dei

    registri. Il risultato fa si che Qi venga messo = 0 e lo stesso lo faccio per Qj. Avendo completato

    vado a scrivere no sul busy. Per lo STORE Vk va in memoria allindirizzo A e vado a mettere il busy

    uguale a no.

    Ritorniamo al loop, cosa fa?

    Carica un vettore che caricato in memoria a partire da un certo numero, 0 + IMM R1. R1 stato

    inizializzato a puntare allultimo elemento di questo vettore ( meccanismo visto ieri per gestire i

    vettori in modo tale da avere un puntatore che quando arriva a 0 esco dal loop). Supponiamo che

    R1 valga 800, carico F0. F2 un valore precaricato e faccio F0*F2 e calcolo F4. Vado nello stesso

    indirizzo dove avevo caricato il dato e scrivo F4. Decremento R1, se R1 non uguale a R2 salto al

    loop. Quando combaciano non salter pi. Il programma sta leggendo il vettore in memoria e lo sta

    moltiplicando per lo scalare F2 per poi aggiornare il vettore. Vediamo come avviene questa

    esecuzione.

    Stessa tabella di prima, dove per viene aggiunta una colonna che ci chiarisce listruzione di che

    iterazione . Abbiamo una situazione in cui, in un particolare momento, la LOAD stata emessa

    ed eseguita. Non stata ancora completataF0 non ancora stato letto. La MULT che vuole

    usare F0 non pu essere in esecuzione, stata solo emessa. La STORE che vuole usare F4

    stata solo emessa. La cosa strana che nel frattempo stata avviata laltra LOAD ed avviata in

    esecuzione. Succeder che, questa LOAD, produrr F0 cos come anche laltra LOAD produrr F0.

    Attenzione per che lF0 della 2 LOAD non lF0 che deve essere usato dalle prime 2 istruzioni.

    Infatti nella stazione di prenotazione( che possiamo vedere nellimmagine sotto), queste 2 istruzionihanno come Qj non F0, perch altrimenti quando viene prodotto il 1 F0 entrambe non possono

    partire, ma hanno scritto qual la stazione di prenotazione che produce quel dato. Quindi la 1

  • 7/24/2019 Calcolatori 22

    11/12

    MULT del primo ciclo ha scritto che Qj che produrr F0 LOAD1 e la MULT del secondo ciclo ha

    scritto che il mio F0 LOAD2. Quindi, quando la LOAD1 si completer, anche se il dato andr in

    F0, la MULT non se lo prender dal common data BUS perch su quel common data BUS c

    scritto che quellF0 proviene da LOAD1Solo chi lo sta aspettando da LOAD1 lo pu prendere.

    Nel momento in cui ho eseguito la LOAD, Q0 dello stato dei registri, tiene LOAD2, perch?Se

    viene messa una nuova istruzione che vuole F0, leggendo LOAD2 scriver nel suo Qj: Staiaspettando qualcosa che viene da LOAD2, e la prossima istruzione che entrer dalla coda delle

    istruzioni sar una LOAD. Una nuova LOAD potr essere emessa quando verr a liberarsi una

    nuova stazione di LOAD.

    Per ora le 2 stazioni di LOAD sono impegnate, infatti nella stazione vediamo busy yes a entrambe;

    fra un po, che si completer LOAD1, busy sar no e la prossima LOAD, del terzo ciclo, potr

    essere emessa e ,mettendo la 3 LOAD, verr scritto in F0 dello stato dei registri LOAD3. Tutte le

    istruzioni che verranno emesse dopo, se richiedono F0, dovranno prendere questo F0.

    Accenniamo quello che avviene nel momento in cui abbiamo la gestione col buffer di riordino,

    situazione in cui i risultati vengono gestiti in maniera speculativa.

    (Strategia per gestire la coda di istruzioni in maniera non FIFO: cerca)

    Eseguo delle istruzioni che sono eseguite anche in maniera speculativa.Ovvero?Per esempio, se

    sto facendo un salto, non ho verificato una condizione di salto perchbasata su un registro float

    che devo ancora calcolare. Allora posso ipotizzare che il salto si verifichi (o no) e eseguo le

    istruzioni . Le istruzioni eseguite, producono dei risultati, che non vanno nel banco dei registri

    Non c' neanche un buffer di STORE dove, dal banco dei registri, i dati vengono presi per essere

    scritti in memoria, ma i risultati delle operazioni vengono sistemati nel buffer di riordino e, questo

    buffer, attende fintanto che non avviene la validazione dell'istruzione. Solo quando listruzione

    effettivamente confermata, perch valuto la condizione, allora vado sia nel banco dei registri, sianella memoria. Solo se un dato deve andarsi a scrivereeffettivamente,perch la mia

  • 7/24/2019 Calcolatori 22

    12/12

    speculazione stata confermata, posso andarlo a mettere in memoria. Il buffer funge, in un certo

    senso, da anticamera sia per la scrittura dei registri che per la scrittura in memoria.

    Vediamo delle architetture di rango superiore. L'obiettivo aumentare le prestazioni e questa

    cosa parte dall'idea che fino ad ora siamo stati limitati da 1 condizione: il fatto che in ogni colpo diclock, venisse prelevata dalla memoria una sola istruzione. Tutto quello che abbiamo visto, ha

    previsto che in un colpo di clock prelevo unistruzione, faccio il fetch, poi il decode e via dicendo.

    Poi eravamo stati bravi da gestire il fatto che, se anche listruzione non era completata, posso

    avviare unaltra istruzione se quelle precedenti non sono completate. Ci siamo messi in una

    condizione in cui, nella migliore delle ipotesi, siamo eseguendo un'istruzione per colpo di clock.

    Abbiamo un CPI ideale di 1 ( Clock Per Istruzione)Il programma non potr essere completato in

    meno di un colpo di clock per istruzionee raggiunger il CPI=1 solo se non ho beccato alcuno

    stallo. Il prossimo step: come posso fare a diminuire quel CPI?Voglio impiegare meno di un

    colpo di clock per istruzione. Ho una serie di possibilit; il bottle neck che se voglio eseguire pi

    di un'istruzione nel colpo di clock, devo avere l'hardware per fare questo ma anche necessito di

    prelevare l'istruzione e quindi praticamente, per migliorare la prestazione, devo prelevare pi

    istruzioni per colpo di clock. Se riesco a fare ci, devo pensare a come gestire queste istruzioni e

    posso iniziare a pensare se, effettivamente, possibile diminuire questo CPI. Laltra opzione ,

    cambiare mentalit, e pensare a unistruzione che continua a prelevarne una per colpo di clock ma

    al suo interno codifichi il lavoro che in una programmazione standard era richiesto in una sola

    istruzione. Se quando vado in memoria a prelevare unistruzione e trovo una MULT, la eseguo e poi

    prelever unaltra istruzione e via dicendo,c un modo per prelevare unistruzione sola dalla

    memoria per colpo di clock ma accelerare le cose?Si, se listruzione che prelevo mi spiega un

    compito che sino a oggi vedevo spiegato in una serie di istruzioni. Questo lapproccio deiprocessori vettoriali: con un'istruzione codifico un task che, altrimenti, veniva codificato con tante

    istruzioni, pur continuando a prelevare un istruzione per colpo di clock, miglioro le prestazioni.

    L'altro approccio: miglioriamo le prestazioni prelevando pi istruzioni per colpo di clock.