4.19. Muistialtaat

Kamera, joka pitää kolmea täysiresoluutioista kehystä kehyspuskurialtaassa, ajaa erillistä esikatselupuskuria rinnalla ja jolla on silti tilaa Python-skriptille ja sen objekteille, käsittelee enemmän muistia kuin yksittäinen RAM-lohko MCU:ssa pystyisi tarjoamaan. MicroPython mahduttaa kaiken jakamalla sen niiden useiden erilaisten muistityyppien kesken, joita MCU tarjoaa, ja ohjaamalla kunkin varauksen sellaiseen muistiin, jota se todella tarvitsee.

4.19.1. Muistityypit

Nykyaikainen OpenMV Cam -MCU tarjoaa neljä erilaista muistityyppiä. Ensimmäinen on sovellukselle näkymätön; muut kolme ovat altaita, joista varaukset voivat tulla.

  • Suorittimen datavälimuisti – pieni, erittäin nopea muistialue, joka sijaitsee suorittimen ja muun RAM-muistin välissä. Kun suoritin lukee tai kirjoittaa arvon päämuistista, välimuisti pitää automaattisesti kopion, joten saman datan toistuvat käytöt pysyvät välimuistissa eivätkä koskaan maksa hitaampaan muistiin menemisen hintaa. Välimuisti ei ole allas, josta varaukset tulevat. Se on sovellukselle läpinäkyvä – se vain saa muun RAM-muistin tuntumaan käytännössä nopeammalta kuin sen raaka viive antaisi olettaa, aina siihen pisteeseen asti, jossa työjoukko lakkaa mahtumasta siihen.

  • Tiiviisti kytketty suorittimen muisti – pieni RAM-lohko, joka on johdotettu suoraan suorittimeen ilman väylää välissä. Yhden kellojakson käyttö, ei koskaan ohitusvirheitä, ei koskaan odotusta. Varaukset, jotka aidosti tarvitsevat mahdollisimman nopeaa muistia – joissa jokainen viiveen kellojakso merkitsee – tulevat tästä altaasta.

  • Nopea sirunsisäinen muisti – muutamasta sadasta kilotavusta noin megatavuun RAM-muistia, joka on rakennettu MCU-paketin sisään. Matala viive, suuri kaistanleveys, mutta rajallinen koko. MicroPython-keko sijaitsee täällä, jotta Python-objektien käytöt pysyvät nopeina; pienemmät työpuskurit, joita suoritin koskettaa paljon, jakavat saman altaan.

  • Hitaampi suuren kapasiteetin muisti – korteilla, jotka yhdistävät MCU:n ulkoiseen muistipiiriin, kymmeniä megatavuja sirun ulkopuolista RAM-muistia, johon päästään käsiksi ulkoisen väylän kautta. Paljon suurempi, mutta jokainen käyttö kestää kauemmin kuin sirunsisäisessä muistissa; datavälimuisti piilottaa suuren osan tästä kustannuksesta niille työjoukoille, jotka se voi pitää, ja ero näkyy toiminnoissa, jotka pyyhkäisevät dataa, joka on liian suuri välimuistiin mahtuakseen. Käytetään varauksiin, joiden on oltava suuria ja jotka suoritin voi sietää hitaammalla nopeudella – ennen kaikkea kehyspuskurialtaaseen.

Perheen kortit asettuvat kirjolle: joillakin on vain sirunsisäistä RAM-muistia; jotkut yhdistävät sirunsisäisen RAM-muistin paljon suurempaan ulkoiseen lohkoon. Kutakin kolmesta varattavissa olevasta tyypistä käsitellään muistialtaana – lohkona, josta varaukset tulevat – ja se on merkitty niin, että kukin pyyntö voi pyytää sen tyyppistä muistia, jota se todella tarvitsee.

4.19.2. Ensisijainen kehyspuskuri

