25.12.2014 Views

Laboration 2

Laboration 2

Laboration 2

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!