Vahemälu on kiire juurdepääsuga vahepuhver, mis sisaldab teavet, mida kõige tõenäolisemalt küsitakse. Juurdepääs vahemälus olevatele andmetele on kiirem kui algandmete toomine töömälust (RAM) ja kiirem kui välismälust (kõvaketas või pooljuhtketas), vähendades seeläbi keskmist juurdepääsuaega ja suurendades arvutisüsteemi üldist jõudlust.

Paljudel keskprotsessori (CPU) mudelitel on oma vahemälu, et minimeerida juurdepääsu muutmälule (RAM), mis on registritest aeglasem. Vahemälu võib pakkuda märkimisväärset jõudlust, kui RAM-i taktsagedus on protsessori taktsagedusest oluliselt madalam. Vahemälu taktsagedus ei ole tavaliselt palju väiksem kui protsessori kiirus.

Vahemälu tasemed

Protsessori vahemälu on jagatud mitmeks tasemeks. Tänapäeva üldotstarbelises protsessoris võib tasemete arv ulatuda 3-ni. N+1-taseme vahemälu on tavaliselt suurema suurusega ning juurdepääsukiiruse ja andmeedastuse poolest aeglasem kui N-taseme vahemälu.

Kiireim mälu on esimese taseme vahemälu - L1-vahemälu. Tegelikult on see protsessori lahutamatu osa, kuna see asub samal kiibil ja on osa funktsionaalsetest plokkidest. Kaasaegsetes protsessorites on L1 vahemälu tavaliselt jagatud kaheks vahemälluks, käskude vahemälluks ja andmevahemälluks (Harvardi arhitektuur). Enamik protsessoreid ilma L1 vahemäluta ei saa töötada. L1 vahemälu töötab protsessori sagedusel ja üldiselt pääseb sellele juurde igal kella tsüklil. Sageli on võimalik teha korraga mitu lugemis-/kirjutustoimingut. Juurdepääsu latentsusaeg on tavaliselt 2–4 tuuma kella tsüklit. Helitugevus on tavaliselt väike - mitte rohkem kui 384 KB.

Kiireim teine ​​on L2-vahemälu – teise taseme vahemälu, mis asub tavaliselt kiibil, nagu L1. Vanemates protsessorites kiipide komplekt emaplaadil. L2 vahemälu maht 128 KB kuni 1–12 MB. Kaasaegsetes mitmetuumalistes protsessorites on teise taseme vahemälu, mis asub samal kiibil, eraldi mälu – vahemälu kogumahuga nM MB on igas tuumas nM/nC MB, kus nC on protsessori tuumade arv. Tavaliselt on tuumkiibil asuva L2 vahemälu latentsusaeg 8 kuni 20 südamiku taktitsüklit.

Kolmanda taseme vahemälu on kõige vähem kiire, kuid selle suurus võib olla väga muljetavaldav - rohkem kui 24 MB. L3 vahemälu on aeglasem kui eelmised vahemälud, kuid siiski oluliselt kiirem kui RAM. Mitmeprotsessorilistes süsteemides on see üldkasutatav ja mõeldud erinevate L2-de andmete sünkroonimiseks.

Mõnikord on ka 4. taseme vahemälu, tavaliselt asub see eraldi kiibis. 4. taseme vahemälu kasutamine on õigustatud ainult suure jõudlusega serverite ja suurarvutite puhul.

Erinevate vahemälude (nii ühe kui ka mitme protsessori) vahelise sünkroonimise probleemi lahendab vahemälu koherentsus. Teabe vahetamiseks erineva tasemega vahemälude või, nagu öeldakse, vahemäluarhitektuuride vahel on kolm võimalust: kaasav, eksklusiivne ja mittevälistav.

Kui oluline on L3 vahemälu AMD protsessorite jaoks?

Tõepoolest, on mõttekas varustada mitmetuumalised protsessorid spetsiaalse mäluga, mida jagavad kõik saadaolevad tuumad. Selles rollis võib kiire kolmanda taseme (L3) vahemälu märkimisväärselt kiirendada juurdepääsu kõige sagedamini nõutavatele andmetele. Siis ei pea südamikud võimaluse korral juurdepääsu aeglasele põhimälule (RAM).

Vähemalt teoreetiliselt. Hiljuti AMD teatas Athlon II X4 protsessor, mis on ilma L3 vahemäluta Phenom II X4 mudel, mis vihjab, et see pole nii vajalik. Otsustasime võrrelda kahte protsessorit (koos L3 vahemäluga ja ilma), et testida, kuidas vahemälu mõjutab jõudlust.

Suurendamiseks klõpsake pildil.

Kuidas vahemälu töötab?

Enne testidesse sukeldumist on oluline mõista mõningaid põhitõdesid. Vahemälu tööpõhimõte on üsna lihtne. Vahemälu puhverdab andmed protsessori töötlemistuumadele võimalikult lähedale, et vähendada protsessori päringuid kaugemasse ja aeglasemasse mällu. Kaasaegsetel töölauaplatvormidel sisaldab vahemälu hierarhia kuni kolme taset, mis eelneb RAM-ile juurdepääsule. Pealegi ei teeni teise ja eriti kolmanda taseme vahemälud mitte ainult andmete puhverdamist. Nende eesmärk on vältida protsessori siini ülekoormamist, kui tuumad peavad infot vahetama.

Tabamused ja möödalaskmised

Vahemälu arhitektuuride tõhusust mõõdetakse tabamussagedusega. Andmepäringud, mida vahemälu suudab rahuldada, loetakse tabamusteks. Kui see vahemälu ei sisalda vajalikke andmeid, edastatakse päring mööda mälukonveieri edasi ja arvestatakse möödalaskmist. Loomulikult kulub möödalaskmiste tõttu teabe hankimiseks rohkem aega. Selle tulemusena ilmuvad arvutuskonveierisse "mullid" (tühikäigud) ja viivitused. Tabamused, vastupidi, võimaldavad teil säilitada maksimaalse jõudluse.

Vahemälu sisestamine, eksklusiivsus, sidusus

Asenduspoliitikad määravad, kuidas vahemälus uute kirjete jaoks ruumi vabastatakse. Kuna vahemällu kirjutatud andmed peavad lõpuks ilmuma põhimällu, võivad süsteemid teha seda samaaegselt vahemällu kirjutamisega (läbikirjutamine) või märkida andmepiirkonnad määrdunud (tagasikirjutamine) ja kirjutada mälu.kui see vahemälust välja tõstetakse.

