Käskyjen putkitus: mikä on komentoputki ja miten se toimii
Käskyjen putkitus on tekniikka, jota käytetään nykyaikaisten mikroprosessoreiden, mikrokontrollerien ja suorittimien suunnittelussa niiden käskykapasiteetin (aikayksikössä suoritettavien ohjeiden määrä) lisäämiseksi. Putkitus kasvattaa läpimenoa ottamalla useita käskyjä samanaikaisesti eri käsittelyvaiheisiin siten, että jokainen vaihe tekee oman osansa ja välittää tuloksen seuraavalle.
Perusajatuksena on jakaa (ns. jakaa) suorittimen käskyn käsittely käskyn mikrokoodin määrittelemänä sarjaksi itsenäisiä mikrooperaatioiden vaiheita (joita kutsutaan myös "mikroohjeiksi", "mikro-opiksi" tai "µopiksi"), ja kunkin vaiheen lopussa on varastointi. Näin suorittimen ohjauslogiikka voi käsitellä ohjeita hitaimman vaiheen käsittelynopeudella, joka on paljon nopeampi kuin aika, joka tarvitaan käskyn käsittelyyn yksittäisenä vaiheena. Huomaa, että kaikki arkkitehtuurit eivät käytä mikrokoodia; monissa RISC-toteutuksissa vaiheet ovat kiinteästi johdettuja, kun taas monissa CISC-toteutuksissa käskyt muunnetaan sisäisiksi µopeiksi.
Termi "putki" viittaa siihen, että jokainen askel sisältää yhden mikroinstruktion (kuten vesipisara) ja jokainen askel on yhteydessä toiseen askeleeseen (analogia; kuten vesiputket). Kun putki on “täynnä”, jokaisella kellosykillä valmistuu yksi käsky, vaikka yksittäisen käskyn kokonaisviive koostuu useista vaiheista.
Useimpia nykyaikaisia suorittimia ohjaa kello. Keskusyksikkö koostuu sisäisesti logiikasta ja muistista (flip flopeista). Kun kellosignaali saapuu, fläppiflopit tallentavat uuden arvonsa, minkä jälkeen logiikka tarvitsee ajan purkaakseen fläppien uudet arvot. Seuraavan kellopulssin saapuessa fläppiflopit tallentavat uuden arvon ja niin edelleen. Jakamalla logiikka pienempiin osiin ja lisäämällä flip‑flop‑rekistereitä (putkirekistereitä) logiikan osien väliin logiikan tarvitsema aika (arvojen dekoodaamiseen ja arvojen perusteella kelvollisten ulostulojen tuottamiseen) lyhenee. Tällä tavoin voidaan lyhentää kellojaksoa ja kasvattaa kellotaajuutta.
Esimerkki: 5-vaiheinen RISC-putki
Esimerkiksi RISC-putki jaetaan viiteen vaiheeseen, joiden välissä on joukko flip-floppeja seuraavasti:
- Käskyn nouto
- Käskyn dekoodaus ja rekisterin haku
- Suorita
- Muistin käyttö
- Rekisterin kirjoitus takaisin
Prosessorit, joissa on putkijohdotus, koostuvat sisäisesti vaiheista (moduuleista), jotka voivat työskennellä puoliksi itsenäisesti erillisten mikroohjeiden parissa. Kukin vaihe on flip-flopeilla kytketty seuraavaan vaiheeseen ("ketju") siten, että vaiheen ulostulo on tulo toiselle vaiheelle, kunnes käskyjen käsittely on suoritettu. Tällainen prosessorin sisäisten moduulien organisointi lyhentää ohjeen kokonaiskäsittelyaikaa ja ennen kaikkea kasvattaa läpimenoa, koska useita käskyjä on työn alla yhtä aikaa.
Ei-pipeline-arkkitehtuuri ei ole yhtä tehokas, koska jotkin suorittimen moduulit ovat käyttämättömiä, kun taas toinen moduuli on aktiivinen käskysyklin aikana. Putkijohdotus ei poista kokonaan tyhjäkäyntiä putkijohdotetussa suorittimessa, mutta suorittimen moduulien rinnakkaistoiminta lisää käskyjen läpimenoa merkittävästi verrattuna yksivaiheiseen toteutukseen.
Komentoputken sanotaan olevan täysin putkitettu, jos se voi ottaa vastaan uuden komennon joka kellojaksolla. Putkilinjassa, joka ei ole täysin putkitettu, on odotusjaksoja, jotka viivästyttävät putken etenemistä. Tyypillisiä syitä ovat pitkät muistitapahtumat, monisykliset toiminnalliset yksiköt (esim. kertoja) tai jaettujen resurssien konfliktit.
Suorituskyky: läpimeno vs. viive
Putkitus parantaa läpimenoa (käskyä per sykli, IPC), mutta yhden käskyn viive ei lyhene; se on usein jopa pidempi putkirekisterien ja vaiheiden lukumäärän vuoksi. Ihannetilanteessa, kun vaiheajat on tasapainotettu ja häiriöitä ei esiinny, N-vaiheinen putki voi valmistaa yhden käskyn per sykli, jolloin teoreettinen nopeutus verrattuna ei-putkitetuun toteutukseen lähestyy N:ää. Käytännössä nopeutusta rajoittavat epätasapainoiset vaiheajat, muistiviiveet ja haarojen aiheuttamat katkokset.
Putkihäiriöt (hazardit)
- Rakenteellinen häiriö: kaksi tai useampia vaiheita tarvitsee samaa resurssia yhtä aikaa (esim. yksi muistiväylä sekä käskyille että datoille). Seurauksena on odotus tai kupla putkessa.
- Datahäiriö: käsky tarvitsee operandin, jota edellinen käsky ei ole vielä tuottanut. Alalajit: RAW (read after write), WAR (write after read) ja WAW (write after write).
- Ohjaushäiriö: ehdolliset hypyt ja haarat muuttavat suorituksen suuntaa; jos suuntaa ei tiedetä ajoissa, väärin haetut käskyt täytyy hylätä (flush), mikä aiheuttaa viiveen.
Häiriöiden hallinta
- Edelleenohjaus / bypass: välitetään juuri laskettu tulos suoraan seuraaville vaiheille ilman, että odotetaan rekisterikirjoitusta.
- Putkilukko (stall) ja NOP-kuplat: pysäytetään vaiheita, kunnes tarvittava data tai resurssi on saatavilla.
- Haaran ennustus ja spekulointi: ennustetaan haaran suunta ja kohde (esim. kohdepuskurit, paluupinot); väärä ennuste tyhjentää putken ja aiheuttaa rangaistuksen, joka kasvaa putken syventyessä.
- Dynaaminen ajoitus ja rekisterien uudelleennimeäminen: vähennetään WAR/WAW-konflikteja ja mahdollistetaan out-of-order-suoritus, joka pitää putken täytenä, vaikka osa käskyistä odottaa operandia.
- Kääntäjän ajoitukset: käskyjen uudelleenjärjestely ja latenssien piilottaminen (esim. delay slot -tekniikat joissakin arkkitehtuureissa).
Syvempi ja leveämpi putki
Putkea voi syventää (lisää vaiheita) taajuuden kasvattamiseksi, mutta silloin vaiheiden tasapainotus vaikeutuu ja haaravirheen rangaistus kasvaa. Putkea voi myös leventää (superskalaari): dekoodataan ja käynnistetään useita käskyjä per sykli useisiin rinnakkaisiin toiminnallisiin yksiköihin. Leveät putket vaativat monimutkaista välittäjälogiikkaa ja rekisteritiedoston moninkertaisia portteja.
Muisti ja välimuistit
Muistivaiheeseen liittyy usein suurin vaihtelu. Välimuistit lyhentävät keskimääräistä latenssia, mutta välimuistihutit voivat pysäyttää useita vaiheita. Yleisiä tekniikoita ovat kuorman/esihakuputket, myymäläpuskuri (store buffer), muistin riippumattomuuden analyysi (memory disambiguation) ja erilliset käsky-/datapolut rakenteellisten häiriöiden vähentämiseksi.
Mikrokoodi ja µopit
Monimutkaiset käskyt voidaan suorittaa mikrokoodatun mikrosekvensserin avulla tai purkaa yhden tai useamman µopin jonoiksi. Nämä µopit kulkevat putken läpi kuten RISC-tyyppiset operaatiot. Joissakin toteutuksissa µopeja voidaan yhdistää (fusion) vähentämään dekoodin ja ajoituksen kuormaa.
Esimerkkikulku 5-vaiheisessa putkessa
Kun ensimmäinen käsky on noudettu (sykli 1), toinen käsky voidaan noutaa heti seuraavassa syklissä samalla, kun ensimmäinen dekoodataan. Sykleissä 3–5 ensimmäinen etenee suoritus-, muisti- ja kirjoitusvaiheisiin, ja samalla toinen, kolmas, neljäs ja viides käsky ovat eri vaiheissa. Syklistä 5 eteenpäin putki tuottaa yhden valmiin käskyn per sykli, kunnes tulee häiriö (esim. haaran virhe-ennuste tai välimuistihuti), joka tyhjentää tai pysäyttää joitakin vaiheita.
Osittain putkitetut yksiköt ja erikoistoiminnot
Kaikki yksiköt eivät välttämättä ole täysin putkitetut. Esimerkiksi kertolaskin tai liukulukuyksikkö voi olla monisyklinen: se voi aloittaa uuden operaation vain joka n:s sykli tai sen tulos valmistuu usean syklin jälkeen. Tällöin ajoituslogiikka huolehtii kuplien lisäämisestä tai ohjaa käskyjä vaihtoehtoisiin yksiköihin, kun mahdollista.
Suunnittelukompromissit
- Taajuus vs. virrankulutus: syvemmät putket nostavat taajuutta mutta lisäävät kulutusta ja lämpöä.
- Monimutkaisuus vs. hyöty: haaran ennustus, dynaaminen ajoitus ja rename parantavat läpimenoa mutta kasvattavat pinta-alaa ja verifiointityötä.
- Tarkat keskeytykset: arkkitehtuurin tila on palautettava johdonmukaiseksi häiriöiden ja poikkeusten sattuessa; tämä vaatii sitoumusvaiheen (retire/commit), joka säilyttää ohjelmallisen järjestyksen.
Yhteenvetona putkitus on keskeinen tekniikka, jolla kasvatetaan suorittimien tehokkuutta: se mahdollistaa useiden käskyjen samanaikaisen käsittelyn, maksimoi resurssien käyttöasteen ja skaalautuu sekä korkeampiin kellotaajuuksiin että laajempiin rinnakkaisiin toteutuksiin, kunhan häiriöt hallitaan tehokkaasti.