Kehyspuskuri, joka tukee snapshot()-metodia, ei pyydä nopeaa muistia. Se pyytää riittävästi muistia – ei sen enempää. Tämä sijoittaa sen siihen altaaseen, joka on suurin, joten kortilla, jolla on sekä sirunsisäistä että ulkoista muistia, kehyspuskuri päätyy ulkoiseen lohkoon.

Täysiresoluutioinen, kolminkertaisesti puskuroitu kehyspuskuri on aivan liian suuri mahtuakseen nopeaan sirunsisäiseen altaaseen useimmissa osissa; suurempi allas on ainoa, joka pystyy ylipäätään pitämään sen. Suorittimen datavälimuisti piilottaa suuren osan käyttökohtaisesta kustannuksesta, kun sovellus käsittelee kuvaa, ja DMA-moottori, joka täyttää kehyspuskurin sensorista, pysyy sensorin datanopeuden tahdissa joka tapauksessa.

Tarkka koko, jonka kehyspuskuri ottaa, valitaan nykyisistä pixformat()-, framesize()- ja framebuffers()-arvoista; se kasvaa tai pienenee aina, kun jokin niistä muuttuu.

4.19.3. Toissijaiset sensorin kehyspuskurit

Toinen CSI-instanssi saa oman kehyspuskurinsa, joka varataan samasta altaasta, jota ensisijainen käyttää. Allas on jaettu; puskurit ovat itsenäisiä. Toissijaisen jalanjälki on yleensä paljon pienempi kuin ensisijaisen, koska toissijaiset sensorit toimivat matalammilla resoluutioilla, joten toisen kehyspuskurin ottama lisämuisti on pieni osa ensisijaisesta.

4.19.4. Virran kehyspuskuri

Kuvan esikatselun puskuri on poikkeus. Sitä ei varata mistään altaista ajonaikaisesti; se on kiinteä alue, joka varataan käännösaikana, tunnetulla osoitteella ja tunnetulla koolla. Tämä pitää esikatselupolun pois kaikkien muiden varausten tieltä – alue on olemassa käynnistyksestä lähtien eikä koskaan siirry.

4.19.5. MicroPython-keko

Python-objektit – muuttujat, listat, sanakirjat, luokkainstanssit, Image-kääre, jonka snapshot()-kutsu palauttaa, jokainen merkkijono ja monikko, jonka sovellus luo – sijaitsevat MicroPythonin roskienkeräystä käyttävässä keossa, joka on erillinen kameran muistialtaista. Roskienkeräystä (GC) käyttävä keko on muistialue, jota MicroPython hallinnoi itse: Python-koodi varaa siitä implisiittisesti aina kun objekti luodaan, ja MicroPython skannaa kekoa säännöllisin väliajoin ja vapauttaa tilan, jonka ovat ottaneet objektit, joihin sovellus ei enää viittaa, joten sovelluksen ei koskaan tarvitse vapauttaa mitään käsin.

Erillinen alue varataan GC-keolle käynnistyksessä, tyypillisesti sijoitettuna nopeaan sirunsisäiseen muistiin, jotta Python-käyttö pysyy nopeana, ja valinnaisella ylivuodolla suurempaan ulkoiseen lohkoon korteilla, jotka tarvitsevat enemmän liikkumavaraa suurille tietorakenteille.

Image, jonka snapshot() palauttaa, on pieni kääreobjekti GC-keossa; taustalla oleva pikselidata sijaitsee kehyspuskurissa yhdessä kameran altaista. Nämä kaksi eivät koskaan kilpaile samasta muistista.

4.19.6. Kaiken kokoaminen yhteen

Kunkin varaustyypin ohjaaminen oikeaan altaaseen – suuret puskurit suurempaan altaaseen, johon ne mahtuvat, viiveherkkä data nopeampiin altaisiin, Python-keko omaan alueeseensa, esikatselu varattuun paikkaansa – on se, mikä mahdollistaa täysiresoluutioisen kaappausputken, esikatselukanavan ja epätriviaalin Python-skriptin ajamisen rinnakkain osissa, joilla on yhteensä vain muutama megatavu nopeaa muistia.