Intel Pentium 4
Arkkitehtuuri

Pentium 4n suunnitteluperiaatteissa keskityttiin erityisesti raa'an laskentatehon kasvattamiseen yksinkertaisella koodilla. Tätä tehtiin kahdella pääperiaatteella, mahdollisimman suurella kellotaajuudella sekä yksinkertaisten laskentakäskyjen mahdollisimman nopealla suorituksella, monimutkaisempien käskyjen kustannuksella.
Mahdollisimman suuren kellotaajuuden saavuttamiseksi piirin liukuhihna jaettiin 28 vaiheeseen, jolloin jokaisesta yksittäisestä liukuhihnan vaiheesta pystyttiin tekemään mahdollisimman lyhyt.
Lisäksi piirin yksinkertaisia operaatioita suorittavat laskentayksiköt kellotettiin kaksinkertaiselle kellotaajuudelle piirin muihin osiin nähden, mikä mahdollisti erittäin suuren suoritusnopeuden näille yksinkertaisille yksiköille. Haittapuolena tästä oli kuitenkin se, että datansiirrosta piirin hitaiden ja nopeiden osien välillä tuli ylimääräisiä viiveitä, ja pelkästään nopeita yksiköitä käyttävät koodipätkät olivat tosimaailman koodissa hyvin lyhyitä ja harvinaisia.
Nopeat laskentayksiköt oli toteutettu jakamalla 32-bittisten operaatioiden suoritus kahteen kuudentoista bitin palaseen ja suorittamalla operaatiot ensin alimmille biteille ja vasta seuraavalla kellojaksolla ylimmille biteille, kun alimpien bittien tuottama muistinumerobitti on jo valmistunut. Näin alimmat bitit pystyttiin välittämään seuraavan operaation laskettavaksi ennen kuin ylimpiä bittejä oli vielä ehditty laskea, eikä muistinumeron välittämisestä laskentayksikön sisällä tule pullonkaulaa kuten yleensä yhteen- ja vähennyslaskuyksiköissä.
Jotta piirin nopeista laskentayksiköistä saatiin täysi teho irti, piti koodi optimoida Pentium 4:lle eri tavalla kuin aiemmille suorittimelle; esimerkiksi neljällä kertominen sujui muilla suorittimilla nopeimmin siirtämällä bittejä kahden verran oikealle, mutta Pentium 4:lla tämä kannatti tehdä kahdella yhteenlaskulla, koska yhteenlaskut laskettiin nopeilla laskentayksiköillä, kun taas bittien siirto hitailla.
Pentium 4:n välimuistirakenne erosi myös selvästi edeltäjistään; L1-datavälimuisti suunniteltiin mahdollisimman nopeaksi, toimimaan vain kahden kellojakson viiveellä. Haittapuolena tästä oli se, että tällöin tästä välimuistista piti tehdä hyvin pieni, vain 8 KiB:n kokoinen. Niin kauan kuin käytettävä data mahtui L1-välimuistiin, prosessori pystyi toimimaan hyvin nopeasti, mutta tosimaailman ohjelmakoodien käyttämät datamäärät olivat yleensä paljon suurempia.
Prosessorin L2-välimuisti suunniteltiin suoriutumaan erittäin hyvin koodista, jossa datalla on paljon paikallisuutta, esimerkiksi koodista jossa käydään läpi suuria määriä peräkkäistä dataa. Tämän johdosta prosessorilla on verrattain pitkä 128 tavun välimuistilinja, joka soveltuu hyvin ottamaan kaiken kaistanleveyden irti suuren kaistanleveyden omaavasta muistista, mutta epäsäännöllisemmin muistia käyttävillä ohjelmilla johtaa siihen, että muistista ladataan turhaan välimuistiin enemmän dataa kuin pienemmällä lohkokoolla ladattaisiin.
Prosessorin L1-käskyvälimuisti talletti alkuperäisten x86-käskyjen sijaan valmiiksi dekoodattuja mikrokäskyjä. Lisäksi käskyjä ei tallennettu välimuistiin osoitteidensa mukaan, vaan siihen järjestykseen missä käskyt oli suoritettu("trace cache"). Tämä mahdollisti paremman suorituskyvyn tiheissä loopeissa, mutta välimuistiin mahtui verrattain pieni määrä käskyjä ja hidasti huonosti ennustettavia hyppyjä kauemmaksi ohjelmakoodissa.
Käskyvälimuistia ennen liukuhihnalla oli 8 dekoodausvaihetta, välimuistin jälkeen 20 vaihetta. Mikäli haarautumiskäskyn yhteydessä hypättiin koodissa kohtaan, jota ei löytynyt käskyvälimuistista, prosessori pysähtyi 28 kellojaksoksi. Jos hypättiin koodissa kohtaan joka löytyi välimuistista, mutta joka ennustettiin väärin, prosessori pysähtyi 20 kellojaksoksi. Jos hyppy osattiin ennustaa oikein, ja hypyn kohde löytyi välimuistista, hypyn suorittaminen ei vienyt yhtään kellojaksoa