RISC-koneen viisiportainen perusputkisto (IF = käskyn haku, ID = käskyn dekoodaus, EX = suoritus, MEM = muistin käyttö, WB = rekisterin palautus). Pystyakseli on peräkkäiset ohjeet, vaaka-akseli on aika. Vihreässä sarakkeessa varhaisin käsky on siis WB-vaiheessa ja viimeisin käsky on käskynhakuvaiheessa.
Pipeliningin edut ja haitat
Pipeliningin edut:
- Prosessorin sykliaika lyhenee, mikä lisää ohjeiden läpimenoaikaa. Pipelining ei lyhennä käskyn suorittamiseen kuluvaa aikaa; sen sijaan se lisää samanaikaisesti ("kerralla") käsiteltävien käskyjen lukumäärää ja lyhentää suoritettujen käskyjen välistä viivettä (ns. läpimenoa).
Mitä enemmän putkistovaiheita prosessorissa on, sitä useampia ohjeita se voi käsitellä "kerralla" ja sitä pienempi viive on valmiiden ohjeiden välillä. Kaikissa nykyisin valmistetuissa
yleisissä mikroprosessoreissa on vähintään kaksi, jopa 30 tai 40 putkivaihetta. - Jos käytetään putkitusta, suorittimen aritmeettinen logiikkayksikkö voidaan suunnitella nopeammin, mutta siitä tulee monimutkaisempi.
- Teoriassa putkijohtaminen lisää suorituskykyä putkijohtamattomaan ytimeen verrattuna moninkertaisesti vaiheiden lukumäärän verran (olettaen, että myös kellotaajuus nousee samalla kertoimella), ja koodi on ihanteellista putkijohtosuoritusta varten.
- Putkipohjaiset suorittimet toimivat yleensä RAM-muistin kellotaajuutta korkeammalla kellotaajuudella (vuoden 2008 tekniikoista lähtien RAM-muistit toimivat alhaisilla kellotaajuuksilla verrattuna suorittimien kellotaajuuksiin), mikä lisää tietokoneiden kokonaissuorituskykyä.
Pipeliningin haitat:
Pipeliningillä on monia haittoja, vaikka suorittimien ja kääntäjien suunnittelijat käyttävätkin monia tekniikoita useimpien haittojen poistamiseksi. Seuraavassa on luettelo yleisimmistä haittatekijöistä:
- Ei-pipeloitu prosessori on yksinkertaisempi ja halvempi valmistaa, sillä se suorittaa vain yhden käskyn kerrallaan. Näin vältetään haarautumisviiveet (putkipohjaisessa prosessorissa jokainen haara viivästyy) sekä ongelmat, joita syntyy, kun sarjakäskyjä suoritetaan samanaikaisesti.
- Putkipohjaisessa prosessorissa flip-floppien lisääminen moduulien väliin kasvattaa käskyjen viiveaikaa verrattuna ei-pipelipohjaiseen prosessoriin.
- Ei-pipeloidulla prosessorilla on määritelty käskykapasiteetti. Putkipohjaisen prosessorin suorituskykyä on paljon vaikeampi ennustaa, ja se voi vaihdella suuresti eri ohjelmissa.
- Monissa malleissa on jopa 7, 10, 20, 31 ja jopa useamman vaiheen pituisia putkia; pitkän putken haittapuolena on se, että kun ohjelma haarautuu, koko putki on huuhdeltava (tyhjennettävä). Putkilinjojen suurempi läpäisykyky jää vajaaksi, kun suoritettava koodi sisältää monia haarautumisia: prosessori ei voi tietää etukäteen, mistä se lukee seuraavan käskyn, vaan sen on odotettava haarautumiskäskyn päättymistä, jolloin sen takana oleva putki jää tyhjäksi. Tätä haittaa voidaan pienentää ennustamalla edellisen toiminnan perusteella, tuleeko ehdollinen haarautumiskäsky haarautumaan. Kun haarautuminen on päättynyt, seuraavan käskyn on kuljettava koko putkisto läpi, ennen kuin sen tulos tulee saataville ja prosessori jatkaa jälleen "työskentelyä". Tällaisissa ääritapauksissa putkipohjaisen prosessorin suorituskyky voi olla huonompi kuin ei-putkipohjaisen prosessorin.
- Valitettavasti kaikki ohjeet eivät ole riippumattomia. Yksinkertaisessa putkistossa yhden käskyn suorittaminen voi vaatia 5 vaihetta. Jotta putki toimisi täydellä suorituskyvyllä, sen on suoritettava neljä seuraavaa itsenäistä ohjetta ensimmäisen suorituksen valmistuessa. Mikä tahansa näistä neljästä käskystä saattaa olla riippuvainen ensimmäisen käskyn tuloksesta, jolloin putkilinjan ohjauslogiikka joutuu odottamaan ja lisäämään putkilinjaan sakkauksen tai hukkaan menevän kellojakson, kunnes riippuvuus on ratkaistu. Onneksi tekniikoilla, kuten eteenpäinohjauksella, voidaan merkittävästi vähentää tapauksia, joissa viivyttelyä tarvitaan.
- Itseään muokkaavat ohjelmat saattavat epäonnistua suorituksessa putkijohdinarkkitehtuurissa, jos muutettavat ohjeet ovat lähellä suoritettavia ohjeita. Tämä voi johtua siitä, että ohjeet saattavat olla jo Prefetch Input Queue -jonossa, joten muutos ei ehkä tule voimaan tulevien ohjeiden suorituksessa. Ohjeiden välimuistit pahentavat ongelmaa entisestään.
- Vaarat: Kun ohjelmoija (tai kääntäjä) kirjoittaa assembly-koodia, hän yleensä olettaa, että jokainen käsky suoritetaan ennen seuraavan käskyn suorittamista. Kun tätä oletusta ei vahvisteta putkijohdolla, ohjelma käyttäytyy virheellisesti, ja tilannetta kutsutaan vaaratilanteeksi. On olemassa
erilaisia tekniikoita vaaratilanteiden ratkaisemiseksi tai kiertämiseksi, kuten eteenpäin lähettäminen ja viivyttäminen (lisäämällä viivytys tai hukkaan menevä kellojakso).
Esimerkkejä
Yleinen putkisto
Oikealla on yleinen putkisto, jossa on neljä vaihetta:
- Hae
- Decode
- Suorita
- Kirjoita takaisin
Ylin harmaa laatikko on suoritusta odottavien ohjeiden luettelo, alin harmaa laatikko on suoritettujen ohjeiden luettelo ja keskimmäinen valkoinen laatikko on putki.
Suoritus on seuraava:
Aika | Täytäntöönpano |
0 | Neljä ohjetta odottaa suoritusta |
1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | Kaikki ohjeet suoritetaan |
Bubble
Kun suorituksessa tapahtuu "hikka" (keskeytys), putkistoon syntyy "kupla", jossa ei tapahdu mitään hyödyllistä. Syklissä 2 violetin käskyn haku viivästyy, ja syklin 3 dekoodausvaiheessa on nyt kupla. Kaikki violetin käskyn takana oleva viivästyy myös, mutta kaikki violetin käskyn edessä oleva jatkaa suoritusta.
Kun verrataan edellä esitettyyn suoritukseen, on selvää, että kupla tuottaa yhteensä 8 kellopistettä 7 kellopisteen sijasta 8 kellopistettä suoritusaikaa.
Kuplat ovat kuin viiveitä, joissa mitään hyödyllistä ei tapahdu noutamisen, dekoodauksen, suorittamisen ja takaisinkirjoituksen aikana. Se on kuin NOP-koodi (lyhenne sanoista No OPeration).
Esimerkki 1
Tyypillinen käsky kahden luvun yhteenlaskuun voisi olla ADD A, B, C
, joka laskee yhteen muistipaikoissa A ja B olevat arvot ja sijoittaa tuloksen muistipaikkaan C. Putkijohdinprosessorissa putkijohdinohjain jakaisi tämän sarjaksi tehtäviä, jotka ovat samanlaisia kuin:
Sijainnit 'R1' ja 'R2' ovat suorittimen rekistereitä. Muistipaikkoihin 'A' ja 'B' tallennetut arvot ladataan (kopioidaan) näihin rekistereihin, lasketaan yhteen ja tulos tallennetaan muistipaikkaan 'C'.
Tässä esimerkissä putkisto on kolmivaiheinen - lataus, suoritus ja tallennus. Kutakin vaihetta kutsutaan putkiston vaiheiksi.
Ei-piipelöidyssä prosessorissa vain yksi vaihe voi työskennellä kerrallaan, joten koko käskyn on oltava valmis ennen kuin seuraava käsky voi alkaa. Putkipohjaisessa prosessorissa kaikki vaiheet voivat työskennellä samanaikaisesti eri ohjeiden parissa. Kun tämä ohje on suoritusvaiheessa, toinen ohje on dekoodausvaiheessa ja kolmas ohje noutovaiheessa.
Esimerkki 2
Käsitteen ymmärtämiseksi paremmin voimme tarkastella teoreettista kolmivaiheista putkea:
Vaihe | Kuvaus |
Lataa | Lue käsky muistista |
Suorita | Suorita käsky |
Myymälä | Tallenna tulos muistiin ja/tai rekistereihin |
ja pseudokoodin assembly-listaus suoritettavaksi:
Näin se toteutettaisiin:
Kello 1 | ||
Lataa | Suorita | Myymälä |
LOAD |
|
|
LOAD-käsky haetaan muistista.
Kello 2 | ||
Lataa | Suorita | Myymälä |
MOVE | LOAD |
|
LOAD-käsky suoritetaan, kun taas MOVE-käsky haetaan muistista.
Kello 3 | ||
Lataa | Suorita | Myymälä |
ADD | MOVE | LOAD |
LOAD-käsky on Store-vaiheessa, jossa sen tulos (luku 40) tallennetaan rekisteriin A. Sillä välin MOVE-käsky suoritetaan. Koska sen on siirrettävä A:n sisältö B:hen, sen on odotettava LOAD-käskyn päättymistä.
Kello 4 | ||
Lataa | Suorita | Myymälä |
STORE | ADD | MOVE |
STORE-käsky on ladattu, kun MOVE-käsky on päättymässä ja ADD-käsky on laskemassa.
Ja niin edelleen. Huomaa, että joskus jokin käsky on riippuvainen toisen käskyn tuloksesta (kuten esimerkissä MOVE). Kun useampi kuin yksi käsky viittaa tiettyyn operandin paikkaan joko lukemalla sitä (syötteenä) tai kirjoittamalla sitä (tulosteena), näiden käskyjen suorittaminen alkuperäisestä ohjelmajärjestyksestä poikkeavassa järjestyksessä voi johtaa vaaratilanteeseen (edellä mainittu).


