Laboration 2
Laboration 2
Laboration 2
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
<strong>Laboration</strong> 2<br />
<strong>Laboration</strong> 2<br />
Syftet med denna laboration är att ingående lära sig konstruktionsprinciper, prestandavinster<br />
samt implementeringsaspekter för cacheminne i moderna minnessystem.<br />
Förberedelser<br />
Läs igenom laborationshandledningen och gör hemuppgifterna i handledningen.<br />
Inledning<br />
<strong>Laboration</strong> 2<br />
Ett datorsystem består som bekant av en centralenhet (eller processor), minne samt in/ut-enheter. Datorsystemets<br />
prestanda beror av prestanda hos dessa komponenter. I föregående laborationer fann vi att en processor kan uppnå<br />
mycket höga beräkningshastigheter med hjälp av pipelining. Load/Store-arkitekturer såsom DLX är utmärkta exempel<br />
på detta. En förutsättning för att den höga beräkningshastigheten skall bibehållas är emellertid att minnessystemet<br />
kan leverera instruktioner och data i varje klockcykel. Med en klockfrekvens på 200 MHz inses snabbt<br />
att man måste ta till speciella knep för att instruktioner och data skall kunna läsas varje 5 ns. Det är dessa knep som<br />
denna laboration skall lära ut.<br />
Det är givet att totalprestandan hos ett datorsystem är starkt beroende på den tid det tar för processorn att hämta<br />
och lämna information i minnet (den s.k. minnes-accesstiden). Eftersom snabba minnen är dyra och eftersom målet<br />
för en datortillverkare är att få ner totalkostnaden på datorsystemet, är det ett viktigt konstruktionsmål att erhålla<br />
ett så stort och snabbt minne till så låg kostnad som möjligt.<br />
På grund av en viktig princip, den s.k. lokalitetsprincipen för minnesreferenser, kan man kombinera små, snabba<br />
(och dyra) minnen med stora långsamma (och billiga) i en hierarki så att hela minnet skenbart uppträder som ett<br />
snabbt (som det dyra) och stort (som det billiga) så att totalkostnaden per minnescell ligger nära det stora minnets<br />
och accesstiden ligger nära det snabba.<br />
Denna viktiga teknik — cacheminnesteknik — är så avgörande i moderna datorsystem att en fundamental förståelse<br />
är viktig. Vi skall i denna laboration studera cacheminnestekniken från följande synvinklar:<br />
• Konstruktionsprinciper för cacheminne<br />
• Inverkan av cacheorganisationen på prestanda<br />
• Programbeteendets inverkan på prestanda<br />
I denna laboration skall vi använda en simulator för ett DLX-baserat datorsystem bestående av en DLX CPU (centralenhet)<br />
och ett minnessystem bestående av en cache och ett huvudminne. Minnessystemet kan konfigureras om<br />
så att man kan studera olika organisationer av cacheminnet och huvudminnet. Simulatorn gör det möjligt att studera<br />
prestanda för olika cacheorganisationer för program skrivna i assemblyspråk för DLX. Första delen av laborationen<br />
tjänar till att förstå hur vissa egenskaper hos minnesreferenserna kan utnyttjas av ett cacheminne så att de<br />
flesta minnesreferenserna kan hanteras av cachen (med dess accesstid). Konstruktionsrymden för en cache är stor<br />
och det är inte självklart hur organisationen påverkar prestanda. Andra delen tjänar till att bringa viss klarhet i detta.<br />
Realisering av “smarta” algoritmer i hårdvara omintetgörs oftast beroende på att de kostar så mycket antingen i<br />
prestanda eller i hårdvarukomplexitet att det inte lönar sig. I slutet av laborationen studerar vi detta.<br />
Vi börjar med att ge en beskrivning av simulatorn.<br />
Per Stenström, Fredrik Dahlgren och Håkan Grahn<br />
Handhavande av simulatorn<br />
Simulatorn som används under laborationen gör det möjligt att analysera olika cacheorganisationers inverkan på<br />
exekveringstiden för program skrivna för DLX.<br />
Simulatorn består av följande delar:<br />
• En simuleringsmodell av mikroprocessorn DLX<br />
• En simuleringsmodell av ett minnessystem bestående av en cache och ett huvudminne<br />
Cachen och huvudminnets organisation kan förändras och dess inverkan på exekveringstiden kan därmed studeras.<br />
1<br />
2
<strong>Laboration</strong> 2<br />
Assemblering av program<br />
DLX-simulatorn läser program skrivna i DLX-assemblyspråk. Man editerar ett assemblyspråksprogram på vanligt<br />
sätt. Det enda man måste tänka på är att programmet inte får exekveras i oändlig slinga och att det måste avslutas<br />
med assemblyinstruktionen trap #0. Filnamnet måste ha filtypen “s”.<br />
Start av simulatorn<br />
I katalogen /home/obelix/staff/ide/nesse/cache/ finns några algoritmer kodade i DLX-assemblyspråk.<br />
Ställ dig i hemmakatalogen. Dess filer, och några andra som inte finns där, kopieras till en underkatalog med<br />
namnet cache_lab genom kommandot:<br />
/home/obelix/staff/ide/nesse/bin/init_cache<br />
Förflytta Dig därefter till denna katalog och starta därefter cachesimulatorn med kommandot<br />
cache example0<br />
Efter att programmet lästs in och analyserats av simulatorn skapas ett fönster som lämpligtvis positioneras någonstans<br />
i mitten av skärmen.<br />
Simulatorns funktioner<br />
I Figur 2.1 visas en bild över simulatorn. Vi skall gå igenom de olika funktionerna nedan. Tre boxar symboliserar<br />
CPUn, cachen och huvudminnet. Mellan CPUn och cachen finns tre fält som vid exekvering visar adress, data och<br />
typ av operation för den minnesoperation som CPUn initierat. Adressen visas också indelad i tag, index och offset<br />
ovanför linjen mellan CPUn och cachen.<br />
Figur 2.1: Simulatorn med de tre boxarna: CPU, cache och minne.<br />
Minnesoperationerna som initieras av cachen visas på motsvarande sätt mellan cachen och minnet. I figuren visas<br />
ett läge då CPUn läser in en instruktion som är 32 bitar (Read L står för läsning av ett 32-bitars ord och I står för<br />
instruktionsuthämtning). Minnesoperationen ger upphov till en cachemiss (minnet är mörklagt) som leder till att<br />
blocket på samma adress hämtas. Allmänt gäller att den enhet som är aktiverad (cache eller minne) mörkläggs vid<br />
en minnesoperation. På så vis ser man lätt om en minnesoperation leder till träff (eng. hit) eller miss. Notera att alla<br />
minnesoperationer motsvarar 32 bitar.<br />
Exekvering av program<br />
Man kan välja mellan tre sätt att exekvera ett program. Dels kan man exekvera programmet i full fart med<br />
(till vänster i figuren) eller så kan man exekvera det till nästa minnesreferens med Step .<br />
Go<br />
3<br />
<strong>Laboration</strong> 2<br />
Ett tredje sätt är att exekvera programmet ett antal minnesreferenser framåt genom att ange ett antal i fältet under<br />
No of steps. I detta fall kan man låta exekveringen ske i halvfart genom Visual . Härvid kommer cachen respektive<br />
minnet att blinka till när de aktiveras. Man kan också exekvera det i full fart med Go fältet under No of<br />
steps.<br />
Det finns också möjlighet att ställa in brytpunkter på en viss adress. Detta görs under CPU-menyn (se nedan).<br />
Ovanstående funktioner erhålls genom att motsvarande fält pekas ut samtidigt som vänster musknapp trycks ned.<br />
Då programmet är färdigexekverat, kommer adressfälten att blankställas.<br />
Ändring av parametrar för CPU, cache- och minnesorganisation<br />
Det finns tre popup-menyer för att ställa in olika parametrar. Dessa menyer är CPU-menyn, cache-menyn samt<br />
minnes-menyn. Menyerna erhålls genom att peka på motsvarande box (CPU-menyn fås då CPUn pekas ut) samtidigt<br />
som vänster musknapp trycks ned.<br />
I CPU-menyn kan följande göras:<br />
• Reset. Initiering av CPUn. Detta måste göras före exekvering av ett program.<br />
• Change. Ändra klockcykeltid för CPUn.<br />
• Break On Address. Inställning av brytpunkt för adress.<br />
• Quit. Lämna simulatorn.<br />
I cache-menyn kan följande göras:<br />
• Change. Ändring av cacheorganisation.<br />
• Contents. Inspektion av cacheinnehållet.<br />
Om Change väljs, erhålls ett fönster i vilket man kan ändra olika parametrar som styr organisationen. Fönstrets<br />
utseende visas i Figur 2.2.<br />
Figur 2.2: Fönstret i vilket man ändrar cacheorganisationen.<br />
4
<strong>Laboration</strong> 2<br />
<strong>Laboration</strong> 2<br />
Som figuren visar kan man ändra cachestorlek, blockstorlek, antal mängder (eng. set) (adressavbildningsmetod),<br />
accesstid, uppdateringsstrategi (eng. write policy) samt utbytesalgoritm (eng. replacement policy). Cache och<br />
blockstorlek anges i antal 32-bitars ord, som vi hädanefter kommer att kalla för ord, kort och gott.<br />
De numeriska värdena ändras genom att man ökar eller minskar genom att trycka på “+” eller “-”. Övriga parametrar<br />
ändras genom att trycka på det högra fältet på motsvarande rad ett antal gånger tills önskat alternativ kommer<br />
upp. Om man exempelvis vill ändra till copy-back, pekar man ut fältet i vilket det står write-through och trycker<br />
därefter på vänster musknapp. Fönstret tas bort genom att aktivera rutan Close .<br />
Om Contents väljs skapas ett fönster i vilket man kan studera såväl innehållet i varje block i cachen som den information<br />
som krävs av adressavbildningsmetoden och utbytesalgoritmen.<br />
Nedan visas cacheinnehållet efter exekvering av ett program med en mängd-associativ, 8 ords cache med 1 ord /<br />
block och 2 block/mängd som använder utbytesalgoritmen LRU samt upp\-dateringsstrategin copy-back (förklaras<br />
senare i kommande avsnitt).<br />
V D R Tag Block<br />
- - - --- -----<br />
0 : 1 1 0 80b 0 0 0 8<br />
1 0 1 805 0 a 24 d9<br />
1 : 1 0 0 805 4 80 0 0<br />
1 0 1 808 0 0 0 8<br />
2 : 1 1 1 80a 0 0 0 6<br />
1 0 0 805 0 1 66 f6<br />
3 : 1 0 0 805 4e 72 27 0<br />
1 1 1 80a 0 0 0 7<br />
Varje rad motsvarar informationen i ett cacheblock med statusbitarna (V=Valid, D=Dirty samt R=Reference för<br />
LRU och FIFO) och taggen. Därefter följer blockinnehållet (1 ord = 4 bytes). Fönstret uppdateras efter varje minnesoperation.<br />
Det tas bort genom att aktivera Close .<br />
Ovanför linjen mellan CPUn och cachen finns tre fält som visar adressen som CPUn lägger ut uppdelad i tag, index<br />
och offset. Detta är tänkt att underlätta inspektionen av cacheinnehållet.<br />
I minnes-menyn kan följande göras:<br />
• Change. Ändring av minnesorganisation.<br />
• Contents. Inspektion av minnesinnehållet.<br />
Under change kan man ändra minnesbredden, dvs det antal (32-bitars) ord som kan överföras mellan cachen och<br />
huvudminnet i en minnesaccess. Man kan också ändra minnesaccesstiden.<br />
Minnesinnehållet kan studeras genom att välja Contents. Detta presenteras blockvis och uppdateras efter varje<br />
minnesoperation.<br />
Resultat av simuleringar<br />
Med en fjärde popup-meny, show-menyn, kan man få ut resultatet från en simulering. Denna popup-meny erhålls<br />
då mittersta musknappen trycks ned inom simulator-fönstret.<br />
I show-menyn kan följande göras:<br />
• Show Result.<br />
• Show Hitgraph, All<br />
• Show Hitgraph, Data<br />
• Show Hitgraph, Instr<br />
• Show Localitygraph, All<br />
• Show Localitygraph, Data<br />
• Show Localitygraph, Instr<br />
Show Result visar andel träffar, exekveringstid, antal minnesreferenser, andel skrivningar etc för senaste simuleringen.<br />
Show Hitgraph visar hur hit-ratio varierar med tiden (i antal minesreferenser) under exekveringen. Man kan välja<br />
att studera detta för alla minnesreferenser, endast data eller instruktioner.<br />
Show Localitygraph visar hur minnesreferenserna fördelar sig i adressrymden som funktion av tiden (i minnesreferenser).<br />
Även här kan man välja att studera alla, endast data eller instruktionsreferenser.<br />
Man kan få ut diagram och textutskrifter på skrivare genom att aktivera Hardcopy fältet i respektive fönster.<br />
För diagrammen måste man därefter aktivera Postscript och blankställa fältet med skrivarens namn. Allra sist<br />
aktiveras OK varvid diagrammet skrivs ut på laserskrivaren.<br />
Konstruktionsprinciper för cacheminne<br />
Lokalitetsprincipen<br />
En cacheminneshierarki består av ett litet snabbt minne (cacheminnet) och ett långsamt större minne (huvudminne).<br />
Genom att endast lagra de delar av huvudminnet som används ofta i cacheminnet, kommer de flesta minnesreferenser<br />
att kunna betjänas av cachen och vi får en skenbar accesstid som ligger mycket nära cacheminnets. Anledningen<br />
att denna enkla teknik fungerar bra beror på lokaliteten hos minnesreferenserna i adressrymden.<br />
Vi skall studera lokaliteten för två program. Det första programmet — example0 — finns längst bak i denna<br />
handledning. Programmet bestämmer en svit av Fibonaccital.<br />
Hemuppgift 2.1<br />
Studera assemblykoden för programmet example0.s och besvara nedanstående fråga<br />
Hur många (32-bitars) ord upptar for-loopen Ledning: Du finner adresserna i hexadecimal form längst till vänster<br />
i listan.<br />
Svar: _____________________________________________________________________________________<br />
——————————————————————————————————— Slut på hemuppgift 2.1<br />
Vi skall studera vilka adresser som refereras under exekveringen av detta program. Detta görs genom att studera<br />
den s.k. lokalitetsgrafen för programmet. I lokalitetsgrafen avsätts adressrymden längs y-axeln och tiden (räknat i<br />
minnesreferenser) längs x-axeln.<br />
5<br />
6
<strong>Laboration</strong> 2<br />
Med adressrymden för ett program menas storleken på det område som definieras av den lägsta och högsta adress<br />
som CPUn adresserar under exekveringen av programmet. Adressrymden definierar hur stort huvudminnet måste<br />
göras för att rymma programmet.<br />
Uppgift 2.1<br />
I katalogen /home/obelix/staff/ide/nesse/cache/ finns några algoritmer kodade i DLX-assemblyspråk.<br />
Ställ dig i hemmakatalogen. Dess filer, och några andra som inte finns där, kopieras till en underkatalog med<br />
namnet cache_lab genom kommandot:<br />
/home/obelix/staff/ide/nesse/bin/init_cache<br />
Förflytta Dig därefter till denna katalog och starta därefter cachesimulatorn med kommandot<br />
cache example0<br />
Exekvera programmet genom att peka på Go (till vänster) och samtidigt trycka ned vänster musknapp. Tag<br />
därefter upp lokalitetsgrafen för detta program genom att välja alternativet Show Localitygraph, All i popup-menyn<br />
som erhålls då mittersta musknappen trycks ned. Efter en stund ritas grafen ut i ett fönster på skärmen.<br />
Hur stor adressrymd i antal ord upptar programmet<br />
Svar: _____________________________________________________________________________________<br />
Hur många ord refereras (instruktioner och data) då for-loopen exekveras<br />
Svar: _____________________________________________________________________________________<br />
Hur stor andel av adressrymden refereras vid exekvering av for-loopen<br />
Svar: _____________________________________________________________________________________<br />
———————————————————————————————————— Slut på uppgift 2.1<br />
Vi skall nu studera referenslokaliteten för ett annat program, nämligen example1, som är en sorteringsalgoritm<br />
som finns listad längst bak i handledningen.<br />
Hemuppgift 2.2<br />
Studera C-programmet example1.c längst bak i handledningen och besvara följande frågor:<br />
Hur många gånger kommer then-satsen i den inre for-loopen att exekveras med aktuella värden på elementen i<br />
vektorn X<br />
Svar: _____________________________________________________________________________________<br />
Hur många varv kommer sista for-loopen att exekveras<br />
Svar: _____________________________________________________________________________________<br />
——————————————————————————————————— Slut på hemuppgift 2.2<br />
7<br />
<strong>Laboration</strong> 2<br />
Uppgift 2.2<br />
Gå ur simulatorn. Detta gör du genom att välja Quit i popup-menyn som erhålls då CPUn pekas ut och vänstra<br />
musknappen trycks ned.<br />
Starta simulatorn (cache example1) och exekvera programmet.<br />
Tag därefter upp lokalitetsgrafen för instruktionsreferenser för programmet (Show LocalityGraph, Instr) och besvara<br />
följande frågor:<br />
Hur stor adressrymd i antal ord upptar programmet<br />
Svar: _____________________________________________________________________________________<br />
Hur många ord (instruktioner) refereras då inre for-loopen (for2) exekveras<br />
Svar: _____________________________________________________________________________________<br />
Hur stor andel av adressrymden refereras vid exekvering av for2<br />
Svar: _____________________________________________________________________________________<br />
Hur många ord refereras då sista for-loopen exekveras<br />
Svar: _____________________________________________________________________________________<br />
Hur stor andel av adressrymden refereras vid exekvering av sista loopen<br />
Svar: _____________________________________________________________________________________<br />
Vad kan man säga om andelen av adressrymden som refereras i looparna i de båda programmen då man jämför<br />
detta med hela programmets totala adressrymd<br />
Svar: _____________________________________________________________________________________<br />
———————————————————————————————————— Slut på uppgift 2.2<br />
En intressant iakttagelse är de två faser som sorteringsprogrammet arbetar i. Den första motsvarar sorteringen och<br />
den andra kopieringen. Lägg märke till hur dessa faser visar sig i lokalitetsdiagrammet som två områden.<br />
Programmen du studerat har det gemensamt att de vid exekvering tillbringar mesta delen av tiden i loopar. Den<br />
andel av adressrymden som används av looparna i programmen är därför viktig att centralenheten kommer åt<br />
snabbt. Dessbättre är denna förhållandevis liten jämfört med programmets totala adressrymd, vilket är hemligheten<br />
bakom cacheteknikens prestandavinster.<br />
8
<strong>Laboration</strong> 2<br />
Cacheorganisationer och algoritmer<br />
I denna del av laborationen skall vi studera hur cacheminnen är organiserade och dess funktion. Som vi sett verkar<br />
det lovande att låta cachen vara liten i förhållande till huvudminnet och samtidigt uppnå att de flesta minnesreferenserna<br />
kan tas om hand av cachen utan inblandning av huvudminnet. Huvuduppgiften för cachekonstruktören är<br />
därför att implementera funktioner som ser till att de för tillfället mest refererade delarna av adressrymden ligger i<br />
cachen.<br />
Konstruktionsrymden för ett cacheminne är stor och omfattar följande viktiga punkter:<br />
• Cachestorlek<br />
• Adressavbildningssmetod (eng. address mapping method)<br />
• Utbytesalgoritm (eng. replacement algorithm)<br />
• Uppdateringstrategi (eng. write policy)<br />
Vi säger att en träff (eng. hit) erhålls om den information som refereras vid en skrivning eller läsning finns i cachen.<br />
Motsatsen till träff kallar vi miss. En träff kommer att hanteras på samma tid som klockcykeltiden för processorn<br />
(CPUn) medan en miss gör att pipelinen stoppas. Ett första ordningens mål för cachekonstruktören är därför att se<br />
till att medelaccesstiden blir så liten som möjlig. Som vi skall se är andelen träffar (eng. hit ratio) en viktig storhet<br />
att betrakta vid denna optimering.<br />
Cachestorlek<br />
Det är klart att desto större cachen är, desto större är sannolikheten att en träff uppstår vid en minnesreferens. För<br />
att få en hög andel träffar vid exekvering av ett program, är det en god approximation att välja cachen så stor att<br />
den rymmer de delar av adressrymden som refereras av den slinga som exekveras flest gånger.<br />
Uppgift 2.3<br />
Med ledning av de lokalitetsbetraktelser du gjorde i föregående avsnitt, besvara nedanstående fråga:<br />
Hur stor bör cachen väljas för att rymma den del av adressrymden som refereras i slingan i example0<br />
Svar: _____________________________________________________________________________________<br />
———————————————————————————————————— Slut på uppgift 2.3<br />
Adressavbildningsmetoder<br />
Eftersom en cache endast innehåller delar av huvudminnets innehåll, och eftersom processorn genererar minnesadresser<br />
är det viktigt att cachen avbildar minnesadresser på cachens minne enligt någon metod. Den metod som<br />
används kallas mängd-associativ avbildning (eng. set-associative mapping) och förklaras nedan.<br />
Cachen är indelad i ett antal mängder som består av ett antal block. Blocken i sin tur är indelade i ett antal 32-bitars<br />
ord. Minnesadressen är indelad i tre fält enligt Figur 2.3 med mest signifikant adressbit till vänster.<br />
Tag Index Offset<br />
Figur 2.3: Indelning av adressen vid mängd-associativ adressavbildning.<br />
9<br />
<strong>Laboration</strong> 2<br />
Avkodare<br />
0<br />
1<br />
2<br />
3<br />
Tag-minne Status Dataminne<br />
. . .<br />
Mängd 0, block 0<br />
Mängd 0, block 1<br />
Mängd 1, block 0<br />
Mängd 1, block 1<br />
Mängd 2, block 0<br />
Mängd 2, block 1<br />
Mängd 3, block 0<br />
Mängd 3, block 1<br />
=<br />
Multiplexer<br />
Index<br />
Träff/miss<br />
Tag<br />
Offset<br />
Figur 2.4: Adressavbildningsmekanism för en cache med 4 mängder och 2 block/mängd.<br />
Hur adressavbildningen går till för en cache med 4 mängder och 2 block/mängd framgår ur Figur 2.4. Index pekar<br />
ut aktuell mängd i cachen. Inom denna mängd jämförs tag-fältet med samtliga tag-fält för de block som finns lagrade<br />
i mängden. Om motsvarande block finns, erhålls det adresserade ordet genom att indexera inom blocket med<br />
offset-fältets värde. Om det inte finns hämtas blocket in från huvudminnet och motsvarande tag-fält uppdateras.<br />
Om samtliga block i den aktuella mängden är upptagna, måste något bytas ut. Olika kriterier för utbyten är tänkbara.<br />
Vi återkommer till dessa senare.<br />
Det finns två specialfall vid val av antal mängder. Det ena specialfallet innebär att antalet mängder är lika med<br />
antalet block. Denna avbildningsmetod kallas direkt-avbildning (eng. direct mapping). Det andra specialfallet fås<br />
om hela cachen motsvarar en mängd. Denna metod kallas fullt associativ avbildning (eng. fully associative mapping).<br />
Minnesadressen är i detta fall endast indelad i två fält enligt Figur 2.5.<br />
Tag Offest<br />
Figur 2.5: Indelning av adressen vid fullt associativ adressavbildning.<br />
Märk noga att CPUn måste kunna referera till 8-bitars ord (bytes). För att detta skall kunna vara möjligt, bestäms<br />
antalet adressbitar av log 2 N M , där N M är minnets storlek i antal bytes.<br />
Hemuppgift 2.3<br />
Besvara nedanstående frågor<br />
Uttryck cachestorleken (N C ) i antalet mängder (S) och blockstorlek (B) för en direkt-avbildande cache<br />
Svar: _____________________________________________________________________________________<br />
Antag att cachens storlek är 8 ord och blockstorleken är 1 ord. Ange antalet adressbitar i tag, index- och offsetfältet<br />
för en direkt-avbildande cache om huvudminnets storlek är 64 kord (64 x 1024 ord).<br />
Svar: _____________________________________________________________________________________<br />
10
<strong>Laboration</strong> 2<br />
Ange antalet adressbitar i tag-fältet för en fullt associativt avbildande cache med storleken 8 ord samt blockstorleken<br />
1 ord om huvudminnets storlek är 64 kord.<br />
Svar: _____________________________________________________________________________________<br />
——————————————————————————————————— Slut på hemuppgift 2.3<br />
Vi skall nu studera en direkt-avbildande cache genom att exekvera programmet example0.<br />
Uppgift 2.4<br />
Gå ur simulatorn och starta den med det första programmet (cache example0). Peka på cachen och tryck på<br />
vänster musknapp. Du får då upp en popup-meny i vilken du väljer Change. Du kan nu välja cacheorganisation.<br />
Välj cache-storlek enligt uppgift 2.3. Välj blockstorlek 1 samt antal mängder så att cachen blir direkt-avbildande.<br />
Ändra dock inga andra fält. Stäng därefter fönstret med Close .<br />
I Cache-menyn väljer du nu Contents som skapar ett fönster i vilket du kan studera cacheinnehållet.<br />
———————————————————————————————————— Slut på uppgift 2.4<br />
Varje rad i cachen mostvarar ett block. Till varje block hör en statusbit V, en tag samt blockinnehållet. V biten<br />
(Valid) anger om blocket innehåller giltig data (jfr. med Figur 2.4).<br />
Uppgift 2.5<br />
Gör nu reset och exekvera programmet stegvis genom att trycka på Step . Följ hela tiden med i programlistan<br />
så att du vet vilka instruktioner som exekveras. Fortsätt tills cachen fyllts. Tryck ytterligare en gång och notera<br />
noga vilket block som byts ut.<br />
Vilket block byts ut och varför<br />
Svar: _____________________________________________________________________________________<br />
Vilken instruktion hämtades in i cachen<br />
Svar: _____________________________________________________________________________________<br />
Fortsätt nu stegvis tills hela loopen ligger i cachen. Studera därefter cachens beteende genom att låta ett antal steg<br />
exekveras i halvfart. Detta gör du genom att skriva in ett antal (välj 32) i fältet No of steps. Tryck därefter på<br />
Visual . Cachen blinkar till vid träff och minnet vid miss.<br />
Det genereras två missar per varv i loopen. Vilka adresser motsvarar dessa<br />
Svar: _____________________________________________________________________________________<br />
Varför genereras missar vid just dessa adresser<br />
Svar: _____________________________________________________________________________________<br />
———————————————————————————————————— Slut på uppgift 2.5<br />
11<br />
<strong>Laboration</strong> 2<br />
Trots att hela adressrymden som loopen refererar till får plats i cachen erhålls missar. Detta beror på en svaghet<br />
hos direkt-avbildande cachar som går under benämningen konfliktmissar (eng. conflict misses) eller “bumps”.<br />
Utbytesalgoritmer<br />
Antalet konfliktmissar, dvs situationer där två minnesadresser konkurrerar om samma block i cachen, kan minskas<br />
genom att välja en mängd-associativ cache med färre antal mängder än antal block i cachen. Extremfallet motsvaras<br />
av fullt associativa cachar.<br />
För alla cachar som inte är direkt-avbildande är det inte självklart vilket block som skall bytas ut då man erhåller<br />
en cache-miss. Många algoritmer är tänkbara men måste förkastas pga att de ej går att implementera till rimlig kostnad.<br />
Vi skall studera tre utbytesalgoritmer, nämligen Random, FIFO och LRU.<br />
Vid Random (eller pseudo-random) väljs det block som skall bytas ut slumpmässigt. Denna algoritm kan approximeras<br />
med round-robin som är ganska lätt att implementera. I simulatorn är Random implementerad genom<br />
slumptalsdragning.<br />
Vid FIFO (First In First Out) bytes det block ut som funnits längst tid i cachen. Denna algoritm kan implementeras<br />
exakt genom att associera en räknare till varje block. Vid varje blockutbyte inkrementeras samtliga räknare. Det<br />
block vars räknare har högst värde byts ut. Räknarens storlek definieras av antalet block i setet. Nackdelen med<br />
denna algoritm är främst att det block som varit längst i cachen nödvändigtvis inte behöver vara det som är minst<br />
refererat.<br />
LRU (Least Recently Used) tar hänsyn till referensintensiteten till varje block. Man associerar en räknare till varje<br />
block. Räknaren nollställs då blocket refereras. Övriga räknare inkrementeras. Vid utbyte väljs det block vars räknare<br />
har högst värde. Räknaren kan teoretiskt behöva vara hur stor som helst. I praktiken räcker det med ett fåtal<br />
bitar (många implementeringar använder endast en bit). I simulatorn anges räknarens värde under R i fönstret med<br />
cachens innehåll.<br />
Val av utbytesalgoritm påverkar kostnaden för cachen på grund av de statusbitar som behövs för beslutsfunktionen.<br />
Uppgift 2.6<br />
Gör nu cachen i förra uppgiften fullt associativ och välj LRU som utbytesalgoritm. Exekvera tills cachen fyllts.<br />
Studera speciellt hur räknarnas värden förändras.<br />
Vilket block kommer att bytas ut vid nästa referens och varför Ledning: Studera räknarnas värde för de olika<br />
blocken<br />
Svar: _____________________________________________________________________________________<br />
Verifiera resultatet!<br />
Fortsätt nu tills hela loopen finns i cachen och exekvera sedan programmet i halvfart 32 steg.<br />
Vilken minnesoperation ger upphov till att både cachen och minnet blinkar<br />
Svar: _____________________________________________________________________________________<br />
Hur många missar genereras per varv och varför<br />
Svar: _____________________________________________________________________________________<br />
_________________________________________________________________________________________<br />
12
<strong>Laboration</strong> 2<br />
<strong>Laboration</strong> 2<br />
Exekvera programmet till slut genom att trycka på Go . Studera därefter statistiken för denna körning genom<br />
att välja alternativet Show result i popup-menyn som fås då mellersta musknappen trycks ned.<br />
Vilken andel träffar erhölls (hit ratio)<br />
Svar: _____________________________________________________________________________________<br />
Jämför detta med cachens storlek kontra storleken på programmets adressrymd (dvs huvudminnets storlek).<br />
———————————————————————————————————— Slut på uppgift 2.6<br />
Uppdateringsstrategier<br />
Den sista konstruktionsdetaljen vi skall studera har att göra med hur huvudminnet skall uppdateras. En metod går<br />
ut på att vid en skrivning uppdatera såväl cachen som huvudminnet s.k. write-through. Nackdelen med detta alternativ<br />
är att varje skrivning därmed tar tid. Ett annat alternativ är att endast uppdatera cachen. I detta fall kommer<br />
huvudminnet inte att innehålla det aktuella värdet varför blocket måste skrivas tillbaka i minnet vid utbyte. Denna<br />
strategi kallas copy-back och kräver att det finns en bit till varje block som anger om blocket skall skrivas tillbaka<br />
(D(irty)-bit). I simulatorn anges D-biten för varje block i fönstret med cachens innehåll under D.<br />
Det bör också nämnas att det finns olika strategier för när ett block skall hämtas in från huvudminnet. Antingen<br />
väljer man att alltid hämta in blocket vid en miss. Ett alternativ då write-through används är att aldrig hämta blocket<br />
vid skrivmissar utan istället uppdatera huvudminnet. Först vid en läsmiss hämtas blocket. I laborationen förutsätter<br />
vi att samtliga missar leder till att blocket hämtas in.<br />
Uppgift 2.7<br />
Vid förra exekveringen blinkade både cachen och minnet som följd av att vi har valt write-through. Ändra i cachemenyn<br />
cachen så att copy-back används och exekvera programmet i halvfart (64 steg).<br />
Vad blev resultatet vad beträffar minnestrafiken<br />
Svar: _____________________________________________________________________________________<br />
———————————————————————————————————— Slut på uppgift 2.7<br />
Cacheorganisationens inverkan på prestanda<br />
Denna del av laborationen tjänar till att förstå hur cacheorganisationen påverkar exekveringstiden för program.<br />
Prestandamodell<br />
Vi skall börja med att gå igenom en förenklad prestandamodell för ett datorsystem med cache och huvudminne. Vi<br />
inför följande beteckningar för olika egenskaper i systemet:<br />
• t CPU —Tiden från det att CPUn tagit emot svar från en minnesreferens tills nästa minnesreferens genereras.<br />
• t A1 — Accesstid för cacheminnet.<br />
• t A2 — Accesstid för minnet.<br />
• B — Blockstorlek i antal ord (32 bitar)<br />
• I — Minnesbredd, dvs hur många ord på konsekutiva adresser som kan överföras mellan cache och huvudminne<br />
i en minnes-cykel.<br />
t CPU utgör den tid det tar för centralenheten att bearbeta varje minnesreferens. Om minnesaccesstiden vore noll,<br />
skulle det ta Nt CPU att utföra N minnesreferenser.<br />
För varje minnesreferens som centralenheten genererar, finns ett antal olika utfall. Dels är första frågan om det<br />
kommer att uppstå en träff i cachen. Isåfall blir accesstiden samma som cachens, dvs t A1 .<br />
Om det uppstår en miss måste i bästa fall blocket läsas in från minnet vilket tar tiden t A2 B/I eftersom B ord måste<br />
överföras och I ord kan överföras samtidigt.<br />
Om copy-back används och det block som skall bytas ut är uppdaterat, måste det skrivas tillbaka vilket ger en ökning<br />
med t A2 B/I.<br />
Vid en skrivträff och då write-through används kan minnet uppdateras samtidigt som cachen varför tiden för denna<br />
operation är accesstiden för minnet, nämligen t A2 .<br />
I tabellen nedan presenteras tiden det tar för skrivningar och läsningar beroende på utfall och beroende på den uppdateringsstrategi<br />
som används. I hemuppgiften nedan skall du komplettera tabellen.<br />
Utfall<br />
Lästräff<br />
Läsmiss utan tillbakaskrivning<br />
Läsmiss med tillbakaskrivning<br />
Skrivträff — write through<br />
Skrivträff — copy back<br />
Skrivmiss — write through<br />
Skrivmiss — copy back, fall 1<br />
Skrivmiss — copy back, fall 2<br />
Hemuppgift 2.4<br />
Komplettera tabellen ovan och besvara följande frågor:<br />
Vilka två fall är möjliga vid skrivmiss då copy-back används<br />
Svar: _____________________________________________________________________________________<br />
Härled uttrycket för skrivmiss då write-through används.<br />
Formel<br />
t A1<br />
t A1 + t A2 B/I<br />
——————————————————————————————————— Slut på hemuppgift 2.4<br />
Exekveringstiden för ett program som genererar N 1 lästräffar, N 2 läsmissar, N 3 skrivträffar och N 4 skrivmissar för<br />
en cache som utnyttjar write-through är då<br />
T = N( t CPU<br />
+ ( 1 – W )t A1<br />
+ Wt A2<br />
+ ( 1 – H)t A2<br />
( B ⁄ I)<br />
)<br />
där N = N 1 + N 2 + N 3 + N 4 för en cache som utnyttjar write-through.<br />
Cachens organisation kan beskrivas med en fem-tipel O = < S, B, A, R, U >, där S = cachestorlek, B = blockstorlek,<br />
A = adressavbildningsmetod, R = utbytesalgoritm samt U = uppdateringsstrategi.<br />
t A2<br />
t A1<br />
t A2 B/I + t A2<br />
T = N 1<br />
t A1<br />
+ N 2<br />
( t A1<br />
+ t A2<br />
( B⁄<br />
I)<br />
) + N 3<br />
t A2<br />
+ N 4<br />
( t A2<br />
( B⁄<br />
I) + t A2<br />
)<br />
(2.1)<br />
Andelen träffar betecknas med H. För exemplet ovan gäller att H = ( N 1<br />
+ N 3<br />
) ⁄ ( N 1<br />
+ N 2<br />
+ N 3<br />
+ N 4<br />
) . Om<br />
andelen skrivningar är W så gäller att<br />
(2.2)<br />
13<br />
14
<strong>Laboration</strong> 2<br />
I den förenklade prestandamodellen har vi inte tagit hänsyn till inverkan av cacheorganisationen på hit-ratio och<br />
accesstid. I själva verket beror hit-ratio på cacheorganisationen och programbeteendet, P. H är således en funktion<br />
av dessa, dvs H = H( O, P ). Vidare gäller att accesstiden för cachen beror av cacheorganisationen, dvs<br />
A 1 = A 1 ( O ). Eftersom det inte finns något icke-trivialt analytiskt uttryck för dessa funktioner, är enda sättet att via<br />
experiment studera inverkan av cacheorganisationen och programbeteendet på dessa.<br />
Låt oss nu studera hur hit-ratio varierar i tiden under det att ett program exekveras.<br />
Uppgift 2.8<br />
Starta simulatorn med programmet example1. Välj en direktavbildande cache med 64 ord och 2 ord/block. Exekvera<br />
programmet i full fart (med Go ). Tag därefter upp show-menyn (mittersta musknappen) och välj alternativet<br />
Show Hitgraph, All. Efter en stund kommer ett diagram upp. I diagrammet ser man hur hit-ratio varierar<br />
med tiden. Tag även upp lokalitetsgrafen för instruktionsreferenser.<br />
Förklara varför hit-ratio till en början är mycket låg<br />
Svar: _____________________________________________________________________________________<br />
_________________________________________________________________________________________<br />
Vad beror variationerna i hit-ratio i mitten av grafen på<br />
Svar: _____________________________________________________________________________________<br />
Varför sjunker hit-ratio i slutet Ledning: Studera programlistan<br />
Svar: _____________________________________________________________________________________<br />
———————————————————————————————————— Slut på uppgift 2.8<br />
Cachestorlekens inverkan på hit-ratio<br />
Vi skall nu studera cachestorlekens inverkan på hit-ratio.<br />
Uppgift 2.9<br />
Ändra cachens organisation enligt följande. Välj en direktavbildande cache på 16 ord som utnyttjar write-through<br />
och med blockstorleken 1 ord.<br />
Vi skall bara studera instruktionsreferenser. Vi väljer därför en cache som endast cachar instruktioner. Välj därför<br />
Cache Type = Instr. cache i samma meny som du väljer övriga cache parametrar.<br />
Exekvera programmet i full fart. Tag därefter upp Show result och fyll i uppgifterna i tabellen nedan. Gör om samma<br />
mätningar för de cachestorlekar som finns upptagna i tabellen. Se hela tiden till att du har en direkt-avbildande<br />
cache. Rita in mätpunkterna i diagrammet och besvara därefter frågorna nedan.<br />
S (cachestorlek) H (total hit-ratio)<br />
16<br />
32<br />
64<br />
128<br />
15<br />
<strong>Laboration</strong> 2<br />
H<br />
1.0<br />
0.8<br />
0.6<br />
0.4<br />
0.2<br />
S<br />
16 32 64 128<br />
Studera diagrammet du upprättat.<br />
Vid en viss cachestorlek ger ytterligare ökning av storleken endast marginell ökning av hit-ratio. Vilken storlek<br />
avses<br />
Svar: _____________________________________________________________________________________<br />
Vilken hit-ratio erhålls vid denna cachestorlek<br />
Svar: _____________________________________________________________________________________<br />
Jämför cachestorleken med den adressrymd som refereras av den inre for-loopen (se uppgift 2.2). Kommentar<br />
Svar: _____________________________________________________________________________________<br />
———————————————————————————————————— Slut på uppgift 2.9<br />
Blockstorlekens inverkan på hit-ratio<br />
Uppgift 2.10<br />
Använd samma program som tidigare (example1). Välj en direkt-avbildande cache som utnyttjar write-through.<br />
Låt cachen vara 32 ord i storlek.<br />
Vi skall nu låta vår cache lagra såväl data som instruktioner. Välj därför Cache type = Cache.<br />
Ställ in cachens accesstid till 10 ns, minnets accesstid till 100 ns och minnesbredden till 1. CPUns klockcykeltid<br />
(t CPU ovan) skall vara 10 ns.<br />
16
<strong>Laboration</strong> 2<br />
Börja med en blockstorlek lika med 1 ord och kör programmet i full fart. Tag därefter upp Show result och fyll i<br />
uppgifterna i tabellen nedan. Gör om samma mätningar för de blockstorlekar som finns upptagna i tabellen och<br />
besvara frågorna.<br />
B H I H D H T<br />
1<br />
2<br />
4<br />
8<br />
16<br />
• B — Blockstorlek i antal ord<br />
• H I — Hit-ratio för instruktioner<br />
• H D — Hit-ratio för data<br />
• H — Total hit-ratio<br />
• T — Exekveringstiden för programmet i µs<br />
Hur stor är andelen skrivningar (W)<br />
Svar: _____________________________________________________________________________________<br />
Hur många referenser genererar programmet (N)<br />
Svar: _____________________________________________________________________________________<br />
Vilken typ av information (instruktioner eller data) ger högst andel träffar Förklaring<br />
Svar: _____________________________________________________________________________________<br />
_________________________________________________________________________________________<br />
Vid vilken blockstorlek uppnås högst andel träffar<br />
Svar: _____________________________________________________________________________________<br />
Varför minskar andelen träffar därefter<br />
Svar: _____________________________________________________________________________________<br />
Trots att andelen träffar ökar så ökar exekveringstiden. Varför Ledning: Studera ekvation 2.2.<br />
Svar: _____________________________________________________________________________________<br />
_________________________________________________________________________________________<br />
17<br />
<strong>Laboration</strong> 2<br />
Beräkna exekveringstiden för en blockstorlek på 1 ord genom att sätta in aktuella värden på storheterna i ekvation<br />
2.2. Jämför detta med exekveringstiden i tabellen.}<br />
Svar: _____________________________________________________________________________________<br />
———————————————————————————————————— Slut på uppgift 2.10<br />
Minnesbreddens inverkan på exekveringstiden<br />
Minnesbredden anger hur många ord som kan överföras mellan cachen och minnet vid blocköverföringar. För att<br />
dra nytta av den minskade andelen träffar vid ökad blockstorlek, bör minnesbredden väljas lika med blockstorleken.<br />
Uppgift 2.11<br />
Gör om mätningarna i föregående uppgift för blockstorlekarna i tabellen nedan men med samma minnesbredd som<br />
blockstorlek.<br />
B H T<br />
1<br />
2<br />
4<br />
Hur förändras nu exekveringstiden med total hit-ratio<br />
Svar: _____________________________________________________________________________________<br />
Vilken är den minsta exekveringstid som uppmäts<br />
Svar: _____________________________________________________________________________________<br />
———————————————————————————————————— Slut på uppgift 2.11<br />
Adressavbildningsmetodernas inverkan på hit-ratio<br />
Vi skall nu studera hur antalet mängder inverkar på hit-ratio för cachesystemet. Som vi såg kunde vi totalt eliminera<br />
de missar som uppstod som följd av konfliktmissar genom att göra cachen fullt associativ. I praktiken är det kostsamt<br />
att implementera cachar fullt associativa varför man nöjer sig med mängd-associativ adressavbildning.<br />
Uppgift 2.12<br />
Gör om mätningarna i föregående uppgift med cachesize = 32 ord, blockstorleken 4 ord och med de antal mängder<br />
som anges i tabellen nedan. Använd FIFO som utbytesalgoritm.<br />
S H<br />
8<br />
4<br />
2<br />
1<br />
18
<strong>Laboration</strong> 2<br />
Förklaring till beteckningar:<br />
• S — Antal mängder<br />
• H — Total hit-ratio<br />
Hur förändras hit-ratio med minskat antal mängder<br />
Svar: _____________________________________________________________________________________<br />
Vid vilket antal mängder uppnås högst hit-ratio<br />
Svar: _____________________________________________________________________________________<br />
Hur stor är skillnaden mellan högsta och lägsta hit-ratio<br />
Svar: _____________________________________________________________________________________<br />
Vilken slutsats drar du om storleken på inverkan av antalet mängder på hit-ratio<br />
Svar: _____________________________________________________________________________________<br />
———————————————————————————————————— Slut på uppgift 2.12<br />
En slutsats av denna mätning är att det inte lönar sig att ha så många block per mängd. I praktiken visar det sig att<br />
2 till 4 block per mängd ger en ökning av hit-ratio. Därefter är ökningen marginell. Med tanke på att implementeringskostnaden<br />
ökar markant då vi ökar associativiteten (ökning av antal block per mängd), skall prestandahöjningen<br />
vara markant för att det skall löna sig.<br />
Utbytesalgoritmernas inverkan på hit-ratio<br />
Uppgift 2.13<br />
Undersök skillnaderna i hit-ratio för de olika utbytesalgoritmerna med samma cache och blockstorlek som i föregående<br />
uppgift samt med 4 block/mängd. Fyll i tabellen nedan.<br />
H Random H FIFO H LRU<br />
Hur stor är skillnaden i hit-ratio mellan Random och LRU<br />
Svar: _____________________________________________________________________________________<br />
Hur stor är skillnaden i hit-ratio mellan FIFO och LRU<br />
Svar: _____________________________________________________________________________________<br />
19<br />
<strong>Laboration</strong> 2<br />
Vilken slutsats drar du om storleken på utbytesalgoritmens inverkan på hit-ratio<br />
Svar: _____________________________________________________________________________________<br />
———————————————————————————————————— Slut på uppgift 2.13<br />
Uppdateringsstrategiernas inverkan på exekveringstiden<br />
I prestandamodellen såg vi att uppdateringsstrategin påverkar exekveringstiden hos programmet. Vi skall studera<br />
dess inverkan på sorteringsprogrammet example1.<br />
Uppgift 2.14<br />
Välj en fullt associativ cacheorganisation med storlek 32 ord, blockstorlek 4 ord samt LRU. Mät exekveringstiden<br />
för programmet med olika minnesbredder för copy-back och write-through enligt tabellen nedan.<br />
I T write-through T copy-back<br />
1<br />
2<br />
4<br />
För vilken minnesbredd är write-through bättre än copy-back och varför<br />
Svar: _____________________________________________________________________________________<br />
_________________________________________________________________________________________<br />
Hur mycket kortare blir exekveringstiden för copy-back jämfört med write-through i bästa fallet<br />
Svar: _____________________________________________________________________________________<br />
———————————————————————————————————— Slut på uppgift 2.14<br />
Anm. Det bör noga påtalas att vi i vår prestandamodell antagit att CPUn måste vänta tills varje skrivning har genomförts<br />
då write-through används. I praktiska implementeringar använder man skrivbuffertar som gör det möjligt<br />
för CPUn att fortsätta efter att en skrivning utförts. Detta betyder att prestanda för write-through är avsevärt bättre<br />
än vad dessa siffror visar.<br />
Uppgift 2.15<br />
Du skall nu exekvera samma program med den cacheorganisation som du kommit fram till ger bäst exekveringstid<br />
och besvara följande frågor.<br />
Hur lång exekveringstid får du<br />
Svar: _____________________________________________________________________________________<br />
Tag nu bort cachen genom att ändra fältet Cache type till No cache. Exekvera därefter programmet.<br />
20
<strong>Laboration</strong> 2<br />
<strong>Laboration</strong> 2<br />
Hur lång exekveringstid får du nu<br />
Svar: _____________________________________________________________________________________<br />
Hur många gånger längre blir exekveringstiden utan cache<br />
Svar: _____________________________________________________________________________________<br />
———————————————————————————————————— Slut på uppgift 2.15<br />
Cacheorganisationens inverkan på accesstiden för cachen<br />
I ovanstående mätningar har vi inte tagit hänsyn till att cacheorganisationen påverkar accesstiden för cachen. Sambandet<br />
mellan accesstiden och organisationen är icke-trivialt. Vi skall dock nämna några generella egenskaper.<br />
I allmänhet gäller att desto större ett minne är desto längre accesstid har det. Detta beror på att adressavkodningsmekanismen<br />
har större grinddjup och ger därför längre fördröjning.<br />
Adresseringen av ett mängd-associativt cacheminne tillgår så att index först adresserar aktuellt set. Därefter sker<br />
en associativ sökning av det block inom setet som överensstämmer med tag-fältet. Allra sist sker en adressering av<br />
ordet inom blocket med hjälp av offset.<br />
Den tid det tar att adressera sig till setet och till ordet är vanligtvis proportionell mot logaritmen på antalet mängder<br />
resp. blockstorleken. Den associativa sökningen är proportionell mot antalet block/mängd.<br />
Vi har begränsat minnesbredden och antalet block/mängd för att göra uppgiften mer realistisk. Ett brett minne är<br />
kostsamt i ett verkligt system eftersom det bestämmer bussvidden mellan cachen och minnet. Vidare är stora associativa<br />
minnen dyrbara. I praktiska implementeringar brukar man därför sällan använda sig av mer än 4 block/<br />
mängd.<br />
Utnyttja allt du lärt dig och lek med simulatorn så mycket du orkar och tycker är kul.<br />
———————————————————————————————————— Slut på uppgift 2.16<br />
Vi sammanfattar nu vad du skall ha lärt dig i laborationen. Fundera igenom punkterna nedan och kontakta din handledare.<br />
• Programlokalitetens inverkan på hit-ratio.<br />
• Funktionen hos de olika cacheminnesorganisationerna.<br />
• Cachestorelekens inverkan på hit-ratio och exekveringstid.<br />
• Blockstorlekens inverkan på hit-ratio och exekveringstid.<br />
• Minnesbreddens inverkan på hit-ratio och exekveringstid.<br />
• Adressavbildningsmetodens inverkan på hit-ratio och exekveringstid.<br />
• Utbytesalgoritmernas inverkan på hit-ratio och exekveringstid.<br />
• Uppdateringsstrategiernas inverkan på hit-ratio och exekveringstid.<br />
I denna del av laborationen skall du med hjälp av ett förenklat uttryck för accesstiden välja den cache organisation<br />
som ger bäst prestanda.<br />
Förutsättnigar<br />
Vi antar att accesstiden endast påverkas av cachestorleken (S) enligt följande uttryck där tiden anges i nanosekunder<br />
(ns):<br />
t A1<br />
= 7log 2<br />
S<br />
(2.3)<br />
Det finns en speciell funktion som ger dig accesstiden för cachen enligt ekvation 2.3 ovan. Denna erhålls genom<br />
att välja Auto access time i cache menyn.<br />
Uppgift 2.16 Extra<br />
Finn den cache med nedanstående förutsättningar som ger kortast exekveringstid för programmet example2, som<br />
utför matrisaddition, och som finns listad längst bak.<br />
Förutsättnigar:<br />
• Auto access time On<br />
• CPUns klockcykeltid är 10 ns<br />
• Minnets accesstid är 100 ns<br />
• Maximal minnesbredd är 4<br />
• Maximalt antal block/mängd är 4<br />
21<br />
22
<strong>Laboration</strong> 2<br />
<strong>Laboration</strong> 2<br />
Programlistor<br />
Programlista för “example0.c” och “example0.s”<br />
Beräkning av Fibonacci tal<br />
main(int argc, char **argv)<br />
{<br />
int x0, x1, x2, temp, i;<br />
}<br />
x0 = 1;<br />
x1 = 1;<br />
for (i = 0; i < 10; i++) {<br />
temp = x0 + x1;<br />
x0 = x1;<br />
x1 = temp;<br />
x2 = temp;<br />
}<br />
Assemblykod för DLX<br />
0000 addi r1,r0,#1 ; x0=1;<br />
0004 addi r2,r0,#1 ; x1=1;<br />
0008 addi r5,r0,#x2 ;<br />
000C addi r3,r0,#10 ; i=10;<br />
0010 L1: add r4,r1,r2 ; temp:=x0+x1;<br />
0014 add r1,r0,r2 ; x0:=x1;<br />
0018 add r2,r0,r4 ; x1:=temp;<br />
001C sw 0(r5),r4 ; x2:=temp;<br />
0020 subi r3,r3,#1<br />
0024 bnez r3,L1 ; then branch L1<br />
0028 nop<br />
002C trap #0<br />
0030 x2:<br />
Programlista för “example1.c”<br />
The bubblesort algorithm<br />
main(int argc, char **argv)<br />
{<br />
int x[10], y[10];<br />
int i, j, temp;<br />
}<br />
for (i = 0; i < 10; i++)<br />
x[i] = 10 - i;<br />
for (i = 0; i < 9; i++) {<br />
for (j = 9; j > i; j--) {<br />
if (x[j] < x[j - 1]) {<br />
temp = x[j - 1];<br />
x[j - 1] = x[j];<br />
x[j] = temp;<br />
}<br />
}<br />
}<br />
for (i = 0; i < 10; i++)<br />
y[i] = x[i];<br />
Programlista för “example2.c”<br />
Matrix addition algorithm<br />
main(int argc, char **argv)<br />
{<br />
int A[10][10], B[10][10], C[10][10];<br />
int i, j;<br />
}<br />
for (i = 0; i < 10; i++) {<br />
for (j = 0; j < 10; j++)<br />
C[i][j] = A[i][j] + B[i][j];<br />
}<br />
23<br />
24