Mitmel vahemälutasemel olevaid andmeid saab salvestada eranditult, see tähendab ilma koondamiseta. Siis ei leia te samu andmerida kahes erinevas vahemälu hierarhias. Või vahemälu võib töötada kõikehõlmavalt, see tähendab, et alumised vahemälutasemed sisaldavad garanteeritult andmeid, mis asuvad ülemistel vahemälutasemetel (lähemal protsessori tuumale). AMD Phenom kasutab eksklusiivset L3 vahemälu, samas kui Intel järgib kaasavat vahemälu strateegiat. Sidususprotokollid tagavad andmete terviklikkuse ja värskuse eri tuumade, vahemälu tasemete ja isegi protsessorite lõikes.

Vahemälu suurus

Suurem vahemälu mahutab rohkem andmeid, kuid suurendab latentsust. Lisaks tarbib suur vahemälu märkimisväärsel hulgal protsessoritransistore, mistõttu on oluline leida tasakaal transistori eelarve, stantsi suuruse, energiatarbimise ja jõudluse/latentsuse vahel.

Assotsiatiivsus

RAM-i kirjeid saab vastendada otse vahemällu, st RAM-i andmete koopia jaoks on ainult üks vahemälu asukoht või need võivad olla n-suunalised assotsiatiivsed, st vahemälus on n võimalikku asukohta, kus see andmeid võidakse salvestada. Kõrgem assotsiatiivsuse aste (kuni täielikult assotsiatiivsete vahemäludeni) tagab suurema vahemälu paindlikkuse, kuna vahemälus olevaid andmeid ei ole vaja ümber kirjutada. Teisisõnu, kõrge n-aste assotsiatiivsus tagab suurema tabamussageduse, kuid suurendab ka latentsust, kuna kõigi nende seoste tabamuse kontrollimine võtab rohkem aega. Tavaliselt on viimase vahemällu salvestamise taseme jaoks mõistlik kõige suurem seos, kuna seal on maksimaalne maht ja väljaspool seda vahemälust andmete otsimine toob protsessoril juurdepääsu aeglasele RAM-ile.

Siin on mõned näited: Core i5 ja i7 kasutavad andmete jaoks 32 KB 8-suunalise assotsiatiivsusega L1 vahemälu ja juhiste jaoks 32 KB L1 vahemälu neljasuunalise assotsiatiivsusega. On arusaadav, et Intel soovib, et juhised oleksid kiiremini kättesaadavad ja L1 andmevahemälu maksimaalne tabamusmäär. Inteli protsessorite L2 vahemälus on 8-suunaline assotsiatiivsus ja Inteli L3 vahemälu on veelgi nutikam, kuna see rakendab tabamuste maksimeerimiseks 16-suunalist assotsiatiivsust.

Kuid AMD järgib Phenom II X4 protsessoritega teistsugust strateegiat, mis kasutab latentsuse vähendamiseks kahesuunalist assotsiatiivset L1 vahemälu. Võimalike möödalaskmiste kompenseerimiseks kahekordistati vahemälu mahtu: 64 KB andmete ja 64 KB juhiste jaoks. L2 vahemälu on 8-suunaline assotsiatiivsus, nagu Inteli disain, kuid AMD L3 vahemälu töötab 48-suunalise assotsiatiivsusega. Kuid otsust valida üks vahemäluarhitektuur teise asemel ei saa hinnata ilma kogu protsessori arhitektuuri arvestamata. On täiesti loomulik, et testitulemustel on praktiline tähendus ja meie eesmärk oli just kogu selle keeruka mitmetasandilise vahemälustruktuuri praktiline testimine.

Igal kaasaegsel protsessoril on spetsiaalne vahemälu, mis salvestab protsessori juhised ja andmed, mis on peaaegu koheselt kasutusvalmis. Seda taset nimetatakse tavaliselt Level 1 või L1 vahemälluks ja see võeti esmakordselt kasutusele 486DX protsessorites. Hiljuti on AMD protsessorite standardseks saanud 64 KB L1 vahemälu tuuma kohta (andmete ja juhiste jaoks) ning Inteli protsessorid kasutavad 32 KB L1 vahemälu tuuma kohta (ka andmete ja juhiste jaoks).

L1 vahemälu ilmus esmakordselt 486DX protsessoritele, pärast mida sai sellest kõigi kaasaegsete protsessorite lahutamatu funktsioon.

Teise taseme vahemälu (L2) ilmus kõikidele protsessoritele pärast Pentium III väljaandmist, kuigi selle esimesed rakendused pakendil olid Pentium Pro protsessoris (kuid mitte kiibil). Kaasaegsed protsessorid on varustatud kuni 6 MB L2-kiibi vahemäluga. Reeglina jagatakse see maht näiteks Intel Core 2 Duo protsessori kahe tuuma vahel. Tüüpilised L2 konfiguratsioonid pakuvad 512 KB või 1 MB vahemälu tuuma kohta. Väiksema L2 vahemäluga protsessorid kipuvad olema madalamal hinnatasemel. Allpool on diagramm varajastest L2 vahemälu rakendustest.

Pentium Pro-l oli L2 vahemälu protsessori pakendis. Järgmistes Pentium III ja Athloni põlvkondades rakendati L2 vahemälu eraldi SRAM-kiipide kaudu, mis oli tol ajal väga levinud (1998, 1999).

Hilisem väljakuulutamine kuni 180 nm protsessitehnoloogiast võimaldas tootjatel lõpuks integreerida L2 vahemälu protsessori stantsi.


Esimesed kahetuumalised protsessorid kasutasid lihtsalt olemasolevaid kujundusi, mis sisaldasid kahte stantsi pakendi kohta. AMD tutvustas monoliitkiibil kahetuumalist protsessorit, lisas mälukontrolleri ja lüliti ning Intel pani oma esimese kahetuumalise protsessori jaoks lihtsalt ühte paketti kokku kaks ühetuumalist kiipi.


Esimest korda hakati L2 vahemälu jagama Core 2 Duo protsessorite kahe andmetöötlustuuma vahel. AMD läks kaugemale ja lõi oma esimese neljatuumalise Phenomi nullist ning Intel kasutas oma esimese neljatuumalise protsessori jaoks kulude vähendamiseks taas paari stantsi, seekord kahte kahetuumalist Core 2 stantsi.