Yleinen nelivaiheinen putkisto; värilliset laatikot edustavat toisistaan riippumattomia ohjeita.


Kupla syklissä 3 viivästyttää suoritusta
Aiheeseen liittyvät sivut
- Putkisto (laskenta)
- Rinnakkaislaskenta
- Käskytason rinnakkaisuus
Kysymyksiä ja vastauksia
Kysymys: Mitä on käskyjen putkijohtaminen?
V: Ohjeiden putkijohtaminen on tekniikka, jota käytetään nykyaikaisten mikroprosessoreiden, mikrokontrollerien ja suorittimien suunnittelussa niiden käskykapasiteetin lisäämiseksi jakamalla suorittimen käskyn käsittely useisiin itsenäisiin vaiheisiin, joiden lopussa on varastointi.
Kysymys: Miten putkijohtaminen toimii?
V: Pipelining toimii jakamalla logiikka pienempiin osiin ja lisäämällä logiikan osien väliin flip-floppeja, mikä lyhentää logiikan tarvitsemaa aikaa arvojen dekoodaamiseen, kunnes se tuottaa kelvollisia ulostuloja näistä arvoista riippuen. Tämä mahdollistaa nopeammat kellojaksot.
K: Mitä esimerkkejä putkistoista on?
V: Esimerkki putkistosta on RISC-putkisto, joka on jaettu viiteen vaiheeseen, joiden välissä on joukko flip-flooppeja.
K: Miten putkijohtaminen lisää käskyjen läpimenoa?
V: Putkijohdotus lisää käskyjen läpimenoa sallimalla prosessorimoduulien työskennellä rinnakkain, mikä vähentää tyhjäkäyntiä käskysyklin aikana ja lisää kokonaiskäsittelyaikaa.
K: Onko jokainen putkisto täysin putkitettu?
V: Ei, kaikki putkistot eivät ole täysin putkitettuja; joissakin putkistoissa on odotusjaksoja, jotka viivästyttävät putkiston etenemistä.