Waarom een nieuwe architectuur?
Na dertien jaar trouwe dienst in alle processors van de 386 tot de Pentium 4 is IA-32 toe aan vervanging. Deze architectuur valt onder het zogenaamde CISC (Complex Instruction Set Computing), een methode van werken waarbij de processor meestal een groot aantal verschillende instructies kent. Omdat de processor natuurlijk niet echt zoveel verschillende dingen kan doen hebben CISC processors intern vaak een RISC (Reduced Instruction Set Computing) ontwerp, oftewel proberen ze van binnen meestal met zo min mogelijk verschillende instructies werken. Omdat de processor intern heel anders in elkaar zit dan hij voor de software in elkaar lijkt te zitten moet er van alles heen en weer vertaald worden. Dat is natuurlijk niet erg makkelijk en daaraan is dan ook te merken dat IA-32 zijn beste tijd gehad heeft.
Enkele problemen van nu:
Een processor heeft aan aantal execution units die verantwoordelijk zijn voor het rauwe rekenwerk. Andere delen van de CPU zorgen ervoor dat er opdrachten en gegevens worden aangevoerd en er resultaten worden afgevoerd. Om het maximale uit een processor te halen is het dus noodzakelijk om de execution units continu van data en opdrachten te voorzien. Dit lijkt niet zo ingewikkeld, maar het vereist nogal wat voorzichtigheid, want hoewel de instructies altijd keurig op een rijtje in het geheugen staan komt het slechts zeer zelden voor dat een programma ze exact in die volgorde uitvoert. Sommige opdrachten mogen namelijk alleen worden uitgevoerd als aan bepaalde voorwaarden is voldaan en soms moet er een keuze gemaakt worden tussen twee functies afhankelijk van het resultaat van de vorige.
Om het nog eens extra lastig te maken werkt de processor met een pipeline. Vooraan in de pipeline vliegen instructies naar binnen en na een ritje door het binnenste van de processor wordt het resultaat op de juiste plek neergezet. Omdat het parcours lang is kunnen er meerdere instructies tegelijk doorheen fietsen. Zolang alles op volgorde gaat is dit geen probleem, maar als het programma bij een zogenaamde branch (vertakking) in de code komt moet er dus eerst gewacht worden op het resultaat van opdracht A voordat de processor weet of opdracht B of opdracht C de pipeline in moet. Dat is vervelend, want zoals we al gezegd hebben moeten de execution units zoveel mogelijk gevuld blijven en zolang er niets de pipeline wordt ingegooid staan die dingen maar een beetje uit hun neus te vreten.
Een oplossing daarvoor is om op het moment dat er zo'n branch optreedt te kijken naar de andere opdrachten die in het cache staan te wachten om te worden uitgevoerd. Als daar opdrachten tussen zitten die niets te maken hebben met de opdrachten die staan te wachten op antwoord en dus de loop van het programma niet in de war kunnen gooien worden deze alvast uitgevoerd. Deze manier van werken heet ook wel OOO of Out Of Order execution. Het voordeel daarvan is dat de execution units toch nog iets te doen hebben, maar natuurlijk kost het uitzoeken van geschikte opdrachten ook nogal wat tijd, in sommige gevallen meer dan het kost om even te wachten. Daarom is er nog iets anders bedacht; gokken.
Natuurlijk zijn daarvoor zeer effectieve stukjes hardware en statistische algoritmes, oftewel branch predictors, bedacht die meer dan 95% van de branches goed kunnen voorspellen. De keren dat het fout gaat is het echter een kleine ramp voor de processor. Stel dat de uitslag van opdracht A bepaalt of opdracht B of E moet worden uitgevoerd. De branch predictor gokt op B en voert A, B, C en D de pipeline in. Zodra A er aan de achterkant uitkomt blijkt echter dat E moest worden gedaan. Op dat moment moeten de effecten van B, C en D ongedaan gemaakt worden, iets wat flink kloktikken kost. Pas zodra de pipeline weer leeg is (flushed) en de waarden zijn hersteld worden E, F en G ingevoerd. Aan deze mis-predictions is helaas niets te doen en met de steeds langer wordende pipelines van tegenwoordig is het een steeds groter probleem aan het worden.
Een ander groot nadeel van IA-32 is het feit dat er te weinig registers zijn; kleine stukjes geheugen op de CPU nog sneller dan het L1 cache. Daardoor is de schaalbaarheid van de processors beperkt, zo kunnen er bijvoorbeeld nooit op een efficiënte manier meer dan drie opdrachten per kloktik worden worden verwerkt door een IA-32 processor. Ook de 32 bit beginnen een beetje krap te worden, indien men met extreem grote bestanden wil omgaan of grote hoeveelheden geheugen wil aanspreken zullen 32 bit processors het laten afweten. Dat is op dit moment nog niet zo ter sprake, maar met de snelle groei van informatietechnologie zal het niet lang meer duren voor het een serieuze bottleneck wordt.
Een processor heeft aan aantal execution units die verantwoordelijk zijn voor het rauwe rekenwerk. Andere delen van de CPU zorgen ervoor dat er opdrachten en gegevens worden aangevoerd en er resultaten worden afgevoerd. Om het maximale uit een processor te halen is het dus noodzakelijk om de execution units continu van data en opdrachten te voorzien. Dit lijkt niet zo ingewikkeld, maar het vereist nogal wat voorzichtigheid, want hoewel de instructies altijd keurig op een rijtje in het geheugen staan komt het slechts zeer zelden voor dat een programma ze exact in die volgorde uitvoert. Sommige opdrachten mogen namelijk alleen worden uitgevoerd als aan bepaalde voorwaarden is voldaan en soms moet er een keuze gemaakt worden tussen twee functies afhankelijk van het resultaat van de vorige.
Om het nog eens extra lastig te maken werkt de processor met een pipeline. Vooraan in de pipeline vliegen instructies naar binnen en na een ritje door het binnenste van de processor wordt het resultaat op de juiste plek neergezet. Omdat het parcours lang is kunnen er meerdere instructies tegelijk doorheen fietsen. Zolang alles op volgorde gaat is dit geen probleem, maar als het programma bij een zogenaamde branch (vertakking) in de code komt moet er dus eerst gewacht worden op het resultaat van opdracht A voordat de processor weet of opdracht B of opdracht C de pipeline in moet. Dat is vervelend, want zoals we al gezegd hebben moeten de execution units zoveel mogelijk gevuld blijven en zolang er niets de pipeline wordt ingegooid staan die dingen maar een beetje uit hun neus te vreten.
Een oplossing daarvoor is om op het moment dat er zo'n branch optreedt te kijken naar de andere opdrachten die in het cache staan te wachten om te worden uitgevoerd. Als daar opdrachten tussen zitten die niets te maken hebben met de opdrachten die staan te wachten op antwoord en dus de loop van het programma niet in de war kunnen gooien worden deze alvast uitgevoerd. Deze manier van werken heet ook wel OOO of Out Of Order execution. Het voordeel daarvan is dat de execution units toch nog iets te doen hebben, maar natuurlijk kost het uitzoeken van geschikte opdrachten ook nogal wat tijd, in sommige gevallen meer dan het kost om even te wachten. Daarom is er nog iets anders bedacht; gokken.
Natuurlijk zijn daarvoor zeer effectieve stukjes hardware en statistische algoritmes, oftewel branch predictors, bedacht die meer dan 95% van de branches goed kunnen voorspellen. De keren dat het fout gaat is het echter een kleine ramp voor de processor. Stel dat de uitslag van opdracht A bepaalt of opdracht B of E moet worden uitgevoerd. De branch predictor gokt op B en voert A, B, C en D de pipeline in. Zodra A er aan de achterkant uitkomt blijkt echter dat E moest worden gedaan. Op dat moment moeten de effecten van B, C en D ongedaan gemaakt worden, iets wat flink kloktikken kost. Pas zodra de pipeline weer leeg is (flushed) en de waarden zijn hersteld worden E, F en G ingevoerd. Aan deze mis-predictions is helaas niets te doen en met de steeds langer wordende pipelines van tegenwoordig is het een steeds groter probleem aan het worden.
![]() |
Een ander groot nadeel van IA-32 is het feit dat er te weinig registers zijn; kleine stukjes geheugen op de CPU nog sneller dan het L1 cache. Daardoor is de schaalbaarheid van de processors beperkt, zo kunnen er bijvoorbeeld nooit op een efficiënte manier meer dan drie opdrachten per kloktik worden worden verwerkt door een IA-32 processor. Ook de 32 bit beginnen een beetje krap te worden, indien men met extreem grote bestanden wil omgaan of grote hoeveelheden geheugen wil aanspreken zullen 32 bit processors het laten afweten. Dat is op dit moment nog niet zo ter sprake, maar met de snelle groei van informatietechnologie zal het niet lang meer duren voor het een serieuze bottleneck wordt.
Volgende pagina (EPIC: de oplossing - 3/10)

