Osaatko avata maalikolle, mikä ominaisuus tuo transaktionaalinen muisti on.
Mahdollistaa joidenkin asioiden tekemisen monisäikeisissä softissa ilman synkronointia.
Eli, normaalisti, jos kaksi säikettä yrittää käyttää samassa muistiosoitteessa olevaa yhtä aikaa, on arpapeliä, kumpi niistä saa käsiteltyä sitä ensin, kumpi myöhemmin, Ja arpa heitetään uusiksi jokaiselle muistiaccessille.
Jos meillä on joku looginen asia, jonka käsittelyyn tarvii tehdä monta muistiaccessia (esim. tietorakenne jonka lukeminen pitää tehdä monella lukuoperaatiolla, tai joku operaatio jonka yhteydessä arvo ensin luetaan muistista, muokataan sitä , ja sitten tallennetaaan musitiin), niin nämä monta muistioperaatiota voivat mennä limitetysti näiden kahden säikeen välille, ja se yleensä tarkoittaa sitä että koodi laskee väärin.
Esimerkki 1:
Oletetaan että meillä on joku laskuri A
Säie 1 lukee arvon A
Säie 2 lukee arvon A
Säie 1 muuttaa arvoa A ja tallettaa sen muistiin
Säie 2 muuttaa (aiemin lukemaansa) arvoa A ja tallettaa sen muistiin.
Tällöin säie 2 ylikirjoittaa säikeen 1 kirjoittaman arvon ja on kuin sitä ei koskaan olisi tehty. laskurin arvo onkin kuin sitä olisi päivitetty vain kerran, ei kaksi kertaa.
Tähän tyypillisenä ratkaisuna on joko synkronointi, jolla pakotetaan että säie 2 saa luettua arvon A vasta kun säie 1 on sen kirjoittanut, tai atomisuus, joka tarkoittaa että koko "luku-päivitys-kirjoitus" on muistin näkökulmasta yksi operaatio, jonka välissä ei saa tehdä muuta. Monissa käskykannoissa on atominen inc(yhdellä lisäys)-operaatio, muttei mitään monimtukaisempaa.
Synkronointi taas tarkoittaa huomattavaa määrää käskyjä ja liikennettä ytimien välillä.
Transaktionaalinen muisti tarkoittaa sitä, että monta muistioperaatiota (ja kaikki niiden välissä tapahtuvat laskentaooperaatiot) voidaan niputtaa muistin järjestyksen(konsistenttiuden) näkökulmasta atomiseksi "transaktioksi". Ennen kuin transaktio on suljettu, mikään sen tekemä ei näy muualle, eikä mikään muualla tällä välillä tehty näy sille. Ja transaktio voi myös failata/voidaan perua, jolloin näyttää kuin mitään sen sisällä olevaa ei olisi suoritettu.
Toinen esimerkki on esim. seuraava:
Säie 1 tuottaa dataa, vaikka pelin varsinainen engine joka pyörittää pelilogiikka ja fysiikkaa, ja tuottaa jatkuvsti uusia versioita datastaan.
Säie 2 kuluttaa dataa, vaikka pelin grafiikkaengine, joka piirtää kuvan. Sen pitää saada mahdollisimman uusi versio
kokonaisesta datasta.
Jos uuden datan laskeminen on vielä kesken, sitten sen kuuluu lukea se viimeisin data joka on kokonaan saatavilla. Keskeneräisen datan lukeminen tarkoittaisi sitä, että sama objekti voisi olla maailmassa monta kertaa jne.
Ilman mitään syknronointia säie 2 lukisi keskeneräistä, epäkonsistentia dataa.
Eli data pitää synkronoida; Säie 2 odottelee ennen lukemistaan, että data on valmista, ja kun säie 1 saa datansa valmiiksi, se herättää säikeen 2 lukemaan sen.
Transaktionalisen muistin kanssa tilanne voisi teoriassa olla siten, että säie 1 kirjoittaa kamansa transaktionaaliseen muistiinsa sitä laskiessaan.
Mikäli säie 2 lukee muistia tällä välillä, se saa muisitista vanhan, konsistentin version.
Vasta kun se on laskenut kaiken, se "commitoi" transaktionsa ja vasta tämän jälkeen säe 2 voi nähdä sen datat.
Ja säie 2 lukee sitä dataa myös transaktiona; Vasta kun myös se on sulkenut oman transaktionsa, säikeen 1 tekemät muutokset näkyvät sille.
Saattoi olla myös, että jos useampi transaktio yrittää käsitellä samaa osoitetta yhtä aikaa, jälkimmäinen niistä ei odota ensimmäisen datoja vaan failaa ja pitää uudelleenkäynnistää, en ole varma yksityiskohdista.
Käytännössä intelin TSXn transaktion maksimikoko on paljon pienempi kuin mitä jonkun pelienginen data ovat, joten tuo kakkosesimerkkini ei oikeasti toimi tuollaisenaan; TSX:n toteutus pohjaa L1D-välimuistin käyttämiseen joten transaktion kokoa rajoittaa ainakin L1-välimuistin kapasiteetti (lake-sarjassa 32 kiB, cove-sarjassa 48 kiB). Ilmeisesti, mikäli transaktion koko olisi suurempi kuin mitä L1D-välimuistiin mahtuu, transaktio failaa. Ja tässä se koko ei mene suoraan tavuina vaan sen pitää siis mahtua niihin välimuistilinjoihin, mitä siellä välimuistissa on, niiden sääntöjen mukaan, miten data välimuistissa voi mennä.