Kolmanda taseme vahemälu on eksisteerinud Alpha 21165 protsessori (96 KB, protsessorid tutvustati 1995. aastal) või IBM Power 4 (256 KB, 2001) algusaegadest. Kuid x86-põhistes arhitektuurides ilmus L3 vahemälu esmakordselt Intel Itanium 2, Pentium 4 Extreme (Gallatin, mõlemad protsessorid aastal 2003) ja Xeon MP (2006) mudelitega.

Varased juurutused andsid vahemälu hierarhias lihtsalt uue taseme, kuigi tänapäevased arhitektuurid kasutavad L3 vahemälu suure jagatud puhvrina tuumadevaheliseks andmeedastuseks mitmetuumalistes protsessorites. Seda rõhutab assotsiatiivsuse kõrge n-aste. Parem on otsida andmeid vahemälust veidi kauem kui sattuda olukorrani, kus mitu tuuma kasutavad väga aeglast juurdepääsu põhimälule. AMD tutvustas esmakordselt L3 vahemälu lauaarvuti protsessoris koos juba mainitud Phenom liiniga. 65 nm Phenom X4 sisaldas 2 MB jagatud L3 vahemälu ja kaasaegsel 45 nm Phenom II X4-l on juba 6 MB jagatud L3 vahemälu. Intel Core i7 ja i5 protsessorid kasutavad 8 MB L3 vahemälu.

Kaasaegsetel neljatuumalistel protsessoritel on iga tuuma jaoks eraldi L1 ja L2 vahemälu, samuti suur L3 vahemälu, mida jagavad kõik tuumad. Jagatud L3 vahemälu võimaldab ka andmevahetust, millega tuumad saavad paralleelselt töötada.


Kui oluline on L3 vahemälu AMD protsessorite jaoks?

Tõepoolest, on mõttekas varustada mitmetuumalised protsessorid spetsiaalse mäluga, mida jagavad kõik saadaolevad tuumad. Selles rollis võib kiire kolmanda taseme (L3) vahemälu märkimisväärselt kiirendada juurdepääsu kõige sagedamini nõutavatele andmetele. Siis ei pea südamikud võimaluse korral juurdepääsu aeglasele põhimälule (RAM).

Vähemalt teoreetiliselt. AMD teatas hiljuti Athlon II X4 protsessorist, mis on Phenom II X4 mudel ilma L3 vahemäluta, vihjates, et see pole nii vajalik. Otsustasime võrrelda kahte protsessorit (koos L3 vahemäluga ja ilma), et testida, kuidas vahemälu mõjutab jõudlust.

Kuidas vahemälu töötab?

Enne testidesse sukeldumist on oluline mõista mõningaid põhitõdesid. Vahemälu tööpõhimõte on üsna lihtne. Vahemälu puhverdab andmed protsessori töötlemistuumadele võimalikult lähedale, et vähendada protsessori päringuid kaugemasse ja aeglasemasse mällu. Kaasaegsetel töölauaplatvormidel sisaldab vahemälu hierarhia kuni kolme taset, mis eelneb RAM-ile juurdepääsule. Pealegi ei teeni teise ja eriti kolmanda taseme vahemälud mitte ainult andmete puhverdamist. Nende eesmärk on vältida protsessori siini ülekoormamist, kui tuumad peavad infot vahetama.

Tabamused ja möödalaskmised

Vahemälu arhitektuuride tõhusust mõõdetakse tabamussagedusega. Andmepäringud, mida vahemälu suudab rahuldada, loetakse tabamusteks. Kui see vahemälu ei sisalda vajalikke andmeid, edastatakse päring mööda mälukonveieri edasi ja arvestatakse möödalaskmist. Loomulikult kulub möödalaskmiste tõttu teabe hankimiseks rohkem aega. Selle tulemusena ilmuvad arvutuskonveierisse "mullid" (tühikäigud) ja viivitused. Tabamused, vastupidi, võimaldavad teil säilitada maksimaalse jõudluse.

Vahemälu sisestamine, eksklusiivsus, sidusus

Asenduspoliitikad määravad, kuidas vahemälus uute kirjete jaoks ruumi vabastatakse. Kuna vahemällu kirjutatud andmed peavad lõpuks ilmuma põhimällu, võivad süsteemid teha seda samaaegselt vahemällu kirjutamisega (läbikirjutamine) või märkida andmepiirkonnad määrdunud (tagasikirjutamine) ja kirjutada mälu.kui see vahemälust välja tõstetakse.

Mitmel vahemälutasemel olevaid andmeid saab salvestada eranditult, see tähendab ilma koondamiseta. Siis ei leia te samu andmerida kahes erinevas vahemälu hierarhias. Või vahemälu võib töötada kõikehõlmavalt, see tähendab, et alumised vahemälutasemed sisaldavad garanteeritult andmeid, mis asuvad ülemistel vahemälutasemetel (lähemal protsessori tuumale). AMD Phenom kasutab eksklusiivset L3 vahemälu, samas kui Intel järgib kaasavat vahemälu strateegiat. Sidususprotokollid tagavad andmete terviklikkuse ja värskuse eri tuumade, vahemälu tasemete ja isegi protsessorite lõikes.

Vahemälu suurus

Suurem vahemälu mahutab rohkem andmeid, kuid suurendab latentsust. Lisaks tarbib suur vahemälu märkimisväärsel hulgal protsessoritransistore, mistõttu on oluline leida tasakaal transistori eelarve, stantsi suuruse, energiatarbimise ja jõudluse/latentsuse vahel.

Assotsiatiivsus

RAM-i kirjeid saab vastendada otse vahemällu, st RAM-i andmete koopia jaoks on ainult üks vahemälu asukoht või need võivad olla n-suunalised assotsiatiivsed, st vahemälus on n võimalikku asukohta, kus see andmeid võidakse salvestada. Kõrgem assotsiatiivsuse aste (kuni täielikult assotsiatiivsete vahemäludeni) tagab suurema vahemälu paindlikkuse, kuna vahemälus olevaid andmeid ei ole vaja ümber kirjutada. Teisisõnu, kõrge n-aste assotsiatiivsus tagab suurema tabamussageduse, kuid suurendab ka latentsust, kuna kõigi nende seoste tabamuse kontrollimine võtab rohkem aega. Tavaliselt on viimase vahemällu salvestamise taseme jaoks mõistlik kõige suurem seos, kuna seal on maksimaalne maht ja väljaspool seda vahemälust andmete otsimine toob protsessoril juurdepääsu aeglasele RAM-ile.

