- Leren
- Informatica & ICT
- Informatica
- Computerarchitectuur: processors, geheugen en prestaties
- Geheugenhiërarchie en caches
Geheugenhiërarchie en caches
GemiddeldLes 5 van 6 in Cursus Computerarchitectuur: processors, geheugen en prestaties
Wat je leert
- Beschrijf hoe programma's gegevens en code opnieuw gebruiken, vergelijk de geheugentechnologieën die deze opslaan en leg uit hoe snelle kleine niveaus en langzame grote niveaus samenwerken.
- Herken temporele en ruimtelijke lokaliteit in programma'sHerken de twee soorten lokaliteit bij toegang tot code en gegevens en leg uit waarom een klein, snel geheugen daardoor de meeste toegangen kan afhandelen.
- Vergelijk SRAM, DRAM en flashgeheugenBeschrijf hoe SRAM, DRAM en flash bits opslaan en vergelijk hun snelheid, dichtheid, kosten per bit, vluchtigheid en gebruikelijke plaats in de hiërarchie.
- Beschrijf hoe de niveaus van de geheugenhiërarchie samenwerkenBenoem de niveaus van registers tot opslag, gebruik de termen voor treffers en missers en leg uit hoe de hiërarchie de illusie van een groot, snel geheugen geeft.
- Herken temporele en ruimtelijke lokaliteit in programma's
- Gebruik de velden voor adrestag, index en offset van een adres om een blok te vinden, volg reeksen toegangen en vergelijk cacheorganisaties van direct afgebeeld tot volledig associatief.
- Splits een adres op in adrestag, index en offsetBereken de veldgroottes van een direct afgebeelde cache uit de capaciteit en blokgrootte, verdeel een adres in zijn velden en bereken hoeveel opslagruimte de cache nodig heeft.
- Volg geheugentoegangen door een direct afgebeelde cacheVolg een reeks adressen door een kleine direct afgebeelde cache, noteer elke treffer of misser en de inhoud van de cache en herken blokken die elkaar verdringen.
- Gebruik set-associatieve en volledig associatieve cachesZoek blokken in n-weg set-associatieve en volledig associatieve caches, kies met een vervangingsstrategie een te vervangen blok en weeg lagere misserfracties af tegen hardwarekosten en cachetoegangstijd.
- Splits een adres op in adrestag, index en offset
- Beschrijf wat er bij een misser gebeurt, deel missers in naar oorzaak, leg het verband tussen cachegrootte, blokgrootte, associativiteit en misserfractie en vergelijk hoe caches schrijfbewerkingen afhandelen.
- Handel cachemissers af en deel ze in naar oorzaakBeschrijf de stappen bij een cachemisser, deel missers in als eerste-toegangs-, capaciteits- of conflictmissers en leg uit hoe cachegrootte, blokgrootte en associativiteit elk type beïnvloeden.
- Vergelijk schrijfstrategieën voor cachesLeg uit hoe caches met direct doorschrijven en terugschrijven het geheugen actueel houden, wat schrijfbuffers en wijzigingsbits doen en hoe cachetoewijzing en geen cachetoewijzing bij een schrijfmisser werken.
- Handel cachemissers af en deel ze in naar oorzaak
- Bereken trefferfracties, de gemiddelde geheugentoegangstijd en geheugenwachtcycli, verwerk die in de CPI en uitvoeringstijd en analyseer systemen met meerdere cacheniveaus.
- Bereken de trefferfractie en de gemiddelde geheugentoegangstijdBereken treffer- en misserfracties en de gemiddelde geheugentoegangstijd van een cache, ook bij een combinatie van instructie- en gegevenstoegangen, en gebruik die om ontwerpen te vergelijken.
- Verwerk geheugenwachtcycli in de CPI en de uitvoeringstijdVoeg geheugenwachtcycli toe aan de CPU-prestatieformule, bepaal hoeveel een cache een programma kost en leg uit waarom snellere processors meer last hebben van langzaam geheugen.
- Analyseer caches met meerdere niveausLeg uit waarom processors meerdere cacheniveaus gebruiken, onderscheid lokale en globale misserfracties en bereken de gemiddelde geheugentoegangstijd en CPI voor hiërarchieën met twee en drie niveaus.
- Bereken de trefferfractie en de gemiddelde geheugentoegangstijd
- Beschrijf hoe virtuele adressen met een paginatabel naar fysieke adressen worden vertaald, waarom een paginafout een door het besturingssysteem afgehandelde misser is en hoe de TLB de vertaling versnelt.
- Vertaal een virtueel adres met een paginatabelLeg uit wat virtueel geheugen biedt, splits een virtueel adres in paginanummer en offset, vertaal het via een paginatabelitem en beschrijf wat er bij een paginafout gebeurt.
- Versnel adresvertaling met een TLBLeg uit hoe de TLB vertalingen in een cache bewaart, volg een toegang door de TLB, paginatabel en cache en bekijk hoe cachetoegang en vertaling overlappen.
- Vertaal een virtueel adres met een paginatabel
- Organiseer lussen en gegevensstructuren zodat programma's de geheugenhiërarchie goed gebruiken en pas blokgewijze verwerking en vooraf ophalen toe om gegevens opnieuw te gebruiken terwijl ze in de cache staan.
- Orden lussen en gegevens voor een goede lokaliteitOrden lussen volgens de opslagvolgorde van arrays, voorkom nadelige stapgroottes en kies gegevensindelingen die alleen bruikbare gegevens in de cache brengen.
- Verdeel berekeningen in blokken en haal gegevens vooraf opDeel lussen opnieuw in blokken die tijdens hergebruik in de cache blijven, kies een blokgrootte en leg uit hoe hardware en software geheugenlatentie verbergen door gegevens vooraf op te halen.
- Orden lussen en gegevens voor een goede lokaliteit
Geheugenhiërarchie en caches: uitleg
1Leg uit waarom computers een geheugenhiërarchie gebruiken
Programma's gebruiken een klein deel van hun code en gegevens herhaaldelijk. Dat hergebruik verklaart waarom een kleine cache de meeste toegangen kan afhandelen, ook als het hele programma veel groter is. Bekijk het verschil tussen hergebruik in de tijd en nabijgelegen adressen, vergelijk de cellen achter SRAM, DRAM en flash en verbind deze technologieën met treffers, missers en overdrachten door de hiërarchie. Hetzelfde toegangspatroon bepaalt later of een cacheontwerp of een aanpassing van een lus helpt.
1.1 Hoe programma's gegevens in elkaars nabijheid opnieuw gebruiken
Een cache werkt omdat de volgende geheugentoegang vaak verband houdt met een recente toegang. Gedurende een korte periode gebruiken de meeste programma's slechts een klein deel van hun adresruimte. Dit patroon heet lokaliteit. Een cache houdt dat actieve deel dicht bij de processor, waar toegangen snel kunnen worden afgehandeld.
Hergebruik in tijd en ruimte
Temporele lokaliteit betekent dat een gegeven kort na een toegang opnieuw wordt gebruikt. Een lus haalt herhaaldelijk de instructies van zijn lichaam op. Een lopend totaal wordt vaak gelezen en bijgewerkt. Door die gegevens beschikbaar te houden, hoeven ze niet opnieuw uit een langzamer niveau te worden opgehaald.
Ruimtelijke lokaliteit betekent dat gegevens op nabijgelegen adressen worden aangesproken. Bij het doorlopen van een array worden aangrenzende elementen gelezen en bij code zonder sprongen worden opeenvolgende instructies opgehaald. Een cache benut dit door bij een misser een heel blok, ook cachelijn genoemd, op te halen. Nabijgelegen bytes komen aan voordat het programma erom vraagt.
Deze patronen kunnen samengaan. De instructies van een lus liggen naast elkaar en worden herhaaldelijk uitgevoerd, dus heeft de instructiestroom zowel ruimtelijke als temporele lokaliteit. Een array-element dat precies één keer wordt gelezen, wordt niet temporeel hergebruikt, ook al heeft de doorloop van de omringende array ruimtelijke lokaliteit.
Tel blokken bij het doorlopen van een array
Bekijk deze C-lus met gehele getallen van 4 bytes en cacheblokken van 64 bytes:
for (int i = 0; i < 1000; i++) {
sum += a[i];
}
Een blok bevat gehele getallen. De array neemt bytes in. Als het eerste element op een blokgrens ligt, raakt de doorloop blokken: 62 volledige blokken en één gedeeltelijk blok.
In een aanvankelijk lege cache zonder vooraf ophalen of verstoring levert de eerste toegang tot elk blok een misser op. De overige elementen in dat blok leveren treffers op. De array veroorzaakt dus 63 missers bij 1000 toegangen, of ongeveer 6,3%. Als je één misser per element telt, zie je alle bruikbare naburige gegevens over het hoofd die met elke misser worden opgehaald.
De bronvariabelen sum en i worden vaak opnieuw gebruikt. Een compiler houdt ze echter meestal in registers, zodat hun hergebruik op bronniveau niet per se toegangen tot de gegevenscache oplevert. Analyseer bij het schatten van cacheverkeer de geheugentoegangen die het gecompileerde programma uitvoert.
De werkverzameling moet passen en samen bewaard kunnen worden
De werkverzameling is de verzameling blokken die tijdens een gekozen tijdvenster wordt gebruikt. Als ze in de cache passen en de plaatsingsregels toestaan dat ze samen worden bewaard, leveren herhaalde toegangen na het eerste laden meestal treffers op. Het tijdvenster is van belang: een heel programma kan enorm zijn terwijl één actieve lus slechts enkele blokken gebruikt.
Capaciteit alleen is niet genoeg. Twee veelgebruikte blokken kunnen op één direct afgebeelde positie worden afgebeeld en elkaar verdringen terwijl andere posities leeg blijven. Een werkverzameling kan dus qua aantal bytes passen en toch niet in de cache blijven.
Verspreide knooppunten van een gekoppelde lijst en willekeurige opvragingen in een grote hashtabel hebben vaak weinig ruimtelijke lokaliteit. Ook een kolomdoorloop van een rijgewijs opgeslagen array slaat veel naburige elementen over. Deze patronen halen bytes binnen die mogelijk ongebruikt blijven voordat ze worden verdrongen. Hardware benut de lokaliteit van het toegangspatroon; door de indeling of doorloop van het programma te veranderen, kun je een groter deel van elk opgehaald blok bruikbaar maken.
Belangrijkste punten
- Temporele lokaliteit gebruikt een gegeven opnieuw; ruimtelijke lokaliteit spreekt nabijgelegen adressen aan.
- Door een heel blok op te halen leveren latere toegangen tot nabijgelegen bytes treffers op.
- Een werkverzameling moet binnen de capaciteit passen en volgens de plaatsingsregels van de cache samen kunnen worden bewaard.
- Bronvariabelen die in registers worden bewaard veroorzaken geen toegangen tot de gegevenscache.
1.2 Geheugencellen, overdrachten en afwegingen
Bij geheugentechnologieën worden snelheid, dichtheid, kosten en behoud van gegevens tegen elkaar afgewogen. De processor heeft snelle toegang tot een kleine hoeveelheid gegevens nodig en betaalbare ruimte voor veel meer. SRAM, DRAM en flash voorzien elk in een ander deel van die behoefte.
Vergelijk de cellen
| Technologie | Hoe een bit wordt opgeslagen | Verversing en stroom | Belangrijkste rol |
|---|---|---|---|
| SRAM | Een stabiele schakeling, doorgaans zes transistors | Geen verversing; verliest gegevens zonder stroom | Caches op de chip |
| DRAM | Lading op een condensator, bereikbaar via een transistor | Periodieke verversing; verliest gegevens zonder stroom | Hoofdgeheugen |
| NAND-flashgeheugen | Een niet-vluchtige cel waarvan de toestand elektrisch wordt geprogrammeerd | Bewaart gegevens zonder stroom; beperkt aantal schrijfbewerkingen | Opslag |
Een SRAM-cel is snel maar neemt aanzienlijk oppervlak in, waardoor SRAM relatief duur per bit is. DRAM-cellen zijn kleiner, zodat DRAM meer capaciteit biedt tegen lagere kosten per bit. Hun lading lekt weg. Bij verversing worden rijen binnen een vast tijdvenster gelezen en hersteld; DDR4 gebruikt bij normale temperatuur een venster van 64 ms. “Statisch” in SRAM betekent geen verversing, niet dat gegevens na stroomuitval bewaard blijven.
Waarom de DRAM-toegangstijd varieert
DRAM is ingedeeld in banken, met rijen en kolommen in elke bank. Bij het activeren van een rij wordt die naar een rijbuffer gekopieerd. Lees- en schrijfbewerkingen selecteren vervolgens kolommen uit die open rij. Om een andere rij in dezelfde bank te openen, moet de bank eerst worden voorgeladen. Bij toegang tot een al open rij is dat wisselen van rij niet nodig.
Opeenvolgende kolommen kunnen in een burst worden overgedragen, wat geschikt is voor het ophalen van een cacheblok. Door verzoeken over banken en kanalen te verdelen kunnen overdrachten overlappen. DDR-geheugen draagt gegevens over op beide klokflanken. Deze eigenschappen verhogen de snelheid waarmee gegevens worden geleverd zonder de wachttijd op de eerste gegevens weg te nemen.
Onderscheid latentie en bandbreedte
Latentie is de vertraging totdat de eerste gegevens aankomen. Bandbreedte is de hoeveelheid die per tijdseenheid wordt overgedragen. Een interface met hoge bandbreedte kan nog steeds een lange initiële vertraging hebben.
Een DDR5-4800-kanaal met een gezamenlijk datapad van 64 bits draagt bijvoorbeeld 8 bytes per overdracht over. De pieksnelheid is bytes/s, of 38,4 GB/s. De aanhoudende bandbreedte voor een applicatie kan lager zijn doordat opdrachten, rijwisselingen en ander werk tijd kosten.
Als een verzoek 60 ns wacht en daarna een blok van 64 bytes ontvangt met 16 GB/s, is de overdrachtssnelheid 16 bytes/ns. De overdracht duurt ns, wat in totaal ongeveer 64 ns geeft. Alleen de bandbreedte verbeteren verkort het deel van 4 ns, niet de eerste 60 ns.
Flash bewaart gegevens maar schrijft anders
NAND-flashgeheugen leest en programmeert pagina's van enkele KiB. Om een geprogrammeerde pagina opnieuw te gebruiken, moet het grotere wisblok met vele pagina's worden gewist. Pagina's lezen duurt doorgaans tientallen microseconden, programmeren honderden microseconden tot enkele milliseconden en wissen milliseconden.
Programmeer- en wiscycli laten cellen slijten. Compact flashgeheugen met meerdere bits per cel ondersteunt vaak enkele duizenden cycli, terwijl cellen met één bit er ongeveer 100.000 kunnen ondersteunen. Controllers gebruiken slijtageverdeling om schrijfbewerkingen over blokken te spreiden.
Ter vergelijking: een SRAM-toegang duurt ongeveer 1 ns, DRAM ongeveer 50–100 ns, NAND lezen ongeveer 25–100 µs en een schijftoegang ongeveer 5–10 ms. Werkelijke apparaten verschillen. De hiërarchie combineert deze technologieën omdat één technologie hun voordelen in snelheid, capaciteit en prijs niet tegelijk kan bieden.
Belangrijkste punten
- SRAM en DRAM zijn vluchtig; flash bewaart gegevens zonder stroom.
- DRAM-verversing herstelt weglekkende lading, terwijl rijbuffers en bursts de toegang efficiënter maken.
- Latentie meet de initiële wachttijd; bandbreedte meet de overdrachtssnelheid.
- Flash programmeert pagina's en wist grotere blokken.
- Slijtageverdeling spreidt de slijtage door programmeren en wissen over flashblokken.
1.3 Volg een toegang door de hiërarchie
De geheugenhiërarchie plaatst kleine, snelle opslag dicht bij de processor en steeds grotere opslag verder weg. Dankzij lokaliteit kunnen de kleine niveaus een groot deel van de verzoeken afhandelen, terwijl de lagere niveaus capaciteit bieden.
Niveaus en overdrachtseenheden
Een typisch pad loopt via registers, L1, L2, L3, hoofdgeheugen en opslag. L1 heeft meestal afzonderlijke instructie- en gegevenscaches van elk ongeveer 32–64 KiB per kern. L2 is vaak honderden KiB tot enkele MiB per kern, terwijl L3 vaak wordt gedeeld en enkele tot tientallen MiB bevat. Het hoofdgeheugen bevat vele GiB en de opslag honderden GB of meer. Ontwerpen verschillen in grootte en verdeling.
Op een processor van ongeveer 3 GHz zijn representatieve latentietijden voor laden ongeveer 4–5 cycli voor L1, 12–15 voor L2, 30–50 voor L3 en 200–300 voor DRAM. Een L1-cache kan elke cyclus een nieuw verzoek accepteren, ook als één verzoek meerdere cycli nodig heeft om te worden voltooid: doorvoer en latentie beschrijven verschillende eigenschappen.
Gegevens reizen door caches in blokken, meestal van 64 bytes. Virtueel geheugen gebruikt pagina's, meestal van 4 KiB, bij het verplaatsen van pagina-inhoud tussen geheugen en opslag. Een cachelijn en een pagina dienen een vergelijkbaar doel voor groepering op verschillende schaal; het zijn niet dezelfde overdrachtseenheden.
Treffers, missers en tijd
Een treffer betekent dat een niveau de gevraagde gegevens bevat. Een misser betekent dat het niveau de gegevens van onderaf moet ophalen. Beide woorden hebben betrekking op het niveau dat wordt gecontroleerd: een L1-misser kan nog steeds een L2-treffer zijn.
De trefferfractie is het aantal treffers gedeeld door het aantal toegangen en de misserfractie is één min de trefferfractie. De cachetoegangstijd omvat het controleren van het niveau en het vaststellen of het verzoek een treffer oplevert. De extra vertraging bij een cachemisser is de extra tijd die bij een misser nodig is om het blok op te halen en te leveren.
Stel dat een vereenvoudigde cache een toegangstijd van 1 cyclus, een trefferfractie van 97% en een extra vertraging van 100 cycli bij een misser heeft. Elke toegang kost 1 cyclus, terwijl 3% nog eens 100 cycli kost:
Een misser duurt in dit voorbeeld 101 cycli. Als je 100 als de volledige tijd voor een misser gebruikt, reken je de tijd voor het opzoeken in de cache niet consequent mee. Zelfs bij een hoge trefferfractie blijven dure missers zichtbaar in het gemiddelde.
Wie beheert elk niveau?
De compiler wijst geschikte waarden toe aan registers. Cachehardware verplaatst blokken automatisch tijdens laad- en opslagbewerkingen en het ophalen van instructies. Programma's gebruiken adressen; ze selecteren geen cacheposities. Het besturingssysteem beheert met hardwareondersteuning de afbeeldingen van virtueel geheugen en handelt pagina's af die naar het hoofdgeheugen moeten worden gehaald.
Door L1 op te splitsen voor instructies en gegevens kan een pipeline tegelijk een instructie ophalen en gegevens benaderen zonder om één cachepoort te concurreren. Lagere caches zijn meestal gecombineerd en slaan zowel instructie- als gegevensblokken op.
Sommige hiërarchieën zijn inclusief: een blok dat boven aanwezig is, heeft ook een kopie eronder. Andere zijn exclusief of niet-inclusief, zodat een kopie in elke lagere cache niet gegarandeerd is. Teken een hiërarchie als een zoek- en overdrachtspad, niet als een belofte dat alle niveaus identieke deelverzamelingen bevatten.
Een grotere L1-cache kan missers verminderen, maar de toegangsvertraging en het energieverbruik verhogen. Door grotere lagere caches toe te voegen kan het ontwerp L1 snel houden en veel van de L1-missers opvangen voordat ze DRAM bereiken. Beoordeel die afweging op basis van toegangstijd, niet alleen capaciteit.
Belangrijkste punten
- Een treffer of misser heeft betrekking op het niveau dat wordt gecontroleerd.
- De cachetoegangstijd geldt voor elke opzoeking; de extra vertraging geldt bij missers.
- Caches dragen blokken over, terwijl virtueel geheugen pagina's gebruikt.
- Afzonderlijke L1-instructie- en gegevenscaches ondersteunen gelijktijdige toegangen vanuit de pipeline.
- Cache-inclusie is een ontwerpkeuze.
- Grotere capaciteit moet worden afgewogen tegen cachetoegangstijd en energieverbruik.
2Zoek gegevens in direct afgebeelde en set-associatieve caches
Een geheugenadres moet een cache vertellen waar die moet zoeken en welke bytes die moet teruggeven. Verdeel adressen in velden, volg hoe verzoeken blokken vervangen en geef elk blok vervolgens meer plaatsingsmogelijkheden met sets en posities. Kleine registraties maken de hardwareregels zichtbaar: een andere byte kan een treffer opleveren in een geladen blok, terwijl een herhaaldelijk gebruikt blok na een conflict kan missen. Deze opzoekregels bepalen ook hoeveel adrestags en besturingsbits de cache moet opslaan.
2.1 Bepaal adrestag, index en offset
Een byteadres geeft één byte in het geheugen aan. Een cache haalt een heel blok op, dus bepaalt de cache bij het opzoeken eerst dat blok en selecteert daarna de gevraagde bytes daarin. In een direct afgebeelde cache heeft elk blok precies één mogelijke positie.
Verdeel het adres naar functie
Bij een blokgrootte van bytes vormen de laagste adresbits de offset. Door het byteadres door de blokgrootte te delen en de rest weg te laten, krijg je het blokadres. De rest is de offset.
Als de cache posities heeft, is de positie-index
Als het aantal posities een macht van twee is, bestaat de index uit de groep adresbits direct boven de offset. De resterende hoge bits vormen de adrestag, die de cache vertelt welk van de vele blokken die een index delen aanwezig is.
De veldvolgorde van hoge naar lage bits is adrestag | index | offset. Voor een adresbreedte van bits geldt:
Gebruik het aantal posities voor de indexberekening. Als je de logaritme van de capaciteit in bytes neemt, tel je de offsetbits een tweede keer.
Werk een voorbeeld met 16 KiB uit
Een direct afgebeelde cache van 16 KiB met blokken van 64 bytes heeft posities. De offset neemt 6 bits in, de index 8 bits en de adrestag bits bij adressen van 32 bits.
Voor byteadres 0x1234ABCD geven de laagste 6 bits offset 13, of 0x0D. Als je die bits verwijdert, krijg je blokadres 0x48D2AF. De laagste 8 bits daarvan zijn 0xAF, dus is de index 175. De resterende bits geven adrestag 0x48D2.
Het byteadres kan uit deze velden worden gereconstrueerd: voeg de adrestag, de 8-bitsindex en de 6-bitsoffset samen. De veldbreedtes zijn van belang omdat een hexadecimaal cijfer 4 bits voorstelt; de grenzen hoeven niet tussen hexadecimale cijfers te vallen.
Een overeenkomende adrestag vereist een geldige positie
Elke positie bevat gegevens, een adrestag en een geldigheidsbit. De index selecteert de positie. Een treffer vereist zowel een gezette geldigheidsbit als een overeenkomst tussen de opgeslagen en de gevraagde adrestag. Bij het opstarten kan een positie willekeurige bits bevatten; de geldigheidsbit voorkomt dat die bits voor een geladen blok worden aangezien.
Zodra het blok aanwezig is, leveren toegangen tot andere bytes in dat blok ook treffers op. Een treffer vereist niet hetzelfde byteadres als waarmee het blok is opgehaald.
Tel metadata afzonderlijk
De opgegeven cachecapaciteit telt gewoonlijk alleen gegevens. Hier bevat elke positie 512 gegevensbits, 18 tagbits en 1 geldigheidsbit, samen 531 bits. De totale opslag is
De gegevens alleen gebruiken 131.072 bits. Adrestags en geldigheidsbits voegen 4.864 bits toe, ongeveer 3,7% van de gegevensopslag. Een ontwerp met terugschrijven heeft ook wijzigingsbits nodig; complexere ontwerpen hebben meer besturingsinformatie nodig.
De index gebruikt lage blokadresbits zodat opeenvolgende blokken over opeenvolgende posities worden verspreid. Bij een breder adres blijven de breedtes van offset en index gelijk als capaciteit en blokgrootte vast blijven; de extra bits verlengen de adrestag.
Belangrijkste punten
- Bereken het aantal posities door de gegevenscapaciteit te delen door de blokgrootte.
- De lage adresbits selecteren de byteoffset; de volgende bits selecteren de positie.
- Een treffer vereist een geldige positie en een overeenkomende adrestag.
- De opgegeven gegevenscapaciteit is exclusief adrestags en besturingsbits.
2.2 Volg een direct afgebeelde cache
Een cachetoegangsregistratie legt vast hoe elke toegang de opgeslagen blokken verandert. Houd voor elke positie een afzonderlijke toestand bij en werk die direct na elke misser bij. Het volgende verzoek gebruikt de bijgewerkte cache, niet de cache zoals die er aan het begin uitzag.
Stel de registratie op
Neem een direct afgebeelde cache van 64 bytes met vier posities van 16 bytes. Die is aanvankelijk leeg. Deel voor elk byteadres door 16 om het blok te vinden en bereken daarna blok modulo 4 voor de index. De adrestag is het bloknummer gedeeld door 4, waarbij het gebroken deel wordt weggelaten. Er zijn 4 offsetbits en 2 indexbits.
Bekijk bij een leesbewerking de geselecteerde positie. Als die geldig is en de adrestag overeenkomt, noteer je een treffer. Noteer anders een misser, vervang het blok en de adrestag van die positie en zet de geldigheidsbit. In een direct afgebeelde cache is geen vervangingskeuze mogelijk.
Volg alle acht toegangen
| Byteadres | Blok | Index | Adrestag | Resultaat | Blok dat op de gekozen positie blijft |
|---|---|---|---|---|---|
0x00 | 0 | 0 | 0 | Misser | 0 |
0x04 | 0 | 0 | 0 | Treffer | 0 |
0x40 | 4 | 0 | 1 | Misser | 4 |
0x00 | 0 | 0 | 0 | Misser | 0 |
0x14 | 1 | 1 | 0 | Misser | 1 |
0x44 | 4 | 0 | 1 | Misser | 4 |
0x08 | 0 | 0 | 0 | Misser | 0 |
0x84 | 8 | 0 | 2 | Misser | 8 |
De eerste toegang vult positie 0 met blok 0. Het volgende adres, 0x04, ligt nog steeds binnen dat blok van 16 bytes en levert dus een treffer op, hoewel het een andere byte aanwijst. 0x40 hoort bij blok 4. Het heeft dezelfde index als blok 0 maar een andere adrestag, dus vervangt het blok 0.
De tweede 0x00 mist daardoor. Eerder gebruik alleen garandeert geen treffer: het blok moet nog steeds aanwezig zijn. Het verzoek om 0x14 laadt blok 1 op positie 1 en laat positie 0 ongewijzigd.
Daarna laadt 0x44 blok 4 opnieuw op positie 0. 0x08 heeft blok 0 nodig en verdringt blok 4. Ten slotte laadt 0x84 blok 8 op diezelfde positie. Aan het einde bevat positie 0 blok 8 en positie 1 blok 1; posities 2 en 3 blijven ongeldig.
Interpreteer het gedrag
Er is één treffer en er zijn zeven missers, dus is de trefferfractie . Blokken 0, 4 en 8 concurreren om positie 0. De cache heeft vier posities, maar dit toegangspatroon gebruikt er slechts twee. De herhaalde verdringingen worden veroorzaakt door afbeeldingsconflicten, niet door een tekort aan totale opslagruimte voor de vier verschillende blokken.
Door een blok te vullen komen alle bytes van dat blok beschikbaar. Bij een opeenvolgende doorloop kan één misser daardoor veel volgende elementen bedienen. Hier nemen de conflicterende toegangen dat voordeel steeds weg voordat de volgende nabijgelegen byte wordt opgevraagd.
Benoem voor een betrouwbare registratie byteadressen en bloknummers expliciet. Als je modulo 4 rechtstreeks op het byteadres toepast, sla je de deling door de blokgrootte over en stuur je verzoeken naar de verkeerde posities. Noteer de vervanging ook wanneer het nieuwe blok eerder is geladen: elke misser plaatst het gevraagde blok en de bijbehorende adrestag op de gekozen positie.
Belangrijkste punten
- Werk de cache-inhoud na elke misser bij.
- Verschillende byteadressen in één aanwezig blok leveren treffers op.
- Een eerder aangesproken blok kan na verdringing een misser opleveren.
- Afbeeldingsconflicten kunnen missers veroorzaken terwijl andere posities leeg blijven.
- Het voorbeeld heeft één treffer bij acht toegangen, een trefferfractie van 12,5%.
2.3 Geef blokken meer plaatsingsmogelijkheden
Een set-associatieve cache geeft een blok meerdere mogelijke posities zonder de hele cache te doorzoeken. De index selecteert een set en het blok kan elke positie in die set innemen. Dit vermindert conflicten tussen blokken die een index delen.
Bereken sets en velden
Voor gegevenscapaciteit , blokgrootte en associativiteit geldt:
De setindex is het blokadres modulo het aantal sets. De offset hangt nog steeds alleen af van de blokgrootte. De adrestag bevat de resterende hoge bits.
Een 8-weg cache van 32 KiB met blokken van 64 bytes heeft 512 blokken en 64 sets. Bij 32-bitsadressen zijn de breedtes van offset, index en adrestag 6, 6 en 20 bits. Adres 0x1234ABCD heeft offset 13, set 47 en adrestag 0x1234A.
Bij vaste capaciteit en blokgrootte halveert een verdubbeling van de associativiteit het aantal sets. Eén indexbit wordt een tagbit; er komt geen gegevenscapaciteit bij.
| Organisatie | Toegestane plaatsing | Index |
|---|---|---|
| Direct afgebeeld | Eén positie | Selecteert die positie |
| n-weg | Elke positie van de n posities in één set | Selecteert die set |
| Volledig associatief | Elke positie in de cache | Geen indexveld |
Bij het opzoeken wordt de adrestag parallel vergeleken met alle geldige adrestags in de gekozen set. Een overeenkomende positie levert de gegevens via een selector. Meer posities per set vereisen meer vergelijkingen en selectiehardware, wat de cachetoegangstijd en het energieverbruik kan verhogen.
Vervang pas een blok als de set vol is
Gebruik eerst een ongeldige positie. Als alle posities bezet zijn, verdringt LRU het blok waarvan de laatste toegang het langst geleden is. Werk de informatie over recent gebruik bij treffers én bij het vullen bij. Een 2-weg set heeft maar één bit nodig om de LRU-positie bij te houden; grotere sets gebruiken vaak pseudo-LRU-benaderingen.
FIFO verdringt het blok dat het eerst is geladen, ook als het onlangs is aangesproken. Willekeurige vervanging kiest een te vervangen blok zonder volledige informatie over recent gebruik bij te houden. Die methode is eenvoudig en kan in grote caches bijna even goed presteren als LRU.
Bekijk de kleine registratie opnieuw met twee posities per set
De cache van 64 bytes met blokken van 16 bytes heeft nu twee sets van twee posities. Blokken 0, 4 en 8 worden op set 0 afgebeeld, terwijl blok 1 op set 1 wordt afgebeeld. Voor 0x00, 0x04, 0x40, 0x00, 0x14, 0x44, 0x08, 0x84 zijn de resultaten misser, treffer, misser, treffer, misser, treffer, treffer, misser.
Blokken 0 en 4 kunnen naast elkaar bestaan, dus leveren herhaalde toegangen ertoe treffers op. Vlak voor de laatste toegang is blok 0 recenter gebruikt dan blok 4. Bij het laden van blok 8 verdringt LRU blok 4. Vier van de acht toegangen leveren een treffer op, tegenover één in de direct afgebeelde versie.
Associativiteit kan eerste-toegangsmissers niet wegnemen en een werkverzameling die groter is dan de capaciteit niet passend maken. Ook kan associativiteit geen conflicten voorkomen wanneer meer dan n veelgebruikte blokken om één n-weg set concurreren. Een herhaalde cyclus van n+1 van zulke blokken kan LRU elke keer laten missen. Door arrays op te vullen kun je veranderen op welke sets ze worden afgebeeld; meer posities per set kiezen is maar één mogelijke reactie op een conflictprobleem.
Belangrijkste punten
- Het aantal sets is de gegevenscapaciteit gedeeld door de blokgrootte en het aantal posities per set.
- Meer associativiteit verandert de plaatsingsvrijheid, niet de gegevenscapaciteit.
- LRU houdt toegangen bij; FIFO houdt de volgorde van plaatsen bij.
- Vul ongeldige posities voordat je geldige blokken vervangt.
- Volledig associatieve caches hebben geen indexveld, maar hebben nog steeds eerste-toegangs- en capaciteitsmissers.
- Meer posities per set kunnen conflictmissers verminderen, maar kosten hardware en tijd.
3Leg cachemissers en schrijfstrategieën uit
Een misser kan ontstaan door eerste gebruik, beperkte capaciteit of blokken die om dezelfde plaatsen concurreren. Door de oorzaak te herkennen begrijp je welke ontwerpwijzigingen die kunnen verminderen. Opslaginstructies voegen een tweede vraagstuk toe: de hiërarchie moet bepalen wanneer gewijzigde gegevens het volgende niveau bereiken en wat er gebeurt als het blok ontbreekt. Volg de afhandeling van leesmissers, schrijfstrategieën, buffers en de verdringing van gewijzigde blokken om de cachetoestand te verbinden met het verkeer en de vertragingen die daaruit ontstaan.
3.1 Leg uit waardoor een misser ontstond
Een cachemisser is een gebeurtenis met zowel een mechanisme als een oorzaak. Het mechanisme beschrijft hoe het verzoek wordt afgehandeld. De oorzaak verklaart waarom het benodigde blok ontbrak en welke ontwerpwijziging kan helpen.
Handel een leesmisser af
In een eenvoudige pipeline die instructies op volgorde uitvoert, detecteert de cache een ongeldige positie of een niet-overeenkomende adrestag en wacht de processor. De cache vraagt het blok op bij het volgende niveau. Als het gekozen te vervangen blok gewijzigd is, moeten de gewijzigde gegevens door terugschrijven worden bewaard. Het binnenkomende blok wordt met zijn adrestag en geldigheidsbit geplaatst en de wachtende toegang wordt voltooid. Bij een misser in de instructiecache wordt op dezelfde manier op het blok van de instructie gewacht en daarna de instructie opnieuw opgehaald.
Bij het gevraagde woord eerst wordt het benodigde woord als eerste in het terugkerende blok opgevraagd. Bij vroegtijdig hervatten kan de uitvoering doorgaan zodra dat woord aankomt. Een niet-blokkerende cache kan andere treffers afhandelen en openstaande missers bijhouden terwijl een processor die instructies buiten de programmavolgorde uitvoert onafhankelijk werk doet. Deze mechanismen verminderen de wachttijd; ze laten de oorspronkelijke gegevensafhankelijkheid niet verdwijnen.
Gebruik de drie C's
| Misserklasse | Waarom het blok ontbreekt | Test |
|---|---|---|
| Eerste-toegangsmisser | Dit is de eerste toegang ertoe | Die zou zelfs bij onbeperkte capaciteit missen |
| Capaciteitsmisser | De actieve blokken overschrijden de beschikbare ruimte | Een volledig associatieve LRU-cache van dezelfde grootte mist ook |
| Conflictmisser | Plaatsingsbeperkingen hebben het blok verdrongen | Een volledig associatieve LRU-cache van dezelfde grootte treft |
Pas eerst de test voor eerste toegang toe. De eerste toegang tot een blok is een eerste-toegangsmisser, ook als de bestemmingspositie al bezet is. Vergelijk bij latere missers de werkelijke cache met een volledig associatieve LRU-cache met dezelfde gegevenscapaciteit en blokgrootte, waarbij beide dezelfde toegangsgeschiedenis ontvangen.
In de eerdere registratie met vier posities veroorzaken blokken 0, 4, 1 en 8 elk één eerste-toegangsmisser. De direct afgebeelde cache mist ook bij de herhaalde toegangen tot blokken 0 en 4. Een volledig associatieve cache met vier posities kan alle vier verschillende blokken bewaren, dus zijn die drie herhaalde missers conflictmissers. Er zijn geen capaciteitsmissers.
Kies een wijziging die de oorzaak aanpakt
Meer capaciteit kan een grotere werkverzameling vasthouden. Meer associativiteit kan ervoor zorgen dat conflicterende blokken naast elkaar passen. Een grotere blokgrootte kan ruimtelijke lokaliteit benutten door bij elke vulling meer bruikbare naburige gegevens binnen te halen.
Blokgrootte heeft tegengestelde effecten. Bij een vaste gegevenscapaciteit betekenen grotere blokken dat minder blokken tegelijk aanwezig zijn. Ongebruikte bytes nemen cacheruimte in, niet-gerelateerde bruikbare blokken kunnen worden verdrongen en elke overdracht kan langer duren. De misserfractie daalt vaak eerst als de blokgrootte groeit en stijgt daarna wanneer deze kosten zwaarder wegen dan de bruikbare ruimtelijke lokaliteit.
Een grotere cache kan ook een langere opzoektijd hebben en extra posities per set vereisen meer vergelijkingshardware. Beoordeel wijzigingen aan de hand van de gemiddelde toegangstijd, inclusief cachetoegangstijd en extra vertraging bij een misser, in plaats van aan te nemen dat een lagere misserfractie een sneller ontwerp garandeert.
In multicore-systemen kan het ongeldig maken na een schrijfbewerking van een andere kern coherentiemissers veroorzaken. Door vooraf ophalen kan een blok vóór de eerste gevraagde toegang binnenkomen, zodat een misser bij die toegang wordt verborgen die extra capaciteit alleen niet kan voorkomen.
Belangrijkste punten
- Deel eerste toegangen in als eerste-toegangsmissers voordat je andere oorzaken controleert.
- Gebruik een volledig associatieve LRU-cache van dezelfde grootte om capaciteits- en conflictmissers te onderscheiden.
- Grotere blokken wegen bruikbare ruimtelijke lokaliteit af tegen minder aanwezige blokken en langere overdrachten.
- Vroegtijdig hervatten, het gevraagde woord eerst en niet-blokkerende caches verminderen de wachttijd op verschillende manieren.
- Vergelijk de volledige toegangstijd bij het beoordelen van een verbetering van de misserfractie.
3.2 Bepaal wanneer opslaginstructies het volgende niveau bereiken
Een opslaginstructie verandert een waarde, dus heeft de hiërarchie een regel nodig om die verandering naar beneden door te geven. Daarbij zijn twee afzonderlijke keuzes betrokken: wat gebeurt er als een opslaginstructie een treffer oplevert en wat als die mist?
Direct doorschrijven en terugschrijven
| Strategie | Actie bij een schrijftreffer | Gevolg voor het volgende niveau |
|---|---|---|
| Direct doorschrijven | Werk de cache bij en stuur de opslaginstructie naar beneden | Elke opslaginstructie werkt het lagere niveau bij |
| Terugschrijven | Werk de cache bij en markeer het blok als gewijzigd | Een gewijzigd blok wordt bij verdringing naar beneden gestuurd |
Een wijzigingsbit legt vast dat een blok in een cache met terugschrijven wijzigingen bevat die nog niet naar het volgende niveau zijn geschreven. Een ongewijzigd te vervangen blok hoeft niet te worden teruggeschreven. De gewijzigde gegevens van een te vervangen blok moeten worden bewaard voordat de positie opnieuw kan worden gebruikt. De laadbewerkingen van de processor halen de nieuwe waarde uit de cache, ook terwijl de lagere kopie ouder is.
Bij 100 opslaginstructies naar één variabele van 4 bytes in de cache stuurt direct doorschrijven zonder samenvoeging 100 schrijfbewerkingen, of 400 bytes aan gegevens. Terugschrijven kan die wijzigingen combineren in één schrijfbewerking van een blok van 64 bytes bij verdringing. Deze vergelijking telt de gegevens van de bijwerkingen, zonder de eerste vulling en protocoloverhead.
Het voordeel hangt af van hergebruik. Herhaaldelijk naar één blok schrijven geeft terugschrijven de kans om bijwerkingen te combineren; schrijfbewerkingen verspreid over veel blokken kunnen leiden tot veel verdringingen van gewijzigde blokken. Lagere caches gebruiken vaak terugschrijven om het verkeer naar DRAM te beperken. L1-gegevenscaches kunnen beide strategieën gebruiken.
Een schrijfbuffer verbergt wachttijd, geen verkeer
Een schrijfbuffer zet schrijfbewerkingen die nog naar een lager niveau moeten in een wachtrij. Bij direct doorschrijven kan de processor doorgaan zodra een opslaginstructie in de buffer staat, in plaats van te wachten tot het lagere geheugen klaar is. Het lagere niveau loopt bij naarmate de gebufferde schrijfbewerkingen worden verwerkt; het kan tijdelijk achterlopen op de waarde in de cache.
De buffer heeft een eindige capaciteit. Als opslaginstructies lang genoeg sneller binnenkomen dan het lagere niveau ze accepteert, raakt de buffer vol en wacht de processor. Een buffer verandert wanneer de processor wacht, niet de blijvend haalbare bandbreedte van de bestemming.
Zonder buffering of overlap wordt een basis-CPI van 1 gelijk aan als 10% van de instructies opslaginstructies zijn en elke opslaginstructie 100 wachtcycli toevoegt. Buffering kan veel van deze vertraging verbergen als de bestemming het gemiddeld bijhoudt.
Behandel een schrijfmisser afzonderlijk
Bij cachetoewijzing bij een schrijfmisser wordt het ontbrekende blok eerst in de cache opgehaald en daarna wordt de opslaginstructie erop toegepast. Dit gaat goed samen met terugschrijven, omdat latere toegangen en schrijfbewerkingen dat blok opnieuw kunnen gebruiken. Bij geen cachetoewijzing bij een schrijfmisser wordt de opslaginstructie naar beneden gestuurd zonder deze cache te vullen. Dit gaat goed samen met direct doorschrijven en kan voorkomen dat bruikbare blokken worden verdrongen tijdens een eenmalige uitvoerstroom.
Dit zijn onafhankelijke strategiekeuzes. Als je weet dat een cache direct doorschrijft, weet je daarmee nog niet of bij een schrijfmisser een lijn wordt toegewezen; een registratie moet beide strategieën specificeren.
Een misser in een cache met terugschrijven die een gewijzigd blok voor vervanging kiest, omvat zowel uitgaande gegevens als de binnenkomende vulling. Dit verhoogt de extra vertraging, tenzij buffers of overlap een deel van het werk verbergen. Andere kernen en I/O-apparaten hebben ook een consistent beeld nodig wanneer het lagere geheugen verouderde gegevens bevat. Coherentie en systeemmechanismen coördineren die zichtbaarheid; een wijzigingsbit alleen legt slechts openstaande wijzigingen vast.
Belangrijkste punten
- Direct doorschrijven stuurt elke opslaginstructie naar beneden; terugschrijven stelt wijzigingen uit tot het gewijzigde blok wordt teruggeschreven.
- Een wijzigingsbit onderscheidt gewijzigde blokken van ongewijzigde.
- Schrijfbuffers verbergen latentie totdat ze vol raken; ze creëren geen bandbreedte.
- Cachetoewijzing of geen cachetoewijzing bij een schrijfmisser bepaalt het gedrag bij een schrijfmisser, onafhankelijk van de strategie bij een treffer.
- De verdringing van een gewijzigd blok voegt uitgaand verkeer toe aan de afhandeling van de misser.
- Bij gebufferd direct doorschrijven kan het lagere niveau tijdelijk achterlopen.
4Bereken cacheprestaties
Een cacheontwerp is alleen nuttig als de treffers en missers tot een betere uitvoeringstijd leiden. Combineer opzoektijd, misserfrequentie en extra vertraging bij missers en verbind daarna toegangskosten met wachtcycli per instructie. Houd instructie- en gegevensverkeer gescheiden, gebruik cycli en kloktijd consequent en nest de kosten van lagere caches met de fractie verzoeken die elk niveau bereikt. Deze berekeningen laten zien waarom een lagere misserfractie of hogere klokfrequentie minder voordeel kan geven dan verwacht.
4.1 Bereken de gemiddelde geheugentoegangstijd
Een hoge trefferfractie is nuttig, maar geen volledige prestatiemaat. Een klein aantal dure missers kan het gemiddelde domineren en een ontwerp dat meer missers voorkomt kan toch verliezen als het opzoeken te langzaam wordt.
Begin met fracties en tijdsdefinities
De twee fracties tellen op tot één. Zet percentages vóór het vermenigvuldigen om in fracties: 5% is 0,05.
De gemiddelde geheugentoegangstijd, of AMAT, is
Elk verzoek controleert de cache, ook verzoeken die missen. De extra vertraging komt na die opzoeking. Je kunt ook de cachetoegangstijd wegen met de trefferfractie en de totale tijd voor een misser met de misserfractie; uitwerken geeft dezelfde formule.
Bij een cachetoegangstijd van 1 cyclus, 5% missers en een extra vertraging van 100 cycli is de AMAT cycli. Bij 2 GHz duurt elke cyclus 0,5 ns, dus is dit 3 ns. Reken alles uit in cycli of alles in tijd en zet zo nodig het eindresultaat om.
Vergelijk volledige ontwerpen
Cache A heeft een opzoektijd van 1,0 ns en 5% missers. Cache B heeft een opzoektijd van 1,2 ns en 3,5% missers. Bij een extra vertraging van 50 ns geldt:
B wint omdat het voorkomen van dure missers de langzamere opzoeking ruimschoots goedmaakt. Als de extra vertraging daalt naar 10 ns, duurt A 1,5 ns en B 1,55 ns. Nu wint A. De waarde van een verbetering van de misserfractie staat in verhouding tot de extra vertraging die ermee wordt vermeden.
Weeg instructie- en gegevenstoegangen correct
Stel dat elke instructie gemiddeld één instructieophaling en 0,3 gegevenstoegangen oplevert. De misserfractie voor instructies is 2% en die voor gegevens 4%. Bij 100 instructies zijn er 100 ophalingen en 30 gegevenstoegangen. Het verwachte aantal missers is op 130 toegangen.
De gecombineerde misserfractie is daarom Bij gelijke cachetoegangstijden van 1 cyclus en extra vertragingen van 100 cycli is de AMAT ongeveer 3,46 cycli per geheugentoegang. Rechtstreeks het gemiddelde van 2% en 4% nemen zou de twee soorten toegang ten onrechte even zwaar laten meetellen.
Schat de extra vertraging door overdracht
Een blokverzoek kan een initiële latentie omvatten, gevolgd door overdrachtstijd. Bij 60 ns latentie, een lijn van 64 bytes en 16 GB/s bandbreedte duurt de overdracht 4 ns, zodat de extra vertraging ongeveer 64 ns is. Bij 3 GHz zijn er 3 cycli/ns, dus is dat 192 cycli.
Controleer wat de opgegeven tijden in een opgave omvatten. Als de volledige toegangstijd bij een misser wordt gegeven, trek dan de tijd voor het opzoeken in de cache af voordat je dat getal als extra vertraging bij een misser gebruikt. Als je de opzoektijd tweemaal meetelt, wordt de AMAT overschat.
Belangrijkste punten
- AMAT telt de cachetoegangstijd op bij de verwachte extra kosten van missers.
- Gebruik decimale misserfracties en één consistente tijdseenheid.
- Weeg de fracties voor instructies en gegevens naar hun aantallen toegangen.
- Een lagere misserfractie kan verliezen van een voldoende langere cachetoegangstijd.
4.2 Reken missers om naar uitvoeringstijd
AMAT meet de tijd per geheugentoegang. CPI meet het aantal cycli per uitgevoerde instructie. Om ze te verbinden tel je hoeveel instructie- en gegevensverzoeken elke instructie oplevert en hoeveel wachtcycli die verzoeken toevoegen.
Tel de wachttermen op
Voor een eenvoudige processor die instructies op volgorde uitvoert en waarvan de cachetreffers in de basis-CPI zijn opgenomen, voegt een misser waarvan de vertraging niet overlapt de extra vertraging toe. Met instructiemisserfractie , gegevenstoegangen per instructie , gegevensmisserfractie en extra vertraging in cycli geldt:
Elke instructie heeft in dit model één verzoek om de instructie op te halen. Alleen laad- en opslaginstructies doen gegevensverzoeken, dus vermenigvuldig je hun misserfractie met hun frequentie. Als hun extra vertragingen verschillen, gebruik je in elke term een afzonderlijke vertraging.
Van verzoeken naar wachtcycli
Neem een basis-CPI van 1,0, een instructiemisserfractie van 2%, een laad- en opslagfrequentie van 30%, een gegevensmisserfractie van 4% en een extra vertraging van 100 cycli bij een misser. Instructiewachtcycli zijn cycli per instructie. Gegevenswachtcycli zijn . De totale CPI is 4,2.
Met een perfecte cache zou de CPI terugkeren naar 1,0. Bij dezelfde klokfrequentie en hetzelfde aantal uitgevoerde instructies zou dat een versnellingsfactor van 4,2 opleveren. De gegevensmisserfractie is tweemaal zo groot als de instructiemisserfractie, maar instructiemissers kosten in totaal meer tijd omdat elke instructie wordt opgehaald en slechts 30% gegevens aanspreekt.
Vul AMAT niet rechtstreeks in als CPI. AMAT is per toegang en omvat de tijd voor een treffer. De CPI-berekening hier telt alleen wachtcycli op boven op de basisuitvoering die al is meegeteld.
Een hogere klokfrequentie laat elke geheugenwachttijd meer cycli kosten
De DRAM-latentie in nanoseconden wordt niet korter wanneer de klokfrequentie van de processor stijgt. Een verdubbeling van de klokfrequentie zet dezelfde geheugenwachttijd van 100 cycli om in 200 cycli bij de nieuwe frequentie. De CPI van het voorbeeld wordt
Elke nieuwe cyclus duurt half zo lang, dus verandert de relatieve uitvoeringstijd van 4,2 oude cycli per instructie naar het equivalent van 3,7 oude cycli. De versnellingsfactor is , ruim onder twee.
Verbeteringen verplaatsen de bottleneck
Als de basis-CPI daalt van 1,0 naar 0,5 terwijl de geheugenwachtcycli op 3,2 blijven, wordt de totale CPI 3,7. Wachtcycli nemen nu van de cycli in beslag. Een betere kern maakt de ongewijzigde geheugenvertraging tot een groter deel van de uitvoeringstijd, een voorbeeld van de wet van Amdahl.
Het eenvoudige model telt alle vertragingen door missers als wachtcycli. Uitvoering buiten de programmavolgorde en niet-blokkerende caches kunnen missers laten overlappen met nuttig werk of andere missers. Prestatietellers in de hardware en metingen van de uitvoeringstijd zijn nodig om die overlap op een echte machine te beoordelen. Houd bij het vergelijken van ontwerpen met dit model dezelfde instructiestroom aan en vermeld welke vertragingen al in de basis-CPI zijn opgenomen.
Belangrijkste punten
- Tel instructiemissers voor elke instructie en gegevensmissers alleen voor gegevenstoegangen.
- Tel extra wachtcycli door missers op bij een basis-CPI waarin treffers al zijn opgenomen.
- Reken de geheugentijd opnieuw om naar cycli als de klokfrequentie verandert.
- Vergelijk uitvoeringstijd via CPI maal klokcyclustijd, niet alleen via CPI.
- Overlap kan de werkelijke wachtcycli kleiner maken dan de eenvoudige som van de extra vertragingen bij missers.
4.3 Nest de kosten van meerdere cacheniveaus
Een lagere cache vermindert de extra vertraging die bij een L1-misser wordt betaald. Die cache heeft een eigen opzoektijd en misserfractie, dus moeten de verwachte kosten van de hiërarchie rekening houden met de fractie verzoeken die elk niveau bereikt.
Houd de noemer bij de fractie
De lokale misserfractie van een niveau is het aantal missers gedeeld door de verzoeken aan dat niveau. De globale misserfractie is het aantal missers gedeeld door alle geheugenverzoeken van de processor.
Als L1 in 4% van de gevallen mist en L2 bij 25% van die verzoeken mist, bereikt slechts , of 1% van de oorspronkelijke verzoeken, het geheugen. Een lokale L2-misserfractie van 25% zegt op zichzelf niets over de fractie van alle verzoeken die het geheugen bereikt: L1 heeft de stroom eerst gefilterd.
Voor twee achtereenvolgens gecontroleerde niveaus geldt:
Hier zijn en opzoektijden, en lokale misserfracties en is de extra vertraging van het geheugen. Alleen L1-missers betalen de L2-opzoektijd. Alleen missers in beide niveaus betalen de extra vertraging van het geheugen.
Reken van binnen naar buiten
Gebruik een L1-toegangstijd van 1 cyclus, een L1-misserfractie van 4%, een L2-toegangstijd van 12 cycli, een lokale L2-misserfractie van 25% en een extra vertraging van het geheugen van 200 cycli. Een verzoek dat L2 bereikt, kost gemiddeld extra cycli. Dus geldt
Zonder L2 zou AMAT cycli zijn. Het opzoeken in L2 voegt werk toe aan elke L1-misser, maar voorkomt dat de meeste van die verzoeken de veel grotere geheugenvertraging betalen.
Vervang binnen de haakjes niet door de globale L2-misserfractie van 1%. Dan zou je tweemaal met de L1-misserfractie vermenigvuldigen. Een equivalente uitgeschreven vorm gebruikt de globale fractie rechtstreeks:
Voeg L3 toe volgens dezelfde logica
Bij een L3-toegangstijd van 40 cycli en een lokale misserfractie van 40% is de L3-afhandelingsterm cycli. De L2-term wordt cycli. De totale AMAT is cycli.
De volledige uitdrukking is L3 wordt alleen meegerekend voor verzoeken die in beide hogere niveaus missen. Een niveau met een zeer langzame opzoektijd of zeer weinig treffers kan meer vertraging toevoegen dan het bespaart.
Gebruik aantallen per instructie voor de CPI
Stel dat de basis-CPI 1 is, L1 0,032 missers per instructie oplevert en het geheugen 100 cycli toevoegt. Zonder L2 is de CPI . Voeg een L2-cache van 10 cycli toe met een lokale misserfractie van 25%:
Bij dezelfde klokfrequentie is de versnellingsfactor . De waarde 0,032 is al het aantal missers per instructie, dus zou een extra vermenigvuldiging met de toegangsfrequentie die frequentie tweemaal meetellen.
Belangrijkste punten
- Lokale en globale misserfracties hebben verschillende noemers.
- Vermenigvuldig lokale misserfracties om de fractie te vinden die een lager niveau bereikt.
- Bereken geneste afhandelingstijden vanaf het laagste niveau omhoog.
- Reken de opzoektijd van een lager niveau alleen toe aan verzoeken die dat niveau bereiken.
- Gebruik missers per instructie rechtstreeks bij het berekenen van de extra CPI door wachtcycli.
- Een extra cache helpt alleen als de vermeden vertraging groter is dan het toegevoegde opzoekwerk.
5Leg uit hoe virtueel geheugen en TLB's in de geheugenhiërarchie passen
Programma's geven virtuele adressen uit, terwijl caches uiteindelijk fysieke gegevens identificeren. Paginatabellen leveren de afbeelding en toegangsrechten en een TLB houdt recent gebruikte vertalingen dicht bij de processor. Doorloop een adresvertaling, onderscheid een ontbrekende vertaling van een paginafout en bekijk hoe cache-indexering kan overlappen met vertaling. Dezelfde ideeën over hiërarchie gelden hier, maar vertaalitems, gegevensblokken en pagina's hebben verschillende taken.
5.1 Vertaal pagina's en controleer toegangsrechten
Virtueel geheugen scheidt de adressen die een programma gebruikt van de plaatsen waar de gegevens in het hoofdgeheugen staan. Elk proces krijgt een eigen virtuele adresruimte. Hardware vertaalt adressen met behulp van afbeeldingen van het besturingssysteem en controleert of elke gevraagde toegang is toegestaan.
Vervang het paginanummer en behoud de offset
Een pagina is een gebied met virtuele adressen van vaste grootte. Een paginakader is een plaats ter grootte van een pagina in het fysieke geheugen. Bij pagina's van 4 KiB bevat elke pagina 4096 bytes, dus heeft de paginaoffset 12 bits nodig. De resterende hoge bits van het virtuele adres vormen het virtuele paginanummer, of VPN.
Een paginatabelitem, of PTE, beeldt een VPN af op een fysiek paginanummer, of PPN. De vertaling vervangt het paginanummer maar behoudt de offset: binnen het fysieke paginakader wordt dezelfde bytepositie geselecteerd.
Voor virtueel adres 0x00403A7C geven de laagste 12 bits offset 0xA7C en is het VPN 0x00403. Als dat VPN op PPN 0x02F1C wordt afgebeeld, is het fysieke adres 0x02F1CA7C. Een 12-bitsoffset toevoegen komt overeen met het PPN met 4096 vermenigvuldigen en de offset optellen; het onverschoven PPN optellen zou het verkeerde adres geven.
Een afbeelding omvat toegangsrechten
Een PTE legt geldigheid, een fysiek paginanummer en rechten zoals lezen, schrijven, uitvoeren en gebruikerstoegang vast. Toegangs- en wijzigingsbits registreren gebruik en wijzigingen. Een bevoorrecht processorregister geeft de paginatabel aan; RISC-V gebruikt satp. Gebruikersprogramma's kunnen deze afbeeldingen niet vrij herschrijven.
Afzonderlijke paginatabellen laten hetzelfde virtuele adres in verschillende processen naar verschillende fysieke gegevens verwijzen. Ze maken ook gericht delen mogelijk: twee processen kunnen virtuele pagina's op hetzelfde fysieke paginakader afbeelden, bijvoorbeeld om alleen-lezen bibliotheekcode te delen. Isolatie en delen zijn beide gevolgen van gecontroleerde afbeeldingen.
Een paginafout vereist aandacht van het besturingssysteem
Een paginafout is een uitzondering die optreedt wanneer de vertaling of de controle van de toegangsrechten niet normaal kan worden voltooid. Een opslaginstructie naar een alleen-lezen afbeelding kan een paginafout veroorzaken, ook als de pagina al in het geheugen staat.
Als een benodigde pagina in het hoofdgeheugen ontbreekt, verkrijgt het besturingssysteem een fysiek paginakader, leest het de pagina uit de opslag, werkt het de afbeelding bij en start het de instructie opnieuw. Een gewijzigde pagina die wordt vervangen moet mogelijk eerst worden teruggeschreven. Sommige fouten worden zonder opslag afgehandeld, zoals het instellen van een afbeelding naar een bestaande pagina of het afhandelen van kopiëren bij schrijven. Een toegang die het systeem niet kan toestaan kan daarentegen eindigen in een procesfout.
Paginafouten waarvoor opslag nodig is, zijn duur. Bij 3 GHz kost een vertraging van 50 µs 150.000 cycli en kost 1 ms 3.000.000 cycli. Grote pagina's spreiden de overdrachtskosten over veel bytes. Een virtuele pagina kan elk geschikt paginakader innemen en gewijzigde pagina's worden teruggeschreven omdat elke opslaginstructie doorsturen naar de opslag te langzaam zou zijn.
Paginatabellen gebruiken ook geheugen
Een vlakke tabel voor virtuele adressen van 32 bits en pagina's van 4 KiB heeft items nodig. Bij 4 bytes per item is dat 4 MiB per proces. Echte ontwerpen gebruiken tabellen met meerdere niveaus om te voorkomen dat één enorme vlakke tabel voor ijl gevulde adresruimtes moet worden toegewezen; RISC-V Sv39 gebruikt drie niveaus.
Virtueel geheugen omvat adresvertaling, beveiliging en delen, ook wanneer elke gebruikte pagina in DRAM past. Paging met opslag is één toepassing van dat mechanisme, niet het hele doel.
Belangrijkste punten
- Vertaling verandert het paginanummer en behoudt de paginaoffset.
- PTE-toegangsrechten regelen lezen, schrijven, uitvoeren en gebruikerstoegang.
- Een paginafout kan een ontbrekende pagina of een probleem met toegangsrechten betekenen.
- Sommige paginafouten worden afgehandeld zonder uit de opslag te lezen.
- Paginatabellen ondersteunen procesisolatie en bewust delen.
- Een vlakke tabel heeft één item per virtuele pagina en kan dus veel opslagruimte kosten.
5.2 Bewaar vertalingen in een TLB
Adresvertaling kan meerdere leesbewerkingen van de paginatabel vereisen voordat een gegevenstoegang doorgaat. Paginatabelitems kunnen treffers opleveren in gewone caches, maar die leesbewerkingen voegen nog steeds werk toe. De vertaalbuffer, of TLB, bewaart recent gebruikte vertalingen, zodat de meeste toegangen het doorlopen van de paginatabel kunnen vermijden.
Volg een toegestane toegang
Het virtuele paginanummer wordt opgezocht in de TLB. Een overeenkomend item levert het fysieke paginanummer en informatie over de toegangsrechten. Na controle van de rechten identificeert het fysieke adres de gegevens in de cachehiërarchie.
Bij een TLB-misser wordt de vertaling verkregen door de paginatabel te doorlopen. Als de afbeelding geldig is en het verzoek toestaat, wordt de vertaling in de TLB geplaatst en gaat de toegang verder. RISC-V en x86-64 gebruiken hiervoor gewoonlijk hardware; sommige architecturen gebruiken softwareafhandelaars. Als de afbeelding het verzoek niet kan afhandelen, veroorzaakt de processor een paginafout voor het besturingssysteem.
Een TLB-misser kan dus samengaan met een treffer of een misser in de gegevenscache. De misser zegt dat de vertaling in de TLB ontbrak, niet dat de pagina in DRAM ontbrak. Omgekeerd kan een TLB-treffer samengaan met een cachemisser of een fout in de toegangsrechten bij een verboden toegang. Vertaling en aanwezigheid van gegevens beantwoorden verschillende vragen.
Tel het geheugen dat door vertalingen wordt gedekt
Het TLB-bereik is het aantal items maal de paginagrootte. Een TLB met 64 items en pagina's van 4 KiB dekt tegelijk 256 KiB. Met pagina's van 2 MiB dekken 64 items 128 MiB. Toegang tot veel verschillende pagina's kan de vertaalcapaciteit uitputten, ook als van elke pagina slechts enkele bytes worden gebruikt.
TLB's op het eerste niveau bevatten vaak tientallen items; lagere TLB-niveaus kunnen honderden of duizenden items bevatten. Hun items omvatten paginanummertags, fysieke afbeeldingen, toegangsrechten en vaak adresruimte-identificatoren. Lokaliteit binnen pagina's en hergebruik bij nabijgelegen toegangen houden de trefferfractie voor vertalingen hoog.
Als bijvoorbeeld 1% van de toegangen vereist dat de paginatabel gedurende 30 cycli wordt doorlopen en de tijd van een TLB-treffer verder wordt verborgen, voegt het doorlopen gemiddeld cycli per toegang toe. Dit voorbeeld gaat ervan uit dat het doorlopen normaal wordt voltooid en laat de afhandeling van paginafouten buiten beschouwing.
Laat indexering en vertaling overlappen
Een fysiek geïndexeerde, fysiek getagde cache wacht op een fysiek adres voordat die een set selecteert. Een virtueel geïndexeerde, fysiek getagde cache, of VIPT-cache, begint een set te lezen terwijl de TLB vertaalt en vergelijkt daarna fysieke adrestags.
Het eenvoudige VIPT-ontwerp haalt alle index- en blokoffsetbits uit de paginaoffset, omdat vertaling die bits behoudt. Dit vereist
Bij pagina's van 4 KiB heeft een 8-weg cache van 32 KiB 4 KiB per positie en voldoet die. Een 12-weg cache van 48 KiB voldoet ook. Een 8-weg cache van 64 KiB heeft 8 KiB per positie en heeft een paginanummerbit nodig voor de indexering, dus vereist die meer posities per set of een aanvullende afhandeling.
Houd bewaarde afbeeldingen actueel
Vertalingen behoren bij adresruimtes. Bij een contextwisseling kunnen oude items worden verwijderd of met adresruimte-identificatoren, of ASID's, worden onderscheiden. Wijzigingen in afbeeldingen vereisen overeenkomstig onderhoud van de vertaalcache; RISC-V biedt sfence.vma. Als een pagina uit het geheugen wordt verdrongen, mag de oude vertaling ervan niet bruikbaar blijven in de TLB. De TLB bevat afbeeldingen en toegangsrechten, terwijl gewone caches de gegevens en instructies van het programma bevatten.
Belangrijkste punten
- Een TLB slaat vertalingen en toegangsrechten op, geen programmagegevens.
- Het succesvol doorlopen van de paginatabel verhelpt een TLB-misser zonder paginafout.
- Het TLB-bereik is het aantal items maal de paginagrootte.
- Eenvoudige VIPT-indexering laat index- en blokoffsetbits binnen de paginaoffset passen.
- ASID's en het ongeldig maken van vertalingen voorkomen het gebruik van afbeeldingen uit de verkeerde adresruimte of van een oude afbeelding.
6Schrijf programma's die rekening houden met de cache
Lussen en gegevensindelingen bepalen welke bytes een processor als volgende opvraagt. Volg die adressen om de ruimtelijke lokaliteit te verbeteren, bruikbare gegevens door blokgewijze verwerking te behouden en te begrijpen wanneer vooraf ophalen wachttijd kan verbergen. Vergelijk rij- en kolomdoorlopen, indelingen voor records en het geheugenbeslag van rekenblokken voordat je een wijziging meet. Capaciteit, setconflicten, vertaalbereik en geheugenbandbreedte helpen allemaal verklaren waarom een aanpassing bij de ene werklast werkt en bij de andere minder helpt.
6.1 Kies lussen en indelingen die elke lijn gebruiken
Code die rekening houdt met de cache gebruikt opgehaalde bytes voordat hun blok wordt verdrongen. Begin met de adressen die de binnenste lus genereert. Vraag vervolgens welke gegevens opnieuw worden gebruikt, hoe ver toegangen uit elkaar liggen en of die blokken samen in de cache kunnen worden bewaard.
Doorloop arrays in opslagvolgorde
C en C++ slaan rechthoekige arrays op in rijgewijze opslagvolgorde. Aangrenzende kolommen van één rij liggen naast elkaar in het geheugen. Fortran, MATLAB en Julia gebruiken kolomgewijze opslagvolgorde; NumPy-arrays gebruiken standaard rijgewijze opslagvolgorde. Een efficiënte binnenste doorloop volgt de werkelijke indeling.
Een C-array double a[1024][1024] neemt 8 MiB in. Elke rij beslaat 8192 bytes. Bij cachelijnen van 64 bytes bevat elke lijn acht doubles. Een rijdoorloop kan alle acht gebruiken voordat die verdergaat, wat in een eenvoudig model met ophalen op verzoek ongeveer één eerste-toegangsmisser per acht toegangen geeft.
Een kolomdoorloop maakt stappen van 8192 bytes tussen opeenvolgende toegangen. Die raakt 1024 verschillende lijnen voordat nabijgelegen gegevens in de volgende kolom opnieuw worden gebruikt. Die lijnen nemen 64 KiB in en overschrijden daarmee een L1-cache van 32 KiB. Ze conflicteren ook: in een cache met 64 sets behoudt een stapgrootte van 128 lijnen de setindex. Een 8-weg set kan geen 1024 concurrerende lijnen bevatten.
Als je een rij opvult tot 1032 doubles, wordt de stapgrootte 8256 bytes, of 129 lijnen. Opeenvolgende rijen gaan dan telkens één set verder modulo 64, waardoor de verzoeken worden gespreid. Opvulling pakt afbeeldingsconflicten aan; de hoeveelheid gegevens blijft van belang.
Verwissel lussen als het resultaat behouden blijft
Verwisseling van lusvolgorde verandert welke lus binnen een andere loopt. Bij rijgewijze matrixvermenigvuldiging doorloopt de volgorde i, j, k een rij van A, maar een kolom van B. In een model met grote gegevensstromen en weinig hergebruik tussen doorgangen kost dit ongeveer missers per binnenste iteratie.
Bij i, k, j doorloopt de binnenste lus rijen van B en C, terwijl één element van A opnieuw wordt gebruikt. Als je voor beide rijen een nieuwe stroom telt, geeft dat ongeveer missers per iteratie, 4,5 keer minder. Als de herhaaldelijk bijgewerkte rij van C aanwezig blijft, nadert het aantal 0,125. Cachecapaciteit en conflicten bepalen welk hergebruik behouden blijft.
Verwisseling moet het vereiste gedrag van de berekening behouden. Afhankelijkheden, overlappende pointers en de evaluatievolgorde van drijvendekommabewerkingen kunnen aanpassingen beperken; compilers hebben bewijs nodig dat een wijziging is toegestaan.
Haal de velden op die je gebruikt
Een array van structuren groepeert alle velden van één object. Een structuur van arrays groepeert één veld over objecten heen. Als een deeltjesrecord acht doubles in één lijn van 64 bytes bevat, haalt het optellen van alleen x over één miljoen uitgelijnde records ongeveer 64 MB op. Een afzonderlijke aaneengesloten array x haalt ongeveer 8 MB op en gebruikt elke binnengehaalde double. Code die alle deeltjesvelden samen gebruikt, kan baat hebben bij de oorspronkelijke structuurindeling.
Gekoppelde knooppunten kunnen verspreid liggen en elk volgend adres kan afhangen van een zojuist geladen pointer. Aaneengesloten arrays of pools van knooppunten kunnen de lokaliteit verbeteren. Compacte veelgebruikte velden laten ook meer actieve gegevens binnen elk niveau passen.
Meet de uitvoeringstijd en relevante prestatietellers in de hardware vóór en na een wijziging. Cachemissers kunnen een langzame lus verklaren, maar berekeningen, bandbreedte of sprongen kunnen de beperkende factor zijn. Houd de invoer en resultaten vergelijkbaar zodat een snelheidsverschil de beoordeelde wijziging weerspiegelt.
Belangrijkste punten
- Stem de binnenste lus af op de opslagvolgorde van de array.
- Grote stapgroottes die een macht van twee zijn kunnen verzoeken in één set concentreren.
- Opvulling verandert de afbeelding; compacte indelingen verminderen het aantal opgehaalde bytes.
- Verwisseling van lusvolgorde moet het vereiste gedrag van de berekening behouden.
- Kies arrays van structuren of structuren van arrays op basis van de gebruikte velden.
- Meet de bottleneck en controleer resultaten wanneer je code wijzigt.
6.2 Gebruik rekenblokken opnieuw en haal gegevens vooruit op
Verwisseling van lusvolgorde verbetert de toegangsvolgorde. Blokgewijze verwerking, ook wel verwerking in rekenblokken genoemd, gaat verder door een klein gebied met gegevens actief te houden totdat het nuttige hergebruik is voltooid. Vooraf ophalen verplaatst een toekomstige overdracht naar een eerder moment, zodat de vertraging overlapt met nuttig werk.
Houd een groep rekenblokken aanwezig
Bij blokgewijze vermenigvuldiging van vierkante matrices dragen één blok van A en één blok van B bij aan één blok van C. Een blok met zijde bevat elementen. Door herhaaldelijk op deze kleine blokken te werken, worden gegevens opnieuw gebruikt voordat de verwerking naar het volgende gebied gaat.
Voor doubles van 8 bytes vereisen drie blokken bytes. In een cache van 32 KiB is de capaciteitsgrens
Een zijde van 32 gebruikt 24.576 bytes, of 24 KiB, en laat enige ruimte over voor andere gegevens. Als je 36 kiest alleen omdat de berekening dat toestaat, blijft veel minder ruimte over en kunnen conflicten optreden. Capaciteit is een eerste schatting; werkelijke blokgroottes worden op basis van metingen afgestemd.
Een blokgewijze doorloop laat de buitenste lus stappen maken ter grootte van het blok. De bovengrenzen van de binnenste lussen stoppen bij de kleinste waarde van het blokeinde en de matrixgrootte. Als een dimensie bijvoorbeeld 70 is en blokken een zijde van 32 hebben, bevat het laatste blok slechts zes elementen langs die dimensie. Een laatste blok van volledige grootte zou buiten de array toegang zoeken.
Schat wat hergebruik bespaart
In een vereenvoudigd model met grote matrices en lijnen van 64 bytes heeft de eenvoudige volgorde i, j, k ongeveer missers wanneer doorlopen rijen bij de volgende doorgang niet meer in de cache staan. Een blokgewijze versie kan dit verminderen tot ongeveer , aangenomen dat de drie gebruikte blokken in de cache blijven en zonder rekening te houden met conflicten.
Voor en zijn deze schattingen ongeveer 1,2 miljard en 8,4 miljoen missers, een factor 144. Beide versies voeren nog steeds ongeveer drijvendekommabewerkingen uit. De besparing zit in herhaalde gegevensverplaatsing, niet in het aantal rekenbewerkingen van de vermenigvuldiging. Het model beschrijft ideaal hergebruik; de gemeten versnellingsfactor hangt ook af van bandbreedte, uitvoering en andere overhead.
Haal vroeg genoeg vooraf op om latentie te verbergen
Hardware die vooraf ophaalt, herkent stromen zoals opeenvolgende toegangen of toegangen met constante stapgrootte. Die vraagt lijnen op voordat ze nodig zijn voor een toegang. Ook software kan vragen om gegevens vooraf op te halen, bijvoorbeeld met __builtin_prefetch van GCC of Clang.
Het tijdstip is van belang. Een verzoek dat te laat wordt gedaan, laat de gevraagde toegang wachten. Een verzoek dat te vroeg wordt gedaan, kan een lijn binnenhalen die vóór gebruik weer wordt verdrongen. Een onnauwkeurig verzoek verbruikt bandbreedte en cacheruimte zonder het programma te helpen. Bij het volgen van pointers is vooraf ophalen moeilijker omdat het volgende adres vaak pas bekend wordt nadat het huidige knooppunt aankomt.
Tijdig vooraf ophalen kan latere missers bij opvragen omzetten in treffers, maar de lijnen reizen nog steeds door de hiërarchie. Het verbergt latentie zonder de vereiste hoeveelheid gegevens voor een opeenvolgende doorloop te verminderen. Blokgewijze verwerking helpt wanneer waarden opnieuw worden gebruikt; een eenmalige doorloop heeft geen herhaalde gegevens om te bewaren en kan al door de geheugenbandbreedte worden begrensd.
Belangrijkste punten
- Blokgewijze verwerking houdt hergebruikte rekenblokken actief zolang hun gegevens nuttig zijn.
- Schat de opslag voor rekenblokken van alle arrays die tegelijk nodig zijn.
- Handel gedeeltelijke randblokken af met begrensde luslimieten.
- Blokgewijze verwerking vermindert gegevensverplaatsing terwijl de hoeveelheid rekenwerk behouden blijft.
- Vooraf ophalen vereist bruikbare adressen en voldoende voorsprong; onnauwkeurige verzoeken verspillen bandbreedte.
Geheugenhiërarchie en caches: voorbeelden
1Van een arraydoorloop naar een geheugenhiërarchie
13 stappen
- 1IntroductieWaarom een klein geheugen dichtbij houden?
Een processor kan veel sneller werk uitgeven dan een groot geheugen elk verzoek kan beantwoorden. Een cache helpt wanneer een programma terugkeert naar recente gegevens of nabijgelegen adressen gebruikt; dat hergebruik heet lokaliteit. Volg een arraydoorloop om te zien hoeveel één lijnvulling kan bedienen en verbind dat hergebruik daarna met de technologieën en niveaus die de gegevens leveren: de geheugenhiërarchie.
- 2UitlegOnderscheid twee soorten lokaliteit
Temporele lokaliteit gebruikt een gegeven snel opnieuw: een luslichaam wordt herhaaldelijk uitgevoerd en een lopend totaal wordt bij elke iteratie bijgewerkt. Ruimtelijke lokaliteit gebruikt nabijgelegen adressen: een opeenvolgende arraydoorloop leest aangrenzende elementen.
Een lus kan beide soorten in zijn instructiestroom hebben, ook wanneer elk array-element maar één keer wordt gelezen. Bepaal wat wordt aangesproken voordat je een soort lokaliteit toekent.
- 3VoorbeeldHoeveel levert één lijn?
Een op een blokgrens uitgelijnde array bevat 1.000 gehele getallen van elk 4 bytes. Cachelijnen bevatten 64 bytes. Elke vulling levert opeenvolgende gehele getallen. Nadat het eerste gehele getal een misser oplevert, kunnen de volgende 15 treffers opleveren. De laatste lijn hoeft niet vol te zijn: de array van 4.000 bytes heeft lijnen nodig.
- 4UitdagingVoorspel een kleinere doorloop
Een uitgelijnde array bevat 320 gehele getallen van vier bytes. Hoeveel leesbewerkingen van de array missen in een aanvankelijk lege cache die op verzoek ophaalt, met lijnen van 64 bytes, zonder verstoring en met ruimte voor de array? Welke lokaliteit levert de overige treffers op?
---reveal---
Er zijn 16 gehele getallen per lijn en lijnen, dus missen 20 leesbewerkingen. De andere 300 leveren door ruimtelijke lokaliteit treffers op. Elk element wordt één keer gebruikt; voor deze treffers is geen temporeel hergebruik van de elementen nodig.
- 5KernpuntEen werkverzameling heeft bruikbare plaatsen nodig
De werkverzameling bestaat uit de blokken die tijdens een tijdvenster worden gebruikt. Een kleine actieve verzameling kan dichtbij blijven, ook als het hele programma groot is.
Zowel capaciteit als plaatsing is van belang. Als twee actieve blokken slechts één gedeelde positie mogen gebruiken, kunnen ze elkaar verdringen terwijl andere posities leeg blijven. Lusvariabelen in registers hebben ook geen ruimte in de gegevenscache nodig, zelfs als de broncode ze herhaaldelijk leest.
- 6UitlegVergelijk geheugencellen onder spanning
SRAM bewaart een bit in een stabiele schakeling onder spanning, doorgaans met zes transistors. Het hoeft niet te worden ververst en is snel, maar kost aanzienlijk oppervlak per bit. DRAM bewaart lading op een condensator; door weglekken is verversing nodig. De compactere cellen maken het geschikt voor een groot hoofdgeheugen.
Beide zijn vluchtig. “Statisch” beschrijft hoe SRAM zijn toestand bewaart terwijl er stroom is, niet of de inhoud een stroomuitval overleeft.
- 7VoorbeeldEerst wachten, dan overdragen
DRAM activeert een rij in de rijbuffer van een bank en levert daaruit geselecteerde kolommen. Bursts en overlappende banken verhogen de leveringssnelheid. Ze nemen de initiële toegangsvertraging niet weg.
Bij 60 ns initiële latentie heeft een lijn van 64 bytes die met 16 bytes/ns wordt overgedragen nog eens 4 ns nodig. De totale afhandeling duurt ongeveer 64 ns. Het grootste deel van die wachttijd gaat vooraf aan de overdracht, ook al verplaatst de interface bytes snel.
- 8UitlegKies opslag die zijn inhoud bewaart
NAND-flashgeheugen bewaart gegevens zonder stroom. Het leest en programmeert pagina's en wist grotere blokken voordat geprogrammeerde ruimte opnieuw kan worden gebruikt. Die bewerkingen duren veel langer dan toegang tot SRAM of DRAM.
Slijtage door programmeren en wissen begrenst de levensduur van een blok. Slijtageverdeling spreidt bijwerkingen over blokken, zodat vaak gewijzigde logische gegevens niet één fysieke plaats vroegtijdig laten verslijten.
- 9UitdagingOnderscheid gegevensbehoud en verversing
Een apparaat moet gegevens bewaren nadat de stroom is uitgeschakeld. Zou het vervangen van DRAM door SRAM aan die eis voldoen? Leg uit.
---reveal---
Nee. SRAM heeft geen verversing nodig, maar verliest zonder stroom nog steeds zijn gegevens, net als DRAM. Niet-vluchtige opslag zoals flash voldoet aan de eis voor gegevensbehoud. De langzamere paginabewerkingen en de noodzaak om te wissen verklaren waarom flash een andere rol heeft dan cachegeheugen op de chip.
- 10UitlegZet de niveaus op volgorde
Registers staan het dichtst bij de uitvoering, gevolgd door L1, L2, L3, DRAM en opslag. Caches verplaatsen blokken, meestal van 64 bytes, terwijl virtueel geheugen pagina's gebruikt, meestal van 4 KiB.
L1 scheidt vaak instructie- en gegevenscaches zodat de pipeline beide tegelijk kan benaderen. Bij een misser in één niveau gaat het zoeken daaronder verder; een L1-misser kan nog steeds een L2-treffer zijn.
- 11VoorbeeldBereken de kosten van een incidentele misser
Gebruik een vereenvoudigde opzoektijd van 1 cyclus, 97% treffers en een extra vertraging van 100 cycli per misser. Elk verzoek betaalt de opzoektijd en 3% betaalt de extra vertraging:
Een misser kost hier 101 cycli. De 100 cycli zijn extra tijd, dus als je die als de volledige tijd voor een misser rekent, laat je de opzoektijd bij missers weg.
- 12UitdagingVerbind het programma met zijn gemiddelde
Twee programma's gebruiken dezelfde cache van 1 cyclus en dezelfde extra vertraging van 80 cycli. Het ene heeft 2% missers; het andere 20%. Bepaal hun gemiddelde tijden en leg uit waarom identieke hardware verschillende resultaten geeft.
---reveal---
De gemiddelden zijn en cycli. Verschillende toegangspatronen leveren verschillende misserfracties op. De cache benut de lokaliteit die elk programma biedt; de capaciteit en technologie alleen leggen het resultaat niet vast.
- 13SamenvattingBekijk een toegang op drie schalen
Bepaal bij het onderzoeken van geheugengedrag welk gegeven opnieuw wordt gebruikt, welk blok daarmee wordt overgedragen en welk niveau het levert. Lokaliteit verklaart waarschijnlijk hergebruik, geheugentechnologie verklaart kosten en capaciteit en de tijden voor treffers en missers zetten die waarnemingen om in een schatting van de toegangstijd. Begin bij een concreet programma met de werkelijke adresstroom.
2Bouw en volg een cacheopzoeking
15 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieEen adres moet twee vragen beantwoorden
- 2UitlegVerwijder eerst de byteoffset
- 3UitlegTel posities vóór indexbits
- 4UitdagingControleer een nieuwe veldindeling
- 5VoorbeeldTel de opgeslagen adrestag mee
- 6VoorbeeldBegin met een lege cache
- 7VoorbeeldZie hoe één positie van eigenaar wisselt
- 8VoorbeeldVoltooi de vervangingsreeks
- 9UitdagingVolg de toegang zonder bytes en blokken te verwarren
- 10UitlegVerdeel posities over sets
- 11VoorbeeldHoud recent gebruik bij elke toegang bij
- 12UitdagingOnderscheid LRU van FIFO
- 13KernpuntWeet wat meer posities per set kunnen opleveren
- 14UitdagingVergelijk ontwerpen met gelijke capaciteit
- 15SamenvattingHoud de toestand bij tijdens het opzoeken
3Onderzoek een misser en bewaar gewijzigde gegevens
12 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieEen misser heeft een oorzaak en een afhandelingspad
- 2UitlegHandel een wachtende leesbewerking af
- 3UitlegDeel in met de juiste vergelijking
- 4UitdagingOnderscheid vrije capaciteit van conflicten
- 5VerbandKies welke kosten je wilt verbeteren
- 6UitlegVolg een blok in een cache met terugschrijven
- 7UitlegZet opslaginstructies bij direct doorschrijven in een wachtrij
- 8UitlegStel een afzonderlijke regel in voor schrijfmissers
- 9UitdagingVolg een opslaginstructie en een latere leesbewerking
- 10VoorbeeldTel het verkeer in beide richtingen
- 11UitdagingVerbind de indeling met schrijfverkeer
- 12SamenvattingHoud de beslissingen gescheiden
4Bereken de kosten van een hiërarchie
16 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieKoppel er een noemer en een eenheid aan
- 2VoorbeeldBereken de AMAT voor één niveau
- 3TipReken om na het berekenen
- 4UitdagingGebruik een opgegeven volledige tijd voor een misser
- 5VoorbeeldWeeg de verzoeken die er zijn
- 6VoorbeeldGa van toegangen naar instructies
- 7VoorbeeldEindig met de uitvoeringstijd
- 8UitdagingVerhoog de klokfrequentie van de processor
- 9VerbandControleer of vertragingen overlappen
- 10VoorbeeldHoud lokale en globale fracties gescheiden
- 11VoorbeeldBereken de lagere afhandelingskosten
- 12VoorbeeldKeer terug naar de oorspronkelijke stroom
- 13UitdagingOnderzoek een fout in de noemer
- 14VoorbeeldVoeg nog een voorwaardelijk niveau toe
- 15UitdagingCombineer cacheverkeer met CPI
- 16SamenvattingKies het juiste niveau van berekening
5Vertaal een adres zonder opzoekingen te verwarren
15 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieEén adres, twee opzoekproblemen
- 2VoorbeeldZoek het ongewijzigde deel
- 3VoorbeeldGebruik het paginatabelitem
- 4UitdagingVertaal een andere byte
- 5UitlegOok een geldige pagina heeft toegangsrechten
- 6UitlegHandel een ontbrekende pagina af
- 7VoorbeeldSchat een vlakke tabel
- 8UitlegGebruik vertalingen in de TLB opnieuw
- 9KernpuntVolg onafhankelijke trefferresultaten
- 10UitdagingBepaal of opslag nodig is
- 11VoorbeeldBereken het vertaalbereik
- 12UitlegBegin cache-indexering tijdens de vertaling
- 13UitdagingControleer een voorgesteld L1-ontwerp
- 14VerbandMaak verouderde vertalingen ongeldig
- 15SamenvattingHoud vertaaltoestand en gegevenstoestand gescheiden
6Maak elke opgehaalde lijn nuttig
13 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieBegin met de adressen van de binnenste lus
- 2VoorbeeldGebruik alle doubles in een lijn
- 3VoorbeeldBekijk capaciteit en conflicten samen
- 4TipVerander de rijstapgrootte
- 5UitdagingKies een indeling voor de toegang
- 6UitlegVerwissel lussen om gegevensstromen te benutten
- 7UitlegHoud drie rekenblokken actief
- 8VoorbeeldLaat ruimte over naast de capaciteitsschatting
- 9UitdagingStop randblokken bij de arraygrens
- 10KernpuntOnderscheid minder overdrachten van minder rekenwerk
- 11UitlegHaal op terwijl nuttig werk doorgaat
- 12UitdagingVerklaar een kleinere versnellingsfactor dan verwacht
- 13SamenvattingTest een concrete wijziging
Geheugenhiërarchie en caches: oefenvragen
Set 1: Geheugengedrag en opzoeken in de cache10 Oefenvragen
Vraag 1 van 10
Toon antwoordVerberg antwoord
Vraag 2 van 10
Toon antwoordVerberg antwoord
Vraag 3 van 10
Toon antwoordVerberg antwoord
Vraag 4 van 10
Toon antwoordVerberg antwoord
Vraag 5 van 10
0x2B6 de positie-index en byteoffset?Toon antwoordVerberg antwoord
Vraag 6 van 10
0x00, 0x07, 0x10, 0x04, in die volgorde. Wat is de trefferfractie?Toon antwoordVerberg antwoord
Vraag 7 van 10
Toon antwoordVerberg antwoord
Vraag 8 van 10
Toon antwoordVerberg antwoord
Vraag 9 van 10
Toon antwoordVerberg antwoord
Vraag 10 van 10
0x24, 0x28, 0x64, 0x34, 0x2C, 0x68. Welke trefferfractie en welk eindblok op index 2 zijn het resultaat?Toon antwoordVerberg antwoord
Set 2: Plaatsing, missers en opslaginstructies10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
0x80 wordt gevolgd door een leesbewerking van 0x80, zonder tussentijdse toegangen. Wat gebeurt er in deze cache?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
0x00, 0x04, 0x20 en 0x24, gevolgd door een leesbewerking van 0x40. Hoeveel bytes worden tussen deze cache en het volgende niveau verplaatst als je alleen vullingen en het terugschrijven van vervangen blokken telt?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 3: Toegangstijd en programmasnelheid10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 4: Pagina's, TLB's en cache-indexering10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
0x12345 afgebeeld op fysiek paginanummer 0x2A. Wat is het fysieke byteadres?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
0x0000, 0x1000, 0x2000, 0x3000, 0x4000, in die volgorde. Alle pagina's zijn aanwezig. Wat gebeurt er na het opwarmen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 5: Codewijzigingen en afwegingen in de hiërarchie10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
a[i][j]?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Kom je niet uit je eigen opgave? Huiswerkhulp
Kernbegrippen
A
Adresruimte-identificator
Adrestag
Array van structuren
B
Bandbreedte
Basis-CPI
Blokgewijze verwerking
Blokoffset
Byteadressering
C
Cache met meerdere niveaus
Cache-index
Cachelijn
Cachemisser
Cachepositie binnen een set
Cachetoegangsregistratie
Cachetoegangstijd
Cachetoewijzing bij een schrijfmisser
Cachetreffer
Cachevervuiling
Capaciteitsmisser
Coherentiemisser
Conflictmisser
D
Direct afgebeelde cache
Direct doorschrijven
Doorlopen van de paginatabel
DRAM
E
Eerste-toegangsmisser
Extra CPI door geheugenwachtcycli
Extra vertraging bij een cachemisser
F
FIFO-vervanging
Fysiek paginanummer
G
Geen cachetoewijzing bij een schrijfmisser
Geheugenbank
Geheugenbeslag van rekenblokken
Geheugenhiërarchie
Geheugenverversing
Geldigheidsbit
Gemiddelde geheugentoegangstijd
Gewogen misserfractie
Globale misserfractie
H
Het gevraagde woord eerst
K
Klokcyclustijd
L
Latentie
Lokale misserfractie
Lokaliteit
LRU-vervanging
M
Misserfractie
N
NAND-flashgeheugen
Niet-blokkerende cache
O
Ongeldig maken van adresvertalingen
sfence.vma om de toestand van de vertaalcache af te stemmen op wijzigingen in afbeeldingen.Opvulling
P
Paginafout
Paginakader
Paginaoffset
Paginatabelitem
Pseudo-LRU
R
Rijbuffer
Rijgewijze opslagvolgorde
a[i][j] doorloop je aangrenzende elementen van één rij als je j in de binnenste lus laat variëren.Ruimtelijke lokaliteit
S
Schrijfbuffer
Set-associatieve cache
Slijtageverdeling
SRAM
Stapgrootte
Structuur van arrays
T
Temporele lokaliteit
Terugschrijven
TLB
TLB-bereik
Trefferfractie
V
Verwisseling van lusvolgorde
Virtueel geheugen
Virtueel geïndexeerde, fysiek getagde cache
Virtueel paginanummer
Volledig associatieve cache
Vooraf ophalen
Voortdurende blokverdringing
Vroegtijdig hervatten
W
Werkverzameling
Wet van Amdahl
Wijzigingsbit
- 1Computerprestaties
- 2Instructiesets en assembleertaal
- 3Rekenen met computers
- 4Datapad en pipelining
- 5Geheugenhiërarchie en caches
- 6Parallelle processors
Over deze les
Door StudeliFout melden
Maak je eigen Studiemateriaal
Maak van je aantekeningen, slides en documenten Leermodules, Oefenvragen, Flashcards en 6 andere tools.