4.19. Spremišta memorije¶
Kamera koja u skupu međuspremnika drži tri sličice pune razlučivosti, usporedno pokreće zaseban međuspremnik za pretpregled i još uvijek ima mjesta za Python skriptu i njezine objekte žonglira s više memorije nego što bi mogao pružiti jedan blok RAM-a na MCU-u. MicroPython sve uspijeva smjestiti tako da to raspoređuje preko nekoliko različitih vrsta memorije koje MCU pruža te tako da svaku vrstu alokacije usmjerava na onu vrstu memorije koja joj zaista treba.
4.19.1. Vrste memorije¶
Moderni MCU u OpenMV Cam kameri izlaže četiri različite vrste memorije. Prva je nevidljiva aplikaciji; ostale tri su spremišta iz kojih alokacije mogu dolaziti.
Podatkovna predmemorija (cache) procesora – malo, vrlo brzo područje memorije koje se nalazi između procesora i ostatka RAM-a. Kada procesor čita ili upisuje vrijednost iz glavne memorije, predmemorija automatski zadržava kopiju, pa ponovljeni pristupi istim podacima ostaju u predmemoriji i nikada ne plaćaju trošak odlaska u sporiju memoriju. Predmemorija nije spremište iz kojeg dolaze alokacije. Ona je prozirna za aplikaciju – jednostavno čini da se ostatak RAM-a u praksi doima bržim nego što bi sugerirala njegova osnovna latencija, sve do točke u kojoj radni skup prestaje stajati u njoj.
Tijesno povezana procesorska memorija – mali blok RAM-a izravno ožičen s procesorom bez sabirnice između. Pristup u jednom ciklusu, nikada ne promašuje, nikada ne čeka. Alokacije kojima zaista treba najbrža moguća memorija – gdje je bitan svaki ciklus latencije – dolaze iz ovog spremišta.
Brza memorija na čipu – nekoliko stotina kilobajta do otprilike megabajta RAM-a, ugrađenog u kućište MCU-a. Niska latencija, visoka propusnost, ali ograničena veličina. Ovdje se nalazi MicroPython hrpa (heap) kako bi pristupi Python objektima ostali brzi; manji radni međuspremnici koje procesor često dotiče dijele to spremište.
Sporija masovna memorija – na pločicama koje uz MCU spajaju vanjsku memorijsku jezgru, deseci megabajta RAM-a izvan čipa do kojih se dolazi preko vanjske sabirnice. Mnogo veća, ali svaki pristup traje dulje nego kod memorije na čipu; podatkovna predmemorija skriva velik dio tog troška za radne skupove koje može zadržati, a razlika se pojavljuje kod operacija koje prolaze kroz podatke prevelike za predmemoriju. Koristi se za alokacije koje moraju biti velike i koje procesor može tolerirati pri sporijoj brzini – ponajprije za skup međuspremnika slike.
Pločice u obitelji nalaze se na spektru: neke imaju samo RAM na čipu; neke uz RAM na čipu spajaju mnogo veći vanjski blok. Svaka od tri vrste koje se mogu alocirati tretira se kao spremište memorije – komad iz kojeg alokacije dolaze – i označena je tako da svaki zahtjev može tražiti onu vrstu memorije koja mu zaista treba.
4.19.2. Primarni međuspremnik slike¶
Međuspremnik slike koji stoji iza snapshot() ne traži brzu memoriju. Traži dovoljno memorije – ništa više. To ga smješta u ono spremište koje je najveće, pa na pločici koja ima i memoriju na čipu i vanjsku memoriju međuspremnik slike završava u vanjskom bloku.
Trostruko međuspremani međuspremnik slike pune razlučivosti prevelik je da bi stao u brzo spremište na čipu na većini dijelova; veće spremište jedino ga uopće može zadržati. Podatkovna predmemorija procesora skriva velik dio troška po pristupu kada aplikacija obrađuje sliku, a DMA mehanizam koji puni međuspremnik slike sa senzora u svakom slučaju drži korak s brzinom podataka senzora.
Točna veličina koju zauzima međuspremnik slike odabire se iz trenutnih vrijednosti pixformat(), framesize() i broja framebuffers(); raste ili se smanjuje svaki put kada se bilo koja od tih promijeni.
4.19.3. Sekundarni međuspremnici slike senzora¶
Druga instanca CSI dobiva vlastiti međuspremnik slike, alociran iz istog spremišta koje koristi primarna. Spremište je dijeljeno; međuspremnici su neovisni. Otisak sekundarnog obično je mnogo manji od otiska primarnog jer sekundarni senzori rade pri nižim razlučivostima, pa je dodatna memorija koju zauzima drugi međuspremnik slike mali dio one primarnog.
4.19.4. Međuspremnik toka¶
Međuspremnik pretpregleda slike je iznimka. Ne alocira se iz nijednog spremišta tijekom izvođenja; to je fiksno područje rezervirano u vrijeme izgradnje, s poznatom adresom i poznatom veličinom. To drži putanju pretpregleda izvan puta svim ostalim alokacijama – područje postoji od pokretanja i nikada se ne pomiče.
4.19.5. MicroPython hrpa¶
Python objekti – varijable, liste, rječnici, instance klasa, omotač Image koji vraća poziv snapshot(), svaki niz i n-torka koje aplikacija stvori – nalaze se na MicroPython hrpi sa skupljanjem otpada (garbage collection), koja je odvojena od memorijskih spremišta kamere. Hrpa sa skupljanjem otpada (GC) je područje memorije kojim MicroPython sam upravlja: Python kod iz nje implicitno alocira svaki put kada se stvori objekt, a MicroPython povremeno pregledava hrpu i vraća prostor koji zauzimaju objekti koje aplikacija više ne referencira, pa aplikacija nikada ne mora ručno ništa oslobađati.
Za GC hrpu se pri pokretanju izdvaja namjensko područje, obično smješteno u brzu memoriju na čipu kako bi Python pristup ostao brz, uz neobavezno prelijevanje u veći vanjski blok na pločicama kojima treba više prostora za velike podatkovne strukture.
Image koju vraća snapshot() mali je omotač na GC hrpi; temeljni podaci o pikselima nalaze se u međuspremniku slike u jednom od spremišta kamere. Njih dvoje nikada se ne natječu za istu memoriju.
4.19.6. Sve zajedno¶
Usmjeravanje svake vrste alokacije u pravo spremište – velikih međuspremnika u veće spremište gdje stanu, podataka osjetljivih na latenciju u brža spremišta, Python hrpe u vlastito područje, pretpregleda u njegov rezervirani utor – jest ono što omogućuje da se cjevovod snimanja pune razlučivosti, kanal pretpregleda i netrivijalna Python skripta izvode jedno uz drugo na dijelovima koji ukupno imaju tek nekoliko megabajta brze memorije.