edit: nyt alkaa olla editoitu kasaan.
"Ryzenissä on kaksi L3:a joista toinen nopea, toinen hidas" Ei ole vaan kahdella neljän ytimen ryppäällä on kummallakin oma L3, toisen ytimen data ei mene toisen L3:een ellei se ole jaettua dataa.
Mieti nyt vähän vaikka moniprosessorivehkeitä. Olisivat todella nopeita jos kaikki cachet snoopattaisiin jokaisen muistihaun yhtedessä.
Voi huoh.
Perinteinen snooppaus ei edes sellaisenaan
toimi nykyaikaisilla väylärakenteilla, koska jonkun core2n jälkeen ei ollut mitään yhtä väylää, jota voisi snoopata.
Minä en ole sanallakaan mielestäni puhunut mitään mistään snooppaamisesta.
Vaan se välimusitikoherenttiusprotokolla on nykyään aika paljon monimutkaisempi ja fiksumpi, ja toteutusyksityiskohdat vaihtelee selvästi eri prossujen välillä.
Aina kun jonkun muistiosoitteen sisältämää dataa halutaan muistista, tarvii tietää, onko se jo likaisena josain välimuistissa, mutta sitä tietoa ei tarvi hakea sieltä toiselta välimuistilta asti, koska tästä
niiden muiden välimuistien likaisisten lohkojen krijanpidosta voidaan pitää lähempänä olevia kopioita.
Mutta sitten tämän kirjanpidon ylläpitämisestä tulee kuitenkin paljon liikennettä, ja ne kirjanpidon ylimääräiset kopiot vie paljon tilaa.
Tyypillinen kehittyneempi ratkaisu on hakemistopohjainen välimuistikoherenssi. Huonona puolena on se, että tuon kirjaston tietorakenteet on isoja, se vaatii pajon (S)RAMia.
Todennäköisesti huomattava osa Romen IO-piirin pintaa-alasta menee juuri tähän.
Directory-based coherence - Wikipedia
Oma muistiavaruus. Kyllä vaan threadien paikalliset muuttujat on per thread.
Mikään ei estä toisia säikeitä ronkkimasta niitä toisen säikeen paikallisia muuttujia, ja se on aivan sallittua koodia C-kielellä, niin kauan kun sen paikallisen muuttujan sisältävästä funktiosta ei ole poistuttu.
Esimerkkikoodi, ei ole käännetty eikä testattu ja sisältää todennäköisesti muutaman pikkuvirheen.
Tässä tuo luotu säie jää looppaamaan, kunnes sen paikallisen muuttujan arvo muuttuu. Ja sitä muutetaan ulkopuolelta, pääsäikeestä.
Koodi:
void myFunc0(int** ptr) {
int myLocalVar = 0;
*ptr = &myLocalVar; // store pointer to my local variable to the external pointer
while (ptr == 0) {
/* still looping */
}
}
void anotherFunc(int* ptr) {
*ptr = 1; // write one to the pointer.
}
void main() {
pthread_t myThread;
int* ptr;
pthread_create( myThread, NULL, &myFunc, &ptr),
anotherFunc(ptr);
pthread_join(myThread, NULL);
}
Kuten sanoin aikaisemmin jos kooderi on idiootti niin kaikki data on jaettua.
Ei, vaan jos koodari on idiootti niin koodari kopioi aivan turhaan dataa edestakaisin.
Sinulla ei ole mitään pätevyyttä arvioida koodarien idioottiutta kun tiedät koodaamisesta paljon vähemmän kuin edes idioottikoodarit.
Muistihan on prosessorille privaattia jos sitä ei ole käytössä muualla.
VOi huoh. Voisitko nyt ottaa yhtään selvää, mistä höpiset?
Kaikki normaalit pienehköt, yhteen laatikkoon mahtuvat , moniprosessorijkärjestelmät toimivat ohjelmointimallin kannalta SMP-periaatteella. jaetulla muistimallilla. Kaikki muisti on nimenomaan oletuksena
jaettua systeemin sisällä.
Tälle kilpaileva moniprosesorointimalli on sitten viestinvälitys, jossa kaikilla on oma muistinsa ja sitten erikseen viesteillä lähetellään dataa muille. Sitä käytetään vain hyvin järeissä, tuhansien ytimien supertietokoneissa, ja niissäkin muutama ydin on yleensä tyypillisesti keskenään SMP.
OpenCL sitten määrittelee myös muistimallin, jossa on myös sekä work-itemille omaa muistia(private) että work-gropille omaa muistia (local), mutta tämä on irrelevanttia sen kannalta, miten C-kielisiä ohjelmia ajamaan kykenevä käyttöjärjestelmä ja prosessori ajavat normaaleita ohjelmia.
Aivan, kooderinhan se on hoidettava threadien yhteisen datan jakaminen. Tässä ei mitään tarvetta snoopata toisen ytimen cacheja.
Paitsi että se rauta ei mistään voi ennakolta tietää, aikovatko ne kaksi eri säiettä käyttää samassa välimuistilonjassa olevaa dataa, tai onko siellä vielä jollain kolmannella ytimellä joku säie, joka käyttää samassa välimusitiliinjassa olevaa dataa.
Sen raudan täytyy toteuttaa joku välimuistikoherenttiusprotokolla, joka huolehtii, että samaa välmuistilinjaa ei ole likaisena monessa eri välimusitilinjassa, jatoteuttaa lisäksi käskykantaspeksin mukaiset konsistenttiussäännöt.
Ja miksi se ei tietäisi? Mitä jos pistetään jokaiseen välimuistilinjaan tieto siitä onko cachelinja käytössä vai ei.
Mitähän nyt tarkoitat "jokaisella välimuistilinjalla" ?
Tietysti siellä välimuistissa on täytyy olla kirjanpito siitä, mitä se sisältää. (kutsutaan yleensä nimellä tag)
Mutta jos haluat alkaa jäljittämään koko systeemin osoitteista, että onko ne jossain jonkun muun välimuistissa, niin:
Zen taitaa tukea ainakin 2 teratavua fyysistä muistia.
välimuistilinja on 64 tavua. Eli koko fyysinen muistiavaruus jakautuu
32 miljardiin välimuistilinjaan.
Että jos ehdotat noin suoraviivaista ratkaisua, niin saat lisätä sinne prosessorille 4 gigatavun verran sitä kirjanpitoa.
Tähän on hiukan fiksumpia ratkaisuita, joissa sen kirjanpidon määrä pysyy inhimillisenä. Mainitsin tuossa ylempänä jo tuon hakemistopohjaisen koherenttiusprotokollan periaatteen.
Privaatin tapauksen kanssa kirjoitus cacheen ei tarvii mitään toimenpidettä minnekään muualle kun tiedetään että muisti ei ole missään muualla käytössä.
Ei tiedetä, missään x86-järjestelmässä ei oel mitään privaattia musitia. Kaikki muisti on jaettua koko systeemin kesken. X86 on SMP. ARM on SMP. Kaikki normaalit CPU-arkkitehtuurit on SMP.
Ainoa, missä se tiedetään on se välimusitikoherenttiusprotokolla. Sen välimuistikoherenttiusjärjestelmän kirjanpito merkitsee sen lohkon privaatiksi, jos sitä ei sillä hetkellä ole muussa välimuistissa. Ja sitten kun siihen kirjoitetaan, se merkitään myös likaiseksi.
Jos nyt toinen threadi/prosessi haluaa käyttää samaa välimuistilinjaa
Ei , vaan joku toinen VÄLIMUISTI haluaa osoittaa samaan osoitteeseen.
ja välimuistin koherenssiprotokolla huomaa tämän.
broadcastataan tieto muillekin em. linjaa käyttäville jotta kirjoitukset aiheuttavat linjan päivityksen kaikkiin käyttöpaikkoihin.
Ne "muut" tiedetään tasan tarkkaan vain sen välimuistin koherenssiusprotokollan kautta. Ja ne muut on
muita välimuisteja.
Ei prosesseja eikä säikeitä.
Ja käyttöjärjestelmä voi myös koska tahansa siirtää sen säikeen ajautumaan toiselle ytimelle.
Jos moniprosessorikoodista aiotaan jotain nopeusetuakin saada on käytetty muutettava muisti syytä olla pääosin privaattia.
... että voidaan aivan turhaan tuhlata aikaa ja kaistaa turhaan muistin kopiointiin edestakaisin. Niillä ytimillä on välimuistit sitä varten, että liikenne siihen dataan, mitä sillä hetkellä käsitelläöän on nopeaa.
Ja mikään normaali SMP-periaatteella tarjoava yleiskäyttöinen moniprosessorijärjestelmä ei tarjoa mitään "privaattia " muistia joka olisi mitenkään raudalla eroteltu "jaetusta" muistista. Prosessorin näkökulmasta se kaikki on aivan samanlaista muistia.
Ja miksi pitäisi olla? Jos se muisti on threadissa varattua eikä sitä jaeta niin se pysyy privaattina kunnes threadi tapetaan.
Rauta ei tiedä, mikä muisti on "privaattia" ja mikä ei ole "privaattia".
Tai ainoa keino miten se tietää sen, on välmuistikoherenttiusprotokollan kautta.
Ja sinun ratkaisu olisi snoopata joka muistihaun yhteydessä kaikki cachet läpi? Et kovin nopeita prosessoreita saa aikaiseksi
Minä en ole sanallakaan puhunut mitään mistään snooppaamisesta. Sinä sen sijaan höpiset siitä jatkuvasti ja tunget sitä sanaa minulle suuhun.
Vaan että vaaditaan
jonkinlainen välimuistin koherenttiusprotokolla jolla varmistutaan, ettei data ole muissa välimuisteissa.
Minä ymmärrän, mitä raudalta vaaditaan, että
ohjelmat toimivat.
Minä olen oikeasti koodannut monisäikeisiä ohjelmia.
Minä olen myös ollut pääsuunnittelijana pienen 4-ydin-signaaliprosessorin arkkitehtuurissa (työkaverit sitten suunnittelivat RTL-toteutuksen). Siinä tosin ei ollut välimuistikoherenttiutta, koska siinä OLI sinun kaipaamasi privaattimuistit, eikä ollenkaan välimuistia yhteiselle isolle muistille. ja juuri niiden privaattimuistien takia sillä ei voinut ollenkaan ajaa C-kielisiä normaaleilla säikeistysrajapinnoilla(pthread ja muut vastaavat) tehtyjä monisäikeistettyä ohjelmia vaan sitä ohjelmoitiin OpenCL:llä.
http://www.almarvi.eu/assets/almarvi_d3.5_final_v10.pdf