Superscalaire processor

Een superscalaire processor is een processor die meerdere instructies tegelijkertijd kan uitvoeren. Hierbij gaat de processor een groep van instructies ophalen om vervolgens te kijken welke afzonderlijk uitgevoerd kunnen worden. Niet elke instructie kan immers zomaar parallel uitgevoerd worden (bijvoorbeeld de uitkomst van de ene instructie is een parameter voor een andere instructie). Veel van dit soort van problemen kunnen echter relatief gemakkelijk opgelost worden door gebruik te maken van bijkomende registers (dupliceren van bronnen) of de referenties naar bepaalde registers te wijzigen.

Het parallel uitvoeren van instructies gebeurt via een aantal functionele eenheden. In de praktijk zal men deze eenheden verder uitvoeren met pipelines om de doorvoer van instructies verder te verhogen.

Het superscalaire ontwerp gaat goed samen met zowel een RISC- als een CISC-architectuur.

Meerdere pipelines bewerken

Elk van de functionele eenheden van een superscalaire architectuur kan verder uitgerust worden met een instructie pipeline. Zij zullen elke instructie verder opdelen in stages en net zoals bij een productielijn meerdere instructiestages parallel uitvoeren. Beide zullen de performantie van een superscalaire processor drastisch verhogen.

In de praktijk wordt een superscalaire processor bijna altijd gecombineerd met pipelining hoewel dit per definitie niet verplicht is.

Parallelle verwerking in de processor bewerken

De instructies die klaar gezet staan worden door verschillende onderdelen van een processor (tegelijkertijd) uitgevoerd.

Afhankelijkheidsbeperkingen bewerken

De verschillende soorten beperkingen op gebied van het parallel uitvoeren van instructies kunnen we opdelen in 5 hoofdgroepen:

1) Data-afhankelijkheid:

Wanneer de uitvoer van een instructie nodig is als invoer voor een tweede instructie moet deze tweede instructie wachten op de eerste instructie alvorens volledig uitgevoerd te kunnen worden.

2) Procedurele afhankelijkheid:

Dit is het geval bij instructies die een branch moeten volgen (bijvoorbeeld if, else). De volgende instructies die moeten worden uitgevoerd zijn volledig gebaseerd op de uitkomst van deze branch.

3) Bronafhankelijkheid:

Dit treedt op wanneer twee instructies willen gebruikmaken van dezelfde bronnen op hetzelfde moment. In tegenstelling tot data-afhankelijkheid kan dit probleem voorkomen worden door deze bronnen te dupliceren en beschikbaar te stellen.

4) Uitvoerafhankelijkheid:

Wanneer de uitvoer van twee verschillende instructies naar dezelfde geheugenlocatie wordt geschreven, is de volgorde van de uit te voeren instructies belangrijk. Indien men hier geen rekening mee houdt dan zouden andere instructies de verkeerde waarde gebruiken.

5) Anti-afhankelijkheid:

Dit wordt geacht als het tegenovergestelde van data-afhankelijkheid: Hierbij gaat de ene instructie de inhoud van een geheugenplaats gebruiken als operand terwijl een andere instructie hier op hetzelfde moment in wegschrijft.

De optimalisatie hiervan ligt bij goed ontworpen compilers en/of hardware.