Siin on mõned näited: Core i5 ja i7 kasutavad andmete jaoks 32 KB 8-suunalise assotsiatiivsusega L1 vahemälu ja juhiste jaoks 32 KB L1 vahemälu neljasuunalise assotsiatiivsusega. On arusaadav, et Intel soovib, et juhised oleksid kiiremini kättesaadavad ja L1 andmevahemälu maksimaalne tabamusmäär. Inteli protsessorite L2 vahemälus on 8-suunaline assotsiatiivsus ja Inteli L3 vahemälu on veelgi nutikam, kuna see rakendab tabamuste maksimeerimiseks 16-suunalist assotsiatiivsust.

Kuid AMD järgib Phenom II X4 protsessoritega teistsugust strateegiat, mis kasutab latentsuse vähendamiseks kahesuunalist assotsiatiivset L1 vahemälu. Võimalike möödalaskmiste kompenseerimiseks kahekordistati vahemälu mahtu: 64 KB andmete ja 64 KB juhiste jaoks. L2 vahemälu on 8-suunaline assotsiatiivsus, nagu Inteli disain, kuid AMD L3 vahemälu töötab 48-suunalise assotsiatiivsusega. Kuid otsust valida üks vahemäluarhitektuur teise asemel ei saa hinnata ilma kogu protsessori arhitektuuri arvestamata. On täiesti loomulik, et testitulemustel on praktiline tähendus ja meie eesmärk oli just kogu selle keeruka mitmetasandilise vahemälustruktuuri praktiline testimine.

Peaaegu kõik arendajad teavad, et protsessori vahemälu on väike, kuid kiire mälu, mis salvestab andmeid hiljuti külastatud mälupiirkondadest – definitsioon on lühike ja üsna täpne. Vahemälu mehhanismide igavate üksikasjade tundmine on aga vajalik koodi jõudlust mõjutavate tegurite mõistmiseks.

Selles artiklis vaatleme mitmeid näiteid, mis illustreerivad vahemälu erinevaid funktsioone ja nende mõju jõudlusele. Näited on C# keeles, keele ja platvormi valik ei mõjuta oluliselt tulemuslikkuse hindamist ja lõppjäreldusi. Loomulikult ei saa te mõistlike piiride piires tõlgendatavaid tulemusi, kui valite keele, milles massiivist väärtuse lugemine võrdub räsitabelile juurdepääsuga. Tõlkija märkmed on kaldkirjas.

Habracut - - -

Näide 1: Mälu juurdepääs ja jõudlus

Kui palju kiirem on teie arvates teine ​​tsükkel kui esimene?
int arr = uus int;

// esiteks
jaoks (int i = 0; i< arr.Length; i++) arr[i] *= 3;

// sekund
jaoks (int i = 0; i< arr.Length; i += 16) arr[i] *= 3;


Esimene tsükkel korrutab kõik massiivi väärtused 3-ga, teine ​​silmus korrutab ainult iga kuueteistkümnenda väärtuse. Teine tsükkel saab alles lõpule 6% töötab esimene tsükkel, kuid tänapäevastel masinatel täidetakse mõlemad tsüklid ligikaudu võrdse ajaga: 80 ms Ja 78 ms vastavalt (minu masinal).

Lahendus on lihtne – juurdepääs mälule. Nende silmuste kiiruse määrab eelkõige mälu alamsüsteemi kiirus, mitte täisarvude korrutamise kiirus. Nagu näeme järgmises näites, on RAM-i juurdepääsude arv nii esimesel kui ka teisel juhul sama.

Näide 2: vahemälu ridade mõju

Kaevame sügavamale ja proovime teisi astmeväärtusi, mitte ainult 1 ja 16:
jaoks (int i = 0; i< arr.Length; i += K /* шаг */ ) arr[i] *= 3;

Siin on selle ahela tööajad erinevate sammuväärtuste K jaoks:

Pange tähele, et astmeväärtustega 1 kuni 16 jääb tööaeg praktiliselt muutumatuks. Kuid väärtuste puhul, mis on suuremad kui 16, väheneb tööaeg umbes poole võrra iga kord, kui sammu kahekordistame. See ei tähenda, et tsükkel kuidagi võluväel kiiremini jooksma hakkaks, lihtsalt väheneb ka iteratsioonide arv. Võtmepunkt on sama tööaeg sammuväärtustega 1 kuni 16.

Põhjus on selles, et kaasaegsed protsessorid ei pääse mälule ligi ühe baidi kaupa, vaid pigem väikestes plokkides, mida nimetatakse vahemälu ridadeks. Tavaliselt on stringi suurus 64 baiti. Kui loete mis tahes väärtust mälust, satub vahemällu vähemalt üks vahemälu rida. Hilisem juurdepääs mis tahes väärtusele sellelt realt on väga kiire.

Kuna 16 int väärtust hõivavad 64 baiti, pääsevad tsüklid sammudega 1 kuni 16 juurde samale arvule vahemälu ridadele või täpsemalt massiivi kõikidele vahemälu ridadele. Sammus 32 toimub juurdepääs igale teisele reale, sammus 64 igale neljandale reale.

Selle mõistmine on mõne optimeerimistehnika puhul väga oluline. Juurdepääsude arv sellele sõltub andmete asukohast mälus. Näiteks võivad joondamata andmed vajada kahte juurdepääsu põhimälule ühe asemel. Nagu ülalpool teada saime, on töökiirus kaks korda väiksem.

Näide 3: 1. ja 2. taseme vahemälu suurused (L1 ja L2)

Kaasaegsetel protsessoritel on tavaliselt kaks või kolm vahemälu taset, mida tavaliselt nimetatakse L1, L2 ja L3. Erinevatel tasemetel vahemälu suuruste väljaselgitamiseks võite kasutada utiliiti CoreInfo või Windows API funktsiooni GetLogicalProcessorInfo. Mõlemad meetodid pakuvad teavet ka vahemälu rea suuruse kohta igal tasemel.

Minu masinas teatab CoreInfo 32 KB L1 andmevahemälu, 32 KB L1 käsu vahemälu ja 4 MB L2 andmevahemälu. Igal tuumal on oma isiklikud L1 vahemälud, L2 vahemälu jagab iga tuumapaar:

