De performance van een processor wordt ruwweg in 2 componenten onderverdeeld:
- Het aantal keer per seconde dat de processor nuttig werk kan verrichten. Dit noemen we de kloksnelheid en wordt gemeten in Hz (of een factor daarvan zoals MHz of GHz).
- De hoeveelheid werk dat de processor in 1 keer (dus in 1 kloktik) kan verrichten. Dit noemen we de IPC-graad (staat voor "Instructions Per Cycle") en wordt aangeduid d.m.v. een reëel getal. Dit getal is trouwens nooit absoluut meetbaar; je kan enkel het maximum aangeven. Eventueel zou je het gemiddelde kunnen berekenen voor een bepaalde reeks bewerkingen.
Beiden worden bepaald door de architectuur van de processor. Eenvoudig gesteld verwerkt een processor instructies op data om verwerkte data als uitvoer te geven. In moderne processoren wordt een instructie opgedeeld in deel-instructies. Iedere deel-instructie wordt dan na elkaar uitgevoerd door een onderdeel van de processor (die we de pipeline stage noemen). Alle pipeline stages worden door alle instructies in een vaste volgorde doorlopen. De volledige opeenvolging van doorlopen stages noemen we de execution-pipeline. Eens alle stages van de execution-pipeline doorlopen zijn, is de instructie afgehandeld. De regel is dat iedere deel-instructie binnen 1 kloktik van de processor uitgevoerd moet kunnen worden. Op deze manier werkt een processor aan meerdere instructies tegelijkertijd (iedere pipeline stage kan werken aan een deel-instructie van een verschillende instructie).
Uit deze uitleg moet het duidelijk zijn dat de kloksnelheid van de processor bepaald wordt door de deel-instructie die de meeste tijd inneemt (d.i. de bottleneck).
Stel dat een ontwerper de maximaal haalbare kloksnelheid wil verhogen, dan kan die op zoek gaan naar de langzaamste deel-instructie en die optimaliseren. Stel dat die deel-instructie na optimalisatie nog steeds de langzaamste instructie is, dan kan de ontwerper kiezen om die deel-instructie op te splitsen in 2 deel-instructies. We zeggen dan dat de execution-pipeline verlengd wordt. De bedoeling is dat de 2 deel-instructies nu elk apart minder tijd innemen dan de oorspronkelijk deel-instructie (ideaal nemen beide deel-instructies 50% in van de oorspronkelijke deel-instructie).
Dit is de techniek die Intel gebruikt heeft bij het ontwerpen van de Pentium4 architectuur. Bij iedere nieuwe generatie Pentium4 heeft Intel deze techniek verder gebruikt en is de execution-pipeline sinds de eerste Pentium4 (de zgn. Wilamette core) verlengd van (dacht ik) een 20-tal stappen tot nu meer dan 30 in de Prescott-core.
Het nadeel van deze techniek is dat deze een zwaar negatieve invloed heeft op de tweede component van de performance (de IPC). Een programma bestaat uit een hele reeks instructies die achtereenvolgens (in een welbepaalde volgorde) uitgevoerd moeten worden. Sommige instructies in dat programma worden meermaals uitgevoerd (we noemen dit een iteratie/herhaling) en andere mogen pas uitgevoerd worden wanneer aan een conditie voldaan is (we noemen dit een selectie).
Wanneer de processor een selectie tegenkomt (we noemen dit een branch), dan moet in principe gewacht worden op de uitkomst van de selectie vóór de volgende instructies uitgevoerd worden. De selectie wordt opgesplitst in deel-instructies die elk 1 kloktik in beslag nemen. Op een processor met 30 deel-instructies, zal het "evalueren" van de conditie dus zeker 30 kloktikken in beslag nemen. De volgende instructie wordt pas nadien uitgevoerd waardoor de uitkomst ervan weer pas na 30 kloktikken verkregen wordt.
Om dit performance-verlies te beperken passen ontwerpers een truukje toe. Deze bestaat erin de uitkomst van de conditie te voorspellen (we noemen dit "branch prediction"). Op basis van die voorspelling voert de processor meteen ook de instructie (of opeenvolging van instructies) uit die hoort bij die uitkomst van de voorspelling. De selectie wordt m.a.w. door de execution-pipeline gestuurd en de eerstvolgende instructie die uit de execution-pipeline komt is de instructie die volgt op de voorspelde selectie-uitkomst.
Werd het resultaat van de conditie correct voorspeld, dan zijn de volgende instructies vrijwel meteen uitgevoerd na de evaluatie van de conditie.
Is het resultaat van de conditie verkeerd voorspeld, dan moet de correcte instructie (of opeenvolging van instructies) uitgevoerd worden. De correcte instructie moet dan nog alle pipeline stages doorlopen eer die uitgevoerd is. De kost van een verkeerde voorspelling is gelijk aan het aantal pipeline stages (in de Prescott is dat 30; je verliest dus 30 kloktikken bij iedere verkeerde voorspelling).
Natuurlijk kan het aantal voorspellingsfouten ingeperkt kunnen worden door een beter voorspellingsalgoritme te gebruiken. Maar geen enkel voorspellingsalgoritme is feilloos en er gebeuren dus zowieso voorspellingsfouten. Bij een processor met veel pipeline stages zal zo'n fout meer kosten dan bij een processor met weinig stages.
Zoals je nu kan inzien zal iedere foute voorspelling de hoeveelheid nuttig uitgevoerd werk per kloktik (IPC) sterk verlagen bij iedere foute voorspelling. De huidige Pentium4 heeft ongeveer 30 pipeline stages. De Pentium-M heeft er zo'n 12 à 13. De AthlonXP had er 10 en de Athlon64 heeft er 12. Op het IPC-vlak heeft de AthlonXP dus de beste troeven in handen. Dat de Athlon64 en de Pentium-M op gelijke kloksnelheid beter presteren ligt aan diverse andere optimalisaties (een beter voorspellingsalgoritme, ...) die de IPC opvoeren.