TAMPEREEN TEKNILLINEN YLIOPISTO Digitaali- ja tietokonetekniikan laitos TKT-3200 Tietokonetekniikka I Harjoitustyö 2: DLX I - arkkitehtuuri.. 2010 Ryhmä Nimi Op.num.
Yleistä harjoitustyöstä Tämän työn tarkoituksena on auttaa ymmärtämään kuinka liukuhihnoitettu prosessori toimii ja mitkä tekijät vaikuttavat sen suorituskykyyn. Työssä käytetään DLX-prosessorin liukuhihnoitetun version simulaattoria. DLX-simulaattori on tehty Ruotsissa Lundin yliopistossa. Harjoitustyöstä palautetaan tämä dokumentti täydennettynä. Vastauksina kysymyksiin riittävät lyhyet mutta kuitenkin tarkat vastaukset. Vastaukset kirjoitetaan siististi lyijykynällä, jotta virheitä voi korjata. Suttuiset, hutaistut tai muulla tavoin epämääräiset palautukset johtavat bumerangiin tai harjoituksen kokonaan uudelleen tekemiseen. DLX-simulaattori Tässä harjoitustyössä tulemme opiskelemaan DLX-prosessorin datapolkumallia (data path model). Rakennamme kolmea mallia käyttäen astettain täydellisen datapolkumallin, joka tehokkaasti ratkaisee kiistatilanteita (hazard). Ensimmäisestä mallista, Datapath Model 1 (DP-1), puuttuu tuki bypasstekniikalle. Toinen malli, Datapath model 2 (DP-2), tukee bypass-tekniikkaa, mutta käyttää ALUa hyppyosoitteiden laskemiseen. Kolmas malli, DLX, käyttää hyppyosoitteiden laskemiseen erityistä summainta. Simulaattori tukee ainoastaan kokonaislukukäskyjä. DLX-KONTROLLI-harjoitustyössä tutkitaan ohjauslogiikan toteuttamista DLX-mallille. Simulaattori lukee symbolista konekieltä, joka on kirjoitettu DLX-prosessorille. Assembler-ohjelman voi kirjoittaa tavallisella tekstieditorilla, tekstitiedoston pääte pitää olla '.s'. Viimeisen käskyn pitää olla trap 0. Asennus Siirry kotihakemistoosi Lintulassa. Kopioi simulaattori ja kooditiedostot itsellesi kurssin kotisivuilta (varmista ensin, että sinulla on quotaa jäljellä ainakin noin 1.1 MB). Pura paketti haluamaasi hakemistoon. Nyt sinulla on kaikki tämän ja DLX-KONTROLLI -työn tekemiseen tarvittavat tiedostot alihakemistossa DLX. Siirry tähän hakemistoon (cd DLX). Simulaattorin käynnistys Simulaattori käynnistetään seuraavasti sparc_pipe (tai./sparc_pipe jos sinulla ei ole nykyistä hakemistoa polkumäärittelyssä) Voit tehdä tämän myös etänä SSH:n yli miltä tahansa koneelta josta löytyy X ikkunointi. 1/16
Ruutuun ilmestyy seuraava ikkuna: Ikkunassa näkyvät viisi suorittimen osavaihetta ovat vasemmalta lueteltuna: IF (Instruction Fetch), ID (Instruction Decode), EX (Execute), MEM (Memory Access) ja WB (Write Back to Register File). Prosessori liukuhihnoitetaan laittamalla osavaihden väliin D-kiikut (rekisterit), joihin osavaiheiden tulokset tallennetaan joka kellojaksolla. Pystysuorien katkoviivojen päällä olevat laatikot ovat D- kiikkuja. Katkoviivojen välissä sijaitsevat ne toiminnalliset yksiköt, jotka suorittavat laskennan kussakin osavaiheessa. Laskenta etenee takaisinkirjoituksia lukuunottamatta vasemmalta oikealle. Lihavat vaakaja pystysuorat viivat kuvaavat 32-bittisiä väyliä, jotka yhdistävät toiminnalliset yksiköt ja D-kiikut toisiinsa. Kaaviota, jossa käytetään edellä kuvailtua järjestelmän kelloon tahdistettujen muistielementtien ryhmittelyä pystysuorien viivojen päälle kutsutaan Werner-diagrammiksi. Kussakin osavaiheessa suorituksessa oleva käsky näkyy kunkin osavaiheen alareunassa olevassa laatikossa. Rekisteritiedoston sisältöä voi tutkia osoittamalla sitä hiirellä ja napauttamalla hiiren vasenta nappulaa. Rekisteritiedoston rekisterien sisältöä ei voi muuttaa manuaalisesti. Simulaattorin toiminnot Ikkunan vasemmassa yläreunassa on kaksi alasvetovalikkoa: File ja Views. Valikon File komennolla Load voidaan lukea sisään assembly-kooditiedosto ja komennolla Quit poistutaan simulaattorista. Valikosta Views valitaan käytettävä prosessorin datapolkumalli: DP_1, DP_2 tai DLX. Muut tässä valikossa olevat vaihtoehdot selviävät DLX-Kontrolli -työssä. Hazardien tutkimista varten jokaiseen datapolkumalliin liittyy kolme optiota: Pipelining/No Pipelining, Delayed Load/No Delayed Load ja Delayed Branch/No Delayed Brach. Näitä optioita voi muutella hiiren avulla ikkunan yläreunassa olevista laatikoista, mutta joissain datapolkumalleissa osa näistä optioista on kiinteitä eli niitä ei voi muuttaa. Ennen ohjelman suoritusta pitää ohjelmalaskuri ja rekisteritiedosto nollata. Tämä tapahtuu klikkaamalla kenttää Reset. Huomaa, että Reset ei nollaa datamuistia; datamuisti (sekä ohjelmalaskuri ja rekisteritiedosto) nollautuvat esim. koodin (uudelleen)latauksen yhteydessä. Ohjelmaa voidaan suorittaa kellojakso kerrallaan klikkaamalla kenttää Clock. Ohjelman koko suoritus täydellä nopeudella tapahtuu klikkaamalla kenttää Run. Elapsed Cycles on se kokonaisaika kellojaksoina, joka alkaa kun ensimmäinen käsky haetaan IF-vaiheesta ja päättyy, kun viimeinen käsky saavuttaa WB-vaiheen. Kokonaisajassa on huomioitu liukuhihnan täyttämiseen tarvittavat kellojaksot. 2/16
CPI lasketaan seuraavasti. CPI KellojaksojenMaara = --------------------------------------------------- = KaskyjenMaara( einop) KellojaksojenMaara ------------------------------------------------------------------------------------------------------------------------------------------------ KellojaksojenMaara HavaituṫHazardit LiukuhihnanTayttaminen Hazards on kellojaksojen lukumäärä, joka tarvitaan hazardien ratkaisemiseen. Summa muodostuu niistä NOP-käskyistä (saavuttavat WB-vaiheen), joita ilmenee sen jälkeen, kun ensimmäinen käsky saavuttaa WB-vaiheen sekä niistä kellojaksoista, jolloin liukuhihna on pysäytetty (stalled) hazardien vuoksi. DLX-käskyjen osaoperaatiot Tarkastele seuraavaa ohjelmaa (kaikki luvut ovat heksadesimaalilukuja): LW ADD SW R3,18(R0) R1,R3,R3 18(R0),R1 Mitä M[18+R0] sisältää ohjelman suorituksen jälkeen, jos M[18+R0] on ennen suoritusta 20 16? Nyt tutkimme mitä osaoperaatioita datapolku suorittaa eri osavaiheissa yllä olevan ohjelman käskyille ajamalla se ilman liukuhihnoitusta. Ajamalla ohjelma ilman liukuhihnoitusta voimme keskittyä yhden käskyn suoritukseen kerrallaan ja tutkia mitä eri liukuhihnan osavaiheissa tapahtuu. Ohjelmakoodi exempel1.s ladataan simulaattoriin valitsemalla valikosta File->Load. Anna tiedoston nimi ja klikkaa OK. Varmista, että asetukset ovat Datapath Model 1, No Pipelining, No Delayed Load ja No Delayed Branch. Anna kellopulssi klikkaamalla kenttää Clock. Mikä käsky noudetaan sisään? Mitä kyseinen käsky tekee? Anna kellopulssi. Täydennä taulukkoa 1 (osaoperaatioiden lyhenteet taulukossa 2). Mitä tehdään IDvaiheessa? Anna kellopulssi. Mistä ALU saa operandinsa? Mikä on ALU-operaation tulos? Mitä ALU:ssa laskettiin? Anna kellopulssi. Minkä arvon DMAR saa? Mihin DMAR-väylä on kytketty? Mikä osaoperaatio siis suoritettiin EX-vaiheessa? 3/16
Mitä rekisteri R3 sisältää (klikkaa Reg-file:ä)? Anna kellopulssi. Mitä rekisteri R3 nyt sisältää ja miksi? Käsky LW R3,18(R0) on nyt suoritettu. Täytä nyt taulukon 1 ensimmäisellä riville käskyn osaoperaatiot (lyhenteet taulukossa 2). Täytetään seuraavaksi myös loput käskyt taulukkoon. Merkitse lopuksi viimeiselle riville, mikä Werner-diagrammin toiminnallinen yksikkö (datamuisti/käskymuisti/alu/ rekisteri) on vastuussa toiminnasta kussakin osavaiheessa. Taulukko 1: Esimerkkikoodin käskyjen osaoperaatiot. Luokka IF ID EX MEM WB LOAD-käsky ALU-käsky STORE-käsky BRANCH-käsky Toiminnallinen yksikkö Taulukko 2: Lyhenteet Taulukko 1:n täydentämistä varten. Osaoperaatio Lyhenne Käskynnouto Rekisterinluku Aritmeettinen/looginen-operaatio Operandin osoitteenlaskenta Hyppyosoitteen laskenta Muistin lukeminen Muistiin kirjoitus Rekisteriin kirjoitus PC:n lataus Ei tehdä mitään - Anna kellopulssi. Käsky ADD R1,R3,R3 noudetaan nyt. Vastaa seuraaviin kysymyksiin antamalla kellopulsseja. Mitä tehdään EX-vaiheessa? Mikä osaoperaatio suoritettiin MEM-vaiheessa? IF RR AO OC JC MR MW RW LPC 4/16
Ennen kuin siirrät käskyn WB-vaiheeseen, niin tutki rekisterien R1 ja R3 sisältöä. Mitä R1 ja R3 sisältävät? R1 = R3 = Anna kellopulssi. Mitä rekisteri R1 nyt sisältää ja miksi? R1 = Täytä taulukkoon 1, mitä osaoperaatioita nyt suoritettiin. Seuraava käsky on SW 18(R0),R1. Suorita käsky antamalla tarpeeksi kellopulsseja ja vastaa seuraaviin kysymyksiin. Mitä kyseinen käsky tekee? Mitkä rekisterit luettiin ID-vaiheessa? Mitä tehtiin EX-vaiheessa? Mikä osaoperaatio tehtiin MEM-vaiheessa? Huomaa, että rekisterin R1 arvon siirtämisessä käytettiin erikoisväylää ALU:n ohitukseen. Väylässä osoite ja data kulkevat eriteltyinä. Mikä osaoperaatio tapahtuu WB-vaiheessa? Täytä käskyn osaoperaatiot taulukkoon 1. Kun ratkaistaan missä liukuhihnan osavaiheessa tietty osaoperaatio suoritetaan, ei ole merkitystä missä vastaava toiminnallinen yksikkö sijaitsee. Osavaihe, jossa osaoperaatio suoritetaan, määräytyy sen mukaan, missä käsky sijaitsee, kun osaoperaatio suoritetaan. Esimerkiksi rekisterin kirjoitus suoritetaan WB-vaiheessa vaikka rekisteritiedosto sijaitsee ID-vaiheessa. Tällä seikalla on merkitystä, kun tutkit BRANCH-käskyn osaoperaatioiden suoritusta. Lopuksi tutkimme käskyn BEQZ R0,14 osaoperaatioita. Mitä tehdään ID-vaiheessa? Mitä tehdään EX-vaiheessa? Mikä on ALU:n ulostulo? 5/16
Mikä ohjaa multiplekseria MX1? Missä tilanteissa MX1:n valintasignaali muuttaa tilaansa? Kun siirrät käskyn WB-vaiheeseen, niin PC:n arvo muuttuu. Mikä on PC:n uusi arvo? Miksi PC:n arvo muuttuu juuri täksi arvoksi? Täytä nyt taulukon 1 puuttuvat kohdat. Taulukosta 1 näemme, että osa käskyistä siirtyy aina seuraavaan osavaiheeseen jokaisella kellopulssilla, kun taas osassa käskyistä joudutaan suorittamaan osaoperaatio "ei mitään" jossain osavaiheessa. Mitkä käskyluokat ja missä osavaiheissa "ei mitään"operaatiot suoritetaan? Olemme tähän mennessä suorittaneet jokaisen käskyn yksikseen. Tärkeä suorituskyvyn mitta on kuinka monta kellojaksoa tarvitaan keskimäärin yhden käskyn suorittamiseen. CPI-luku on tämä mitta. Mikä on suoritetun ohjelman CPI-luku ja miksi? Rinnakkaisuus ja liukuhihnoitus Jotta liukuhihnoitus olisi mahdollista, jokainen käsky pitää pystyä jakamaan osaoperaatioihin ja nämä osaoperaatiot suorittamaan järjestyksessä. Käskyn ei kuitenkaan tarvitse käyttää joka osaoperaatiota. Toinen vaatimus on se, että toiminnallisia yksiköitä ja väyliä pitää olla tarpeeksi jotta kaikki liukuhihnan osavaiheet voivat suorittaa osaoperaation jokaisella kellojaksolla. Muuten liukuhihna pitää pysäyttää kunnes tarvittava toiminnallinen yksikkö/väylä vapautuu. Tällöin kyseessä on rakenteellinen hazardi (structural hazard). Merkitse taulukkoon 1 mitkä liukuhihnan osavaiheet käyttävät seuraavia toiminnallisia yksiköitä: muisti, ALU ja rekisteripankki. Miksi kaksi liukuhihnan osavaihetta voivat samanaikaisesti käyttää rekisteritiedostoa ilman että syntyy rakenteellinen hazardi? Mitkä ovat nämä osavaiheet? Jatkossa oletamme, että muisti on rakennettu niin ettei rakenteellista hazardia synny. 6/16
Tutki seuraavaa ohjelmaa: ADDI R1,R0,#1;R1 <- 1 ADDI R2,R0,#2;R2 <- 2 ADDI R3,R0,#4;R3 <- 4 ADD R1,R1,R1;R1 <- R1+R1 ADD R2,R2,R2;R2 <- R2+R2 ADD R3,R3,R3;R3 <- R3+R3 ADD R1,R1,R1;R1 <- R1+R1 ADD R2,R2,R2;R2 <- R2+R2 ADD R3,R3,R3;R3 <- R3+R3 Selvitä koodia analysoimalla mitä rekisterit R1, R2, R3 sisältävät ohjelman suorituksen jälkeen? Anna vastaus heksadesimaaleina. R1 = R2 = R3 = Ohjelma on tiedostossa exempel2.s. Lataa se simulaattoriin ja aja ohjelma (Run). Kuinka monta kellojaksoa ohjelman suoritus kestää, kun vain yhtä käskyä suoritetaan kerrallaan? (DP_1, No pipelining) Laita nyt liukuhihnoitus päälle (Pipelining) jolloin prosessori nollautuu. Anna kellopulsseja kunnes ensimmäinen käsky saapuu MEM-vaiheeseen. Kuinka monta kellojaksoa siihen kuluu? Tämän jälkeen jokaisella kellojaksolla valmistuu yksi käsky. Sanomme että nyt liukuhihna on täynnä. Anna kellopulssi. Mitä rekisteriä päivitetään ja mitä rekistereitä luetaan? Kuinka montaa käskyä suoritetaan samanaikaisesti liukuhihnalla? Anna kellopulsseja, kunnes viimeinen käsky on WB-vaiheessa. Mitä sisältävät rekisteri R1,R2 ja R3? R1 = R2 = R3 = Kuinka monta kellojaksoa kesti ohjelman suoritus? Jos jätetään huomioimatta liukuhihnan täyttämiseen tarvittavat kellojaksot, niin kuinka paljon nopeampi on ohjelman suoritus käytettäessä liukuhihnoitusta? Merkitse ao. tilaan myös kaava jolla sait tuloksesi. Tästä voimme vetää johtopäätöksen, että liukuhihnoitus nopeuttaa huomattavasti laskentaa, jos rakenteellisia hazardeja ei esiinny. Käytännössä kuitenkin esiintyy ongelmia jotka pienentävät nopeutusta. Seuraavaksi tutkitaan mitä nämä ongelmat ovat. 7/16
Datahazardit Seuraavaksi selvitetään millaisia erikoismekanismeja vaaditaan, jotta ohjelman suoritus tuottaisi oikeita tuloksia huolimatta datariippuvuudesta käskyjen välillä. Bypassing Tutki seuraavaa ohjelmaa: ADDI R1,R0,#2;R1 <- 2 ADD R2,R1,R1;R2 <- R1+R1 ADD R3,R1,R1;R3 <- R1+R1 ADD R4,R1,R1;R4 <- R1+R1 Mitä rekisterien R1, R2, R3 ja R4 pitäisi sisältää ohjelman suorituksen jälkeen? R1 = R2 = R3 = R4 = Ohjelma on tiedostossa exempel3.s. Lataa se ja aja ohjelma (Run). (DP_1, Pipelining) Mitä rekisterit R1, R2, R3 ja R4 sisältävät ohjelman suorituksen jälkeen? R1 = R2 = R3 = R4 = Jotain meni ilmeisesti pieleen. Jotta ymmärtäisimme mikä, ajetaan ohjelma uudestaa. Nollaa prosessori, ja anna kellopulsseja, kunnes käsky ADD R2,R1,R1 saavuttaa ID-vaiheen. Mikä on rekisterin R1 arvo luettaessa? R1 = Missä datapolulla on rekisterin R1 oikea arvo? Anna kellopulsseja, kunnes käsky ADD R3,R1,R1 saavuttaa ID-vaiheen. Mikä on rekisterin R1 arvo luettaessa? R1 = Missä datapolulla on rekisterin R1 oikea arvo? Anna kellopulsseja, kunnes käsky ADD R4,R1,R1 saavuttaa ID-vaiheen. Mikä on rekisterin R1 arvo luettaessa? Onko arvo oikea? R1 = Nyt olet (toivottavasti) oivaltanut, että rekisteritiedosto ei aina sisällä oikeita arvoja. Olet huomannut, että on oltava mahdollista lähettää lasketun käskyn tulos kahdelle seuraavalle käskylle, jos ne käyttävät niitä edeltävän käskyn tulosta. 8/16
Laskettu rekisterin arvo täytyy pystyä lähettämään takaisin seuraaville käskyille. Mistä liukuhihnan kohdasta/kohdista arvo pitää pystyä takaisinkytkemään? Seuraava datapolkumalli, Datapath Model 2 (DP_2) tukee Bypassing-tekniikkaa. Valitse alasvetovalikosta View datapolkumalli DP_2 (jolloin prosessori nollautuu). Anna kellopulsseja kunnes käsky ADD R2,R1,R1 saavuttaa ID-vaiheen. Tutki multipleksereiden MX2 ja MX3 tilaa. Mistä haetaan R1? Anna kellopulsseja, kunnes käsky ADD R3,R1,R1 saavuttaa ID-vaiheen. Tutki multipleksereiden MX2 ja MX3 tilaa jälleen. Mistä haetaan R1? Anna kellopulsseja, kunnes ohjelma on suoritettu ja varmista, että rekistereiden arvo nyt oikea. Delayed Load Tutki seuraavaa ohjelmaa: LW ADD ADD ADD R1,18(R0);R1 <- M[18] R2,R1,R1;R2 <- R1+R1 R3,R1,R1;R3 <- R1+R1 R4,R1,R1;R4 <- R1+R1 Mitä rekistereiden R1, R2, R3 ja R4 pitäisi sisältää ohjelman suorituksen jälkeen, jos M[18] = 20 16 ennen suoritusta. R1 = R2 = R3 = R4 = Ohjelma on tiedostossa exempel4.s. Lataa se ja aja ohjelma (klikkaa Run) (DP_2, Pipelining). Mitä rekisterit R1, R2, R3 ja R4 sisältävät ohjelman suorituksen jälkeen? R1 = R2 = R3 = R4 = Jotain meni ilmeisesti pieleen. Jotta ymmärtäisimme jälleen mikä meni pieleen, niin ajetaan ohjelma uudestaa. Nollaa prosessori ja anna kellopulsseja kunnes käsky ADD R2,R1,R1 saavuttaa ID-vaiheen. Missä osavaiheessa käsky LW R1,18(R0) sijaitsee? Anna kellopulssi. Missä datapolulla on rekisterin R1 oikea arvo? Missä osavaiheessa käsky ADD R2,R1,R1 sijaitsee? 9/16
Miksi käsky ADD R3,R1,R1 saa oikean rekisterin arvon? Yhden käskyn suoritus epäonnistui. Mikä käsky se oli ja miksi juuri tämän kyseisen käskyn suoritus epäonnistui? Ongelma ratkaistaan käyttämällä viivästettyä latausta (Delayed Load). Aina kun käskyluokkaan LOAD kuuluvan käskyn tulosta käytetään seuraavassa käskyssä, liukuhihna pysäytetään, kunnes voidaan käyttää Bypassing-tekniikkaa välittämään latauksen tulos seuraavalle käskylle. Aktivoi Delayed Load klikkaamalla kenttää No Delayed Load. (DP_2, Pipelining, Delayed Load, Delayed Branch) Anna kellopulsseja, kunnes käsky ADD R2,R1,R1 saavuttaa ID-vaiheen. Missä osavaiheessa käsky LW R1,18(R0) sijaitsee? Anna kellopulssi. Missä osavaiheessa käsky ADD R2,R1,R1 nyt sijaitsee? Liukuhihna pysäytetään (STALL) siten, että ID-vaiheessa oleva käsky ja sitä edeltävät käskyt eivät etene liukuhihnassa. Mistä rekisterin R1 arvo nyt haetaan? Suorita ohjelma loppuun komennolla Run, ja varmista että rekisterien arvot ovat nyt oikeat. Kuinka monta kellojaksoa ohjelman suoritus kesti? Kuinka monta kellojaksoa ohjelman suoritus pitäisi kestää, jos datariippuvuutta LOAD-käskyn ja ensimmäisen ADD-käskyn välillä ei esiintyisi? Delayed Load ja Bypassing yhdessä takaavat, että voimme eliminoida kaikki datahazardit. Menetämme kuitenkin yhden kellojakson, jos datariippuvuus LOAD-käskyn ja sitä seuraavan käskyn välillä esiintyy. 10/16
Kontrollihazardit Tutki seuraavaa ohjelmaa (vasemmassa reunassa ovat käskyjen muistiosoitteet) 0000 ADDI R1,R0,#9;R1 <- 9 0004 ADD R2,R0,R0;R2 <- 0 0008 ADD R3,R0,R0;R3 <- 0 000C ADD R4,R0,R0;R4 <- 0 0010 ADD R5,R0,R0;R5 <- 0 0014 LOOP: ADDI R2,R2,#1;R2 <- R2+1 0018 SUBI R1,R1,#1;R1 <- R1-1 001C BNEZ R1,LOOP;If R1 <> 0 then BRANCH to LOOP 0020 ADD R3,R3,R2;R3 <- R3+R2 0024 ADD R4,R4,R2;R4 <- R4+R2 0028 ADD R5,R5,R2;R5 <- R5+R2 Mitä rekisterien R1, R2, R3, R4 ja R5 pitäisi sisältää ohjelman suorituksen jälkeen? R1 = R2 = R3 = R4 = R5 = Mitä rekisterien R3, R4 ja R5 pitäisi sisältää juuri ennen käskyn ADD R3,R3,R2 suorittamista? R3 = R4 = R5 = Kuinka monta käskyä suoritetaan? Ohjelma on tiedostossa exempel5.s. Lataa se ja aja ohjelma (klikkaa Run). (DP_2, Pipelining, Delayed Load, Delayed Branch) Mitä rekisterit R1, R2, R3, R4 ja R5 sisältävät ohjelman suorituksen jälkeen? R1 = R2 = R3 = R4 = R5 = Nollaa prosessori ja anna kellopulsseja kunnes käsky BNEZ R1,LOOP saavuttaa ID-vaiheen ensimmäisen kerran. Anna kellopulssi. Mikä käsky luetaan sisään? Anna kellopulssi. Mikä käsky nyt luetaan sisään? Mikä on ohjelmalaskurin arvo? PC = Anna kellopulssi. Mikä mikä on ohjelmalaskurin arvo ja käsky nyt luetaan sisään? PC = 11/16
Anna kellopulssi. Mikä on rekisterin R3 arvo, ja miksi se on väärin? R3 = Kun hyppykäsky on saapunut ID-vaiheeseen, kuinka monta kellojaksoa kestää kunnes ohjelmalaskuriin ladataan kyseisen hyppykäskyn määräämä osoite? Prosessorimme ei toimi oikein. Ongelmana on se, että ohjelmalaskuria ei ladata hyppyosoitteella heti, vaan suoritetaan joitakin hyppykäskyn jälkeisiä käskyjä riippumatta hyppyehdon toteutumisesta. Yksinkertainen ratkaisu on pysäyttää liukuhihna, kun hyppykäsky on siirtymässä pois ID-vaiheesta, ja vasta kun hyppyosoite on laskettu ja hyppyehto tarkistettu sekä mahdollisesti ohjelmalaskuria muutettu, jatketaan käskyjen suoritusta ohjelmalaskurin osoittamasta käskystä. Tämä toiminta saadaan aikaan optiolla (No Delayed Branch), jota tutkimme seuraavaksi. Muuta asetukset seuraavaksi (DP_2, Pipelining, Delayed Load, No Delayed Branch). Anna kellopulsseja, kunnes käsky BNEZ R1,LOOP saavuttaa ID-vaiheen ensimmäisen kerran. Anna kellopulssi. Mikä käsky luetaan sisään? Käskyjen noutaminen on ilmeisesti keskeytynyt. Kuinka monen kellojakson päästä käskyjä aletaan uudestaan noutamaan? Suorita ohjelma loppuun, ja varmista ovatko rekisterien arvot oikeat. Kuinka monta kellojaksoa kestää ohjelman suoritus? Miksi kellojaksojen määrä eroaa suuresti suoritettujen käskyjen määrästä? Nyt prosessorimme toimii hyppykäskyjen kanssa, mutta seurauksena tästä on huomattava suorituskyvyn lasku. Käytännössä prosessori viettää suuren osan ajastaan ohjelmien loopeissa, ja koska loopit ovat pääsääntöisesti lyhyitä, ratkaisumme ei ole hyväksyttävissä. Hyppyosoitteen laskennan aikaistaminen Ongelmana on se, että hyppyehdot ja hyppyosoite lasketaan EX-vaiheessa ja tulos on saatavilla vasta MEM-vaiheen aikana. Jos laskentaa voitaisiin aikaistaa, suorituskyvyn lasku olisi pienenpi. Aikaisin osavaihe jossa tiedämme käskyn olevan hyppykäsky on ID-vaihe. Hyppyehdon ja hyppyosoitteen laskenta on mahdollista suorittaa näinollen ID-vaiheessa kuten datapolkumallissa DLX on tehty. 12/16
Valitse datapolkumalli DLX (DLX, Pipelining, Delayed Load, No Delayed Branch). Voit nyt halutessasi toistaa exempel5 suorituksen ja katsoa mitä tapahtuu. Vertaile ainakin suoritusaikaa ja CPI lukua. Delayed Branch Mitä tarkoitetaan delayed branch-tekniikalla? Mieti asiaa sekä ohjelmoijan/kääntäjän että laitteiston kannalta. Tutki seuraavaa ohjelmaa: ADDI R2,R0,#200 ;R2 <- 200 LOOP: LW R3,28(R2) ;R3 <- M[28+R2] SUBI R2,R2,#4 ;R2 <- R2-4 BNEZ R2,LOOP ;if R2<>0 then BRANCH to LOOP ADD R1,R3,R1 ;R1 <- R3+R1 Tässä on sijoitettu ADD R1,R3,R1 käsky hyppykäskyn perään. Delayed Branchia käytettäessä ADDkäsky suoritetaan aina ennen itse varsinaista hyppyä. Näin voidaan käyttää delay slot hyödyksi eikä liukuhihnaa tarvitse pysäyttää. Kääntäjä usein siirtää jonkin hyödyllisen käskyn hyppykäskyn perään. Kääntäjä ei aina kuitenkaan onnistu sijoittamaan hyödyllistä käskyä hyppykäskyn perään. Silloin kääntäjä käyttää käskyä, joka eivät häiritse laskentaa. Sellainen käsky on NOP (No Operation). Esimerkki tällaisesta tapauksesta on seuraavassa ohjelmassa: ADDI R2,R0,#200 ;R2 <- 200 ADD R1,R0,R0 ;R1 <- 0 LOOP: ADD R1,R1,R2 ;R1 <- R1+R2 SUBI R2,R2,#1 ;R2 <- R2-1 BNEZ R2,LOOP ;if R2<>0 then BRANCH to LOOP Tässä ohjelmassa kääntäjä ei pysty siirtämään yksinkertaisella tavalla käskyä hyppykäskyn perään koska sitä edeltävät käskyt ovar riippuvaisia toisistaan. Kääntäjän pitää käyttää NOP-käskyä. 13/16
ADDI R2,R0,#200 ;R2 <- 200 ADD R1,R0,R0 ;R1 <- 0 LOOP: ADD R1,R1,R2 ;R1 <- R1+R2 SUBI R2,R2,#1 ;R2 <- R2-1 BNEZ R2,LOOP ;if R2<>0 then BRANCH to LOOP NOP Laske CPI-luku yllä olevalle ohjelmalle. Merkitse lopputuloksen lisäksi myös kaava/funktio jolla laskit CPI-luvun. Ohjelma on tiedostossa exempel9.s. Lataa se ja aja ohjelma (klikkaa Run). (DLX, Pipelining, Delayed Load, Delayed Branch). Onko CPI-luku sama kuin laskemasi? Kehittyneillä menetelmillä voidaan eliminoida edellisen ohjelman NOP-käsky. Seuraava ohjelma suorittaa saman laskennan ilman NOP-käskyä. ADDI R2,R0,#200 ;R2 <- 200 ADD R1,R0,R0 ;R1 <- 0 ADD R1,R1,R2 ;R1 <- R1+R2 LOOP: SUBI R2,R2,#1 ;R2 <- R2-1 BNEZ R2,LOOP ;if R2<>0 then BRANCH to LOOP ADD R1,R1,R2 ;R1 <- R1+R2 SUB R1,R1,R2 ;R1 <- R1-R2 Ohjelmaan on jouduttu lisäämään kaksi käskyä, jotta laskenta tuottaisi oikean tuloksen. Merkitse kyseiset käskyt ylläolevaan koodiin. Yhteisvaikutuksena saamme CPI-luvuksi ykkösen sen kustannuksella, että ohjelman pituus kasvaa kahdella käskyllä. Kuitenkin looppia suoritetaan useimmiten yli kaksi kertaa, jolloin hyöty on suurempi kuin kustannukset. Kääntäjät eivät välttämättä osaa tehdä tämänkaltaisia kehittyneitä analyyseja. Ohjelma on tiedostossa exempel10.s. Lataa se ja aja ohjelma (klikkaa Run). (DLX, Pipelining, Delayed Load, Delayed Branch). Mikä on CPI-luku nyt? Vertaa CPI-lukua ja ohjelman suoritusaikaa edellisen ohjelman (exempel9.s) vastaviin arvoihin. 14/16
Tutki seuraavaa ohjelmaa: ADDI R1,R0,#16 ;R1 <- 16 ADDUI R2,R0,#4777 ;R2 <- 4777 ADDUI R3,R0,#1326 ;R3 <- 1326 ADDI R5,R0,#0 ;R5 <- 0 ADDUI R6,R0,#32768 ;R6 <- 32768 = 8000 16 FRANK: AND R4,R2,R6 ;R4 <- R2 AND R6 SLLI R2,R2,#1 ;R2 <- R2<<1 SLLI R5,R5,#1 ;R5 <- R5<<1 SUBI R1,R1,#1 ;R1 <- R1-1 BNEZ R4,ZED ;if R4<>0 then BRANCH to ZED BNEZ R1,FRANK ;if R1<>0 then BRANCH to FRANK J END ;BRANCH to END ZED: ADD R5,R5,R3 ;R5 <- R5+R3 BNEZ R1,FRANK ;if R1<>0 then BRANCH to FRANK END: TRAP 0 ;end program Mitä tämä ohjelma tekee? Jos vastauksesi ei helposti mahdu yhdelle riville, se on väärin. Ohjelman suoritusaika riippuu R2:n alkuarvosta (esimerkkikoodissa 4777). Millä R2:n arvolla ohjelman suoritus kestää pisimmän ja millä lyhimmän ajan? Max: R2 = 16 = 10 Min: R2 = 16 = 10 Ohjelma on tiedostossa zorbas1.s. Lataa se ja aja ohjelma (klikkaa Run). (DLX, Pipelining, Delayed Load, No Delayed Branch). Kirjoita simulaattorin antamat tulokset seuraavalle riville. Elapsed Cycles = CPI = Hazards = R5 = 16 Muokkaa ohjelmaa siten että kontrollihazardeista päästään eroon. Myös suoritusajan ja CPI-luvun täytyy parantua. Ota käyttöön viivästetty hyppy (Delayed Branch). Voit vaihtaa käskyjen järjestystä ja lisätä/poistaa käskyjä. NOP-käskyä ja sen korvikkeita eli esim. kirjoitusta rekisteriin jota ei koskaan lueta/tarvita ei saa käyttää. Ohjelman toimivuuden voi tarkastaa vertaamalla R5:n loppuarvoa esimerkkikoodin (zorbas1.s) tuottamaan arvoon. Muiden rekisterien loppuarvoilla ei ole niinkään väliä. 15/16
Kirjoita muokkaamasi koodin simulointitulokset seuraavalle riville. Elapsed Cycles = CPI = Hazards = R5 = 16 Kirjoita ohjelmakoodisi seuraaville riveille. Looppeja edeltäviä käskyjä ei tarvitse kirjoittaa sikäli kun niitä ei ole muutettu. 16/16