Loogiline protsessor vahemälu kaardile: *--- Andmevahemälu 0, tase 1, 32 KB, Assoc 8, LineSize 64 *--- Käskude vahemälu 0, tase 1, 32 KB, Assoc 8, LineSize 64 --*-- Andmevahemälu 1, tase 1, 32 kB, assoc 8, LineSize 64 -*-- juhiste vahemälu 1, tase 1, 32 KB, assoc 8, LineSize 64 **-- ühendatud vahemälu 0, tase 2, 4 MB, assoc 16, LineS 64 --*- Andmevahemälu 2, tase 1, 32 KB, Assoc 8, LineSize 64 --*- Käskude vahemälu 2, tase 1, 32 KB, Assoc 8, LineSize 64 ---* Andmevahemälu 3, tase 1, 32 KB, Assoc 8, LineSize 64 ---* Käskude vahemälu 3, tase 1, 32 KB, Assoc 8, LineSize 64 --** Unified Cache 1, Level 2, 4 MB, Assoc 16, LineSize 64
Kontrollime seda teavet eksperimentaalselt. Selleks käime läbi oma massiivi, suurendades iga 16. väärtust – see on lihtne viis vahemälu igal real olevate andmete muutmiseks. Kui jõuame lõppu, pöördume tagasi algusesse. Kontrollime erinevaid massiivi suurusi; peaksime nägema jõudluse langust, kui massiiv ei mahu enam erinevate tasemete vahemäludesse.

Kood on:

int sammud = 64 * 1024 * 1024; // iteratsioonide arv
int pikkusMod = arr.Pikkus - 1; // massiivi suurus -- kahe võimsus

jaoks (int i = 0; i< steps; i++)
{
// x & pikkusMod = x % arr.Pikkus, sest kahe astmed
arr[(i * 16) & pikkusMod]++;
}


Testi tulemused:

Minu masinas on märgatav jõudluse langus pärast 32 KB ja 4 MB – need on L1 ja L2 vahemälu suurused.

Näide 4: juhiste paralleelsus

Vaatame nüüd midagi muud. Milline neist kahest tsüklist teie arvates töötab kiiremini?
int sammud = 256 * 1024 * 1024;
int a = uus int ;

// esiteks
jaoks (int i = 0; i< steps; i++) { a++; a++; }

// sekund
jaoks (int i = 0; i< steps; i++) { a++; a++; }


Selgub, et teine ​​silmus töötab peaaegu kaks korda kiiremini, vähemalt kõigil minu testitud masinatel. Miks? Kuna tsüklite sees olevatel käskudel on erinev andmesõltuvus. Esimestel käskudel on järgmine sõltuvuste ahel:

Teises tsüklis on sõltuvused järgmised:

Kaasaegsete protsessorite funktsionaalsed osad on võimelised üheaegselt sooritama teatud arvu teatud toiminguid, tavaliselt mitte väga suurt hulka. Näiteks on võimalik paralleelne ligipääs L1 vahemälu andmetele kahel aadressil ning võimalik on ka kahe lihtsa aritmeetilise käsu samaaegne täitmine. Esimeses tsüklis ei saa protsessor neid võimalusi kasutada, teises aga saab.

Näide 5: vahemälu assotsiatiivsus

Üks võtmeküsimusi, millele vahemälu kujundamisel tuleb vastata, on see, kas teatud mälupiirkonna andmeid saab salvestada suvalistesse vahemälu lahtritesse või ainult mõnda neist. Kolm võimalikku lahendust:
  1. Otsese kaardistamise vahemälu Iga RAM-i vahemälurea andmed salvestatakse ainult ühte eelmääratletud vahemälu asukohta. Lihtsaim viis vastenduse arvutamiseks on: row_index_in_memory % vahemälu_rakkude_arv. Kaks samasse lahtrisse vastendatud rida ei saa korraga vahemälus olla.
  2. N-kirje osaline assotsiatiivne vahemälu, saab iga rida salvestada N erinevasse vahemälu asukohta. Näiteks 16-kirjelises vahemälus võib rida salvestada ühte 16 lahtrist, mis moodustavad rühma. Tavaliselt jagavad read, millel on võrdsed vähima tähtsusega indeksite bitid, ühte rühma.
  3. Täielikult assotsiatiivne vahemälu, saab iga rida salvestada mis tahes vahemälu asukohta. Lahendus on oma käitumiselt samaväärne räsitabeliga.
Otsekaardistatud vahemälud on altid tülile, näiteks kui kaks rida võistlevad sama lahtri pärast, ajavad teineteist vahemälust vaheldumisi välja, on efektiivsus väga madal. Teisest küljest on täielikult assotsiatiivsed vahemälud, kuigi sellest puudusest vabad, väga keerulised ja nende rakendamine kulukas. Osaliselt assotsiatiivsed vahemälud on tüüpiline kompromiss rakendamise keerukuse ja tõhususe vahel.

Näiteks minu masinas on 4 MB L2 vahemälu 16 kirjega osaliselt assotsiatiivne vahemälu. Kogu RAM on jagatud ridade komplektideks vastavalt nende indeksite kõige vähem olulistele bittidele, iga komplekti read võistlevad ühe 16 L2 vahemälu lahtri rühma pärast.

Kuna L2 vahemälus on 65 536 lahtrit (4 * 2 20 / 64) ja iga rühm koosneb 16 lahtrist, on meil kokku 4096 rühma. Seega määravad reaindeksi alumised 12 bitti, millisesse rühma see rida kuulub (2 12 = 4 096). Selle tulemusena jagavad read, mille aadressid on 262 144 (4096 * 64) kordsed, sama 16 lahtri rühma ja võistlevad selles ruumi pärast.

Assotsiatiivsuse mõju avaldamiseks peame pidevalt juurde pääsema suurele hulgale ridadele samast rühmast, kasutades näiteks järgmist koodi:

avalik staatiline pikk UpdateEveryKth Byte (bait arr, int K)
{
const int rep = 1024 * 1024; // iteratsioonide arv

Stopper sw = Stopper.StartNew();

int p = 0;
jaoks (int i = 0; i< rep; i++)
{
arr[p]++;

P += K; if (p >= arr.Pikkus) p = 0;
}

Sw.Stop();
return sw.ElapsedMilliseconds;
}


Meetod suurendab massiivi iga K-ndat elementi. Kui jõuame lõppu, alustame uuesti. Pärast üsna suurt arvu iteratsioone (2 20) lõpetame. Tegin jookse erinevate massiivi suuruste ja K sammu väärtuste jaoks. Tulemused (sinine - pikk tööaeg, valge - lühike):

Sinised alad vastavad nendele juhtudele, kui pidevate andmete muutumise korral ei suuda vahemälu mahutada kõik vajalikud andmed korraga. Helesinine värv näitab tööaega umbes 80 ms, peaaegu valge - 10 ms.

Tegeleme siniste aladega:

  1. Miks ilmuvad vertikaalsed jooned? Vertikaalsed jooned vastavad sammuväärtustele, mille puhul pääseb juurde liiga paljudele ridadele (üle 16) ühest rühmast. Nende väärtuste puhul ei mahu minu masina 16-kirjeline vahemälu kõiki vajalikke andmeid.

    Mõned halva sammu väärtused on kahe astmed: 256 ja 512. Näiteks kaaluge sammu 512 ja 8 MB massiivi. Selle sammuga on massiivis 32 jaotist (8 * 2 20 / 262 144), mis konkureerivad üksteisega 512 vahemälurühma (262 144 / 512) lahtrite pärast. Sektsioone on 32, kuid iga rühma jaoks on vahemälus ainult 16 lahtrit, nii et kõigile ei jätku ruumi.

    Teised sammuväärtused, mis ei ole kahe astmed, on lihtsalt õnnetud, mis põhjustab samadele vahemälurühmadele suure hulga tabamust ja toob kaasa ka vertikaalsete siniste joonte ilmumise joonisele. Siinkohal kutsutakse arvuteooria austajaid mõtlema.

  2. Miks vertikaalsed jooned katkevad 4 MB piiril? Kui massiivi suurus on 4 MB või vähem, käitub 16-kirjega vahemälu täielikult assotsieeruva vahemäluna, see tähendab, et see mahutab kõik massiivi andmed ilma konfliktideta. Ühe vahemälurühma eest võitleb kuni 16 ala (262 144 * 16 = 4 * 2 20 = 4 MB).
  3. Miks on vasakus ülanurgas suur sinine kolmnurk? Sest väikese sammu ja suure massiiviga ei mahu vahemälu kõiki vajalikke andmeid. Vahemälu assotsiatiivsuse aste mängib siin teisejärgulist rolli; piirang on seotud L2 vahemälu suurusega.

    Näiteks massiivi suuruse 16 MB ja sammuga 128 korral pääseme ligi igale 128. baidile, muutes seega iga teist massiivi vahemälu rida. Vahemällu iga teise rea salvestamiseks vajate 8 MB vahemälu, kuid minu masinas on ainult 4 MB.

    Isegi kui vahemälu oleks täielikult assotsiatiivne, ei võimaldaks see sellesse salvestada 8 MB andmeid. Pange tähele, et juba käsitletud näites sammuga 512 ja massiivi suurusega 8 MB vajame kõigi vajalike andmete salvestamiseks vaid 1 MB vahemälu, kuid vahemälu ebapiisava assotsiatiivsuse tõttu on see võimatu.

  4. Miks kasvab kolmnurga vasak pool järk-järgult intensiivsust? Maksimaalne intensiivsus saavutatakse sammu väärtusel 64 baiti, mis on võrdne vahemälu rea suurusega. Nagu nägime esimeses ja teises näites, ei maksa järjestikune juurdepääs samale reale praktiliselt midagi. Oletame, et 16-baidise sammuga on meil neli mälupääsu ühe hinnaga.

    Kuna iteratsioonide arv on meie testis mis tahes sammu väärtuse jaoks sama, vähendab odavam samm tööaega.

Avastatud mõjud püsivad suurte parameetriväärtuste juures:

Vahemälu assotsiatiivsus on huvitav asi, mis võib teatud tingimustel avalduda. Erinevalt teistest selles artiklis käsitletud probleemidest pole see nii tõsine. See ei ole kindlasti midagi, mis programmide kirjutamisel pidevalt tähelepanu nõuab.

Näide 6: Vale vahemälu partitsioonid

Mitmetuumaliste masinate puhul võib tekkida veel üks probleem – vahemälu sidusus. Protsessori tuumadel on osaliselt või täielikult eraldi vahemälud. Minu masinal on L1 vahemälud eraldi (nagu tavaliselt) ja iga tuumapaar jagab ka kahte L2 vahemälu. Üksikasjad võivad erineda, kuid üldiselt on tänapäevastel mitmetuumalistel protsessoritel mitmetasandiline hierarhiline vahemälu. Pealegi kuuluvad kiireimad, aga ka väikseimad vahemälud üksikutele tuumadele.

Kui üks tuum muudab väärtust oma vahemälus, ei saa teised tuumad enam vana väärtust kasutada. Teiste tuumade vahemälu väärtust tuleb värskendada. Lisaks tuleb ajakohastada kogu vahemälu rida, kuna vahemälud töötavad andmetel rea tasemel.

Näitame seda probleemi järgmise koodiga:

privaatne staatiline int s_counter = uus int ;

privaatne tühine Värskendusloendur(int position)
{
jaoks (int j = 0; j< 100000000; j++)
{
s_loendur = s_loendur + 3;
}
}


Kui oma neljatuumalisel masinal kutsun seda meetodit parameetritega 0, 1, 2, 3 korraga neljast lõimest, siis tööaeg on 4,3 sekundit. Aga kui ma kutsun meetodit parameetritega 16, 32, 48, 64, siis on tööaeg ainult 0,28 sekundit.

Miks? Esimesel juhul jõuavad kõik neli lõimede poolt igal ajahetkel töödeldud väärtust tõenäoliselt ühele vahemälureale. Iga kord, kui üks tuum väärtust suurendab, märgib see teistes tuumades seda väärtust sisaldavad vahemälurakud kehtetuks. Pärast seda toimingut peavad kõik teised tuumad rea uuesti vahemällu salvestama. See muudab vahemällu salvestamise mehhanismi töövõimetuks, hävitades jõudluse.

Näide 7: riistvara keerukus

Isegi praegu, kui vahemälu tööpõhimõtted pole teile saladus, pakub riistvara teile endiselt üllatusi. Protsessorid erinevad üksteisest optimeerimismeetodite, heuristika ja muude rakendamise peensuste poolest.

Mõne protsessori L1 vahemälu pääseb paralleelselt ligi kahele lahtrile, kui need kuuluvad erinevatesse rühmadesse, kuid kui nad kuuluvad samasse rühma, siis ainult järjestikku. Minu teada pääsevad mõned isegi paralleelselt sama lahtri erinevatesse kvartalitesse.

Protsessorid võivad teid üllatada nutikate optimeerimistega. Näiteks eelmise näite kood vale vahemälu jagamise kohta ei tööta minu koduarvutis nii, nagu ette nähtud – kõige lihtsamal juhul suudab protsessor tööd optimeerida ja negatiivseid mõjusid vähendada. Kui muudate koodi veidi, loksub kõik paika.

Siin on veel üks näide veidratest riistvaralistest veidrustest:

privaatne staatiline int A, B, C, D, E, F, G;

privaatne staatiline tühimik Imelikkus()
{
jaoks (int i = 0; i< 200000000; i++)
{
<какой-то код>
}
}


Kui selle asemel<какой-то код>Asendades kolm erinevat valikut, võite saada järgmised tulemused.

Väljade A, B, C, D suurendamine võtab kauem aega kui väljade A, C, E, G suurendamine. Veelgi veidram on see, et väljade A ja C suurendamine võtab kauem aega kui väljade A, C suurendamine. Ja E, G. Ma ei tea täpselt, mis selle põhjused on, aga võib-olla on need seotud mälupankadega ( jah, jah, tavaliste kolmeliitriste säästumälupankadega ja mitte see, mida sa arvasid). Kui teil on selles küsimuses mõtteid, rääkige kommentaarides.

Minu masinas ülaltoodut ei täheldata, kuid mõnikord on ebaharilikult halbu tulemusi - tõenäoliselt teeb ülesannete planeerija oma "kohandused".

Sellest näitest saab õppida, et riistvara käitumist on väga raske täielikult ennustada. jah, Saab ennustada palju, kuid peate oma ennustusi mõõtmiste ja katsete abil pidevalt kinnitama.

Järeldus

Loodan, et kõik ülalpool käsitletu on aidanud teil mõista protsessori vahemälu kujundust. Nüüd saate neid teadmisi oma koodi optimeerimiseks praktikas rakendada.

Enamiku moodsate lauaarvutite kiibid on neljatuumalised, kuid kiibitootjad on juba teatanud plaanist minna üle kuuetuumalisele ning 16-tuumalised protsessorid pole tipptasemel serverite puhul tänapäevalgi haruldased.

Mida rohkem tuumasid on, seda suurem on probleem mälu jaotamisel kõigi tuumade vahel, samal ajal koos töötades. Tuumade arvu suurenemisega on järjest kasulikum minimeerida tuumade haldamisele kuluvat aega andmete töötlemisel – sest andmevahetuse kiirus jääb protsessori kiirusest ja mälus andmete töötlemisest maha. Saate füüsiliselt juurde pääseda kellegi teise kiirele vahemällule või pääsete juurde oma aeglasele, kuid säästate andmeedastusaega. Ülesande teeb keeruliseks asjaolu, et programmide nõutav mälumaht ei vasta selgelt igat tüüpi vahemälu mahule.

Füüsiliselt saab protsessorile võimalikult lähedale paigutada vaid väga piiratud hulga mälu – protsessori L1 vahemälu, mille maht on äärmiselt tühine. Massachusettsi Tehnoloogiainstituudi arvutiteaduse ja tehisintellekti laboratooriumi teadlased Daniel Sanchez, Po-An Tsai ja Nathan Beckmann õpetasid arvutit konfigureerima erinevat tüüpi mälu, et luua reaalajas paindlik programmide hierarhia. Uus süsteem nimega Jenga analüüsib programmide mälule juurdepääsu mahulisi vajadusi ja sagedust ning jaotab ümber kõigi kolme tüüpi protsessori vahemälu võimsuse kombinatsioonides, mis tagavad suurema tõhususe ja energiasäästu.


Alustuseks testisid teadlased jõudluse suurenemist staatilise ja dünaamilise mälu kombineerimisel ühetuumalise protsessori programmide kallal töötades ja said esmase hierarhia - millal on parem kasutada millist kombinatsiooni. 2 tüüpi mälust või ühest. Hinnati kahte parameetrit: signaali viivitust (latentsust) ja energiatarbimist iga programmi töö ajal. Ligikaudu 40% programmidest hakkas mälutüüpide kombinatsiooniga halvemini töötama, ülejäänud - paremini. Olles registreerinud, millistele programmidele "meeldib" segatud jõudlus ja millistele meeldib mälumaht, ehitasid teadlased oma Jenga süsteemi.

Nad testisid virtuaalselt 4 tüüpi programme 36 tuumaga virtuaalarvutis. Testitud programmid:

  • omnet – Objective Modular Network Testbed, C-simulatsiooniteek ja võrgusimulatsioonitööriistade platvorm (pildil sinine)
  • mcf – metasisu raamistik (punane)
  • astar – virtuaalse reaalsuse kuvatarkvara (roheline)
  • bzip2 - arhiveerija (lilla värv)


Pildil on näha, kus ja kuidas iga programmi andmeid töödeldi. Tähed näitavad, kus iga rakendus töötab (üks kvadrandi kohta), värvid näitavad, kus selle andmed asuvad, ja varjutus näitab virtuaalse hierarhia teist taset, kui see on olemas.

Vahemälu tasemed

Protsessori vahemälu on jagatud mitmeks tasemeks. Universaalsete protsessorite jaoks - kuni 3. Kiireim mälu on esimese taseme vahemälu - L1-vahemälu, kuna see asub protsessoriga samal kiibil. Koosneb juhiste vahemälust ja andmevahemälust. Mõned protsessorid ilma L1 vahemäluta ei saa töötada. L1 vahemälu töötab protsessori sagedusel ja sellele pääseb juurde igal kellatsüklil. Sageli on võimalik teha korraga mitu lugemis-/kirjutustoimingut. Helitugevus on tavaliselt väike - mitte rohkem kui 128 KB.

Teise taseme vahemälu L2 suhtleb L1 vahemäluga. See on kiiruselt teine. Tavaliselt asub see kas kiibil, nagu L1, või südamiku vahetus läheduses, näiteks protsessori kassetis. Vanemates protsessorites kiipide komplekt emaplaadil. L2 vahemälu maht 128 KB kuni 12 MB. Kaasaegsetes mitmetuumalistes protsessorites on samal kiibil asuv teise taseme vahemälu eraldi mälu - vahemälu kogumahuga 8 MB, iga tuum moodustab 2 MB. Tavaliselt on tuumkiibil asuva L2 vahemälu latentsusaeg 8 kuni 20 südamiku taktitsüklit. Ülesannetes, mis hõlmavad arvukalt juurdepääsu piiratud mälualale, näiteks DBMS, suurendab selle täielik kasutamine tootlikkust kümme korda.

L3 vahemälu on tavaliselt isegi suurem, kuigi mõnevõrra aeglasem kui L2 vahemälu (tingituna sellest, et siin L2 ja L3 vahel on kitsam kui L1 ja L2 vaheline siin). L3 asub tavaliselt CPU tuumast eraldi, kuid võib olla suur – üle 32 MB. L3 vahemälu on aeglasem kui eelmised vahemälud, kuid siiski kiirem kui RAM. Mitmeprotsessorilistes süsteemides on see laialt levinud. Kolmanda taseme vahemälu kasutamine on õigustatud väga kitsas tööülesannete hulgas ja see ei pruugi mitte ainult mitte suurendada jõudlust, vaid, vastupidi, viia süsteemi jõudluse üldise vähenemiseni.

Teise ja kolmanda taseme vahemälu keelamine on kõige kasulikum matemaatiliste ülesannete puhul, kui andmemaht on vahemälu suurusest väiksem. Sel juhul saate laadida kõik andmed L1 vahemällu korraga ja seejärel töödelda.


Jenga konfigureerib perioodiliselt ümber virtuaalseid hierarhiaid OS-i tasemel, et minimeerida andmevahetust, võttes arvesse ressursside piiranguid ja rakenduste käitumist. Iga ümberseadistamine koosneb neljast etapist.

Jenga jagab andmeid mitte ainult olenevalt sellest, milliseid programme saadetakse – need, mis armastavad suurt ühekiiruselist mälu või need, mis armastavad segavahemälu kiirust, vaid ka sõltuvalt mälurakkude füüsilisest lähedusest töödeldavatele andmetele. Olenemata sellest, millist tüüpi vahemälu programm vaikimisi või hierarhia alusel nõuab. Peaasi on minimeerida signaali viivitust ja energiatarbimist. Sõltuvalt sellest, kui mitut tüüpi mälu programmile meeldib, modelleerib Jenga iga virtuaalse hierarhia latentsust ühe või kahe tasemega. Kahetasandilised hierarhiad moodustavad pinna, ühetasandilised kõvera. Seejärel projitseerib Jenga VL1 mõõtmete minimaalse viivituse, mille tulemuseks on kaks kõverat. Lõpuks kasutab Jenga neid kõveraid parima hierarhia (st VL1 suuruse) valimiseks.

Jenga kasutamisel on olnud märgatav mõju. Virtuaalne 36-tuumaline kiip hakkas töötama 30 protsenti kiiremini ja kasutas 85 protsenti vähem energiat. Muidugi on Jenga praegu vaid töötava arvuti simulatsioon ja läheb aega, enne kui näete selle vahemälu tõelisi näiteid ja isegi enne, kui kiibitootjad selle kasutusele võtavad, kui neile see tehnoloogia meeldib.

Tavalise 36 tuumamasina konfiguratsioon

  • Protsessorid. 36 tuuma, x86-64 ISA, 2,4 GHz, Silvermonti sarnane OOO: 8B-lai
    ifetch; 2-tasemeline bpred 512 × 10-bitise BHSR-iga + 1024 × 2-bitine PHT, 2-suunaline dekodeerimine/väljaandmine/ümbernimetamine/kinnitamine, 32-sisestusega IQ ja ROB, 10-sisestusega LQ, 16-sisene SQ; 371 pJ/juhis, 163 mW/südamiku staatiline võimsus
  • L1 vahemälud. 32 KB, 8-suunaline komplekt-assotsiatiivne, jagatud andmete ja juhiste vahemälu,
    3-tsükliline latentsusaeg; 15/33 pJ tabamuse/eksimuse kohta
  • Prefetchers Service. 16 kirjega voo eeltoojad, mis on modelleeritud ja kinnitatud
    Nehalem
  • L2 vahemälud. 128 KB privaatne tuuma kohta, 8-suunaline komplekt-assotsiatiivne, kaasa arvatud, 6-tsükliline latentsusaeg; 46/93 pJ tabamuse/eksimuse kohta
  • Sidus režiim. 16-suunalised, 6-tsüklilised latentsusaja kataloogipangad Jenga jaoks; vahemälu L3 kataloogid teistele
  • Globaalne NoC. 6 × 6 võrgusilma, 128-bitised fliidid ja lingid, X-Y marsruutimine, 2-tsüklilised konveierruuterid, 1-tsüklilised lingid; 63/71 pJ ruuteri/lingi flit traversal kohta, 12/4mW ruuteri/lingi staatiline võimsus
  • Staatiline mälu blokeerib SRAM-i. 18 MB, üks 512 KB pank paani kohta, 4-suunaline 52-kandidaadiline zcache, 9-tsükliline pangalatentsus, Vantage'i partitsioonid; 240/500 pJ tabamuse/viga kohta, 28 mW/panga staatiline võimsus
  • Mitmekihiline virnastatud DRAM. 1152 MB, üks 128 MB hoiuruum 4 plaadi kohta, sulam koos MAP-I DDR3-3200 (1600 MHz), 128-bitine siin, 16 rida, 8 panka/aste, 2 KB reapuhver; 4,4/6,2 nJ tabamuse/viisaku kohta, 88 mW võlvi staatiline võimsus
  • Põhimälu. 4 DDR3-1600 kanalit, 64-bitine siin, 2 rida/kanal, 8 panka/aste, 8 KB reapuhver; 20 nJ/juurdepääs, 4W staatiline võimsus
  • DRAM-i ajastused. tCAS=8, tRCD=8, tRTP=4, tRAS=24, tRP=8, tRRD=4, tWTR=4, tWR=8, tFAW=18 (kõik ajastused tCK-s; virnastatud DRAM-il on põhimäluna pool tCK-st )