STL labai ribotoje atminties įterptinėje sistemoje

Šiuo metu kuriu įterptinę sistemą, naudojant ARM Cortex M3 procesorių su 64 KB SRAM. Šiuo metu ieško būdų, kaip STL konteineriais suteikti deterministinį darbą, kuris apima tai, kad negaliu paleisti atminties vykdymo metu.

Visų pirma esu susirūpinęs, kaip STL konteineriai atlieka dinaminį atminties paskirstymą. Nors galiu naudoti savo skirstytuvą, kad šios struktūros gautų atmintį iš rezervo, kurį atidėjau, turėčiau nustatyti atskirą fondą kiekvienai struktūrai, kad būtų užtikrinta, jog vienoje struktūros instancijoje negalima naudoti kitos vietos.

Dirbu su kitais šio projekto žmonėmis, kurie nenori nerimauti dėl žaliavinio atminties priskyrimo ir nori naudoti „gerai žinomas“ duomenų struktūras (kamino, eilės, deque). Todėl šiuo metu apsvarstysiu galimybę sukurti apvalkalus aplink C-masyvus, kad būtų palaikomos šios struktūros. Tai statiškai paskirstys atmintį, reikalingą šiems konteineriams palaikyti, ir leis kitiems kūrėjams žinoti konteinerio, kurį jie sukūrė prieš vykdymą, dydį, atsižvelgiant į kompiliatoriaus pateikto kodo dydį. Mano nuomone, tai užtikrina, kad atminties išjungimo problemos negali įvykti vykdymo metu ir labai supaprastina sistemos kūrimą.

Kitas variantas būtų STL konteinerių paskirstymas sistemos inicijavimo metu. Po inicijavimo laikotarpio papildoma dinaminės atminties priskyrimo nebus. Tačiau, kiek žinau, standartinės C ++ STL duomenų struktūros tai nepalaiko - reikės, kad konteineriai, pvz., Krūva, būtų iš anksto išdėstyti (panašūs į vektorių).

Norėčiau dėkoti už komentarus dėl mano pasiūlymo sukurti klases aplink standartines C masyvus? Be to, ar yra paprastesnis būdas statyti STL konteinerio dydį, pvz., Statinį steką ar eilę, kompiliavimo metu? (Žinau, kad tai įmanoma naudojant vektorių, bet nesu tikras dėl kitų)

Pastaba Aš perskaičiau kitą klausimą ( įterptą C + +, kad galėtumėte naudoti STL, ar ne), tačiau šio klausimo autorius nepaaiškino, kiek atminties jie turėjo (kiti tada, kai jie naudojo ARM7 procesą) arba, atrodo, mano panašų sprendimą.

Antra pastaba. Žinau, kad kai kuriems kūrėjams 64KB SRAM gali atrodyti kaip didelė atmintis. Tiesą sakant, aš sukūriau AVR procesorius, turinčius žymiai mažesnį atminties dydį, todėl suprantu šią perspektyvą. Tačiau iš mano dabartinio (galbūt neinformuoto) požiūrio, 64 KB atmintis yra ne tiek daug, kai kalbama apie STL konteinerius.

10
08 марта '12 в 6:44 2012-03-08 06:44 BSchlinker yra nustatytas kovo 8 d . 12 val. 6:44 2012-03-08 06:44
@ 2 atsakymai

Šis klausimas yra painus ir keistas. Pirma, leiskite išsiaiškinti kai kuriuos klaidingus.

Jūs pavadinate „kamino, eilės, deque“ pavadinimą. Na, du iš jų nėra konteineriai. stack ir queue konteinerių adapteriai. Žiūrėkite, kad jie faktiškai nesaugo daiktų; jie tiesiog tarpininkauja su jais. stack užtikrina, kad galite spustelėti, pop ir gauti viršutinį elementą. queue užtikrina, kad jūs galite grįžti tik iš priekio ir gauti priekinį elementą (manau, kad taip pat galite gauti galinį elementą).

Konteinerių adapteriai kaip šablono parametrą iš tikrųjų naudoja faktinį konteinerio tipą. Todėl, jei norite, galite naudoti stack std::list stack . Aš to nepasiūlyčiau (priklausomai nuo jūsų naudojimo atvejo), bet galėtumėte.

Konteinerių adapteriai nerūpi atminties; tai yra konteineriai, kuriuos jie naudoja, skirdami atmintį.

Jei dirbate tokioje ribotoje sistemoje, kurioje yra ribota atmintis, nerandate standartinių konteinerių, kurie bus labai draugiški. Net jei naudojatės paskirstytuvais, kad juos pateiktumėte su fiksuotais atminties buferiais, vienintelis dalykas, kurį šie skirstytuvai gali padaryti, kad būtų užkirstas kelias iš tikrųjų talpyklai skirti daugiau atminties, yra išmesti išimtį.

Pvz., Jei turite vector kurie turėtų veikti per 2 KB atminties, jei jis yra 1 KB dydžio ir bando skirti 2,5 KB daugiau, skirstytuvas negali tiesiog grąžinti 2 KB. Ji gali grąžinti 2.5KB pagal užklausą arba mesti std::bad_alloc . Tai yra jūsų dvi galimybės. Nėra jokio būdo, kaip paskirstytojas galėtų pasakyti vector kad jis gali gauti daugiau atminties, nei ji turi, bet ne taip, kaip ji nori.

Panašiai skirstytuvas turi pateikti naują atmintį, šviežią skiriamą atmintį, kurią galima kopijuoti. Ji neturėtų suteikti tos pačios atminties vietos tik su daugybe prieinamų. Tai gali sukelti problemų kai kuriuose diegimuose.

Vožtuvai yra skirti skirtingoms atminties sritims pasiekti; jie yra prastai suprojektuoti, kad apribotų pačios talpyklos dydį.

Siūlau sekti EASTL kopiją . Tai tikrai yra tokio pobūdžio dalykas. Aš sujungiau jus su „Github“ repo su kai kuriais klaidų taisymais ir tt Tačiau jis vis dar yra tas pats. Tai nėra blogas kodas. Jų STL tipo konteineriai sudaro didžiąją sąsajos dalį, todėl jie iš esmės gali būti pakaitalas. Tačiau jie suteikia ypatingą funkcionalumą specifiniam atminties paskirstymo valdymui.

10
08 марта '12 в 7:27 2012-03-08 07:27 atsakymą pateikė Nicol Bolas kovo 8 d. 12 val. 07:27 2012-03-08 07:27

Be EASTL , taip pat galite naudoti static_vector iš patobulinimo. Ji dalijasi dauguma API su std::vector , ir ji gali būti naudojama su konteinerių adapteriais (eilėje, kamino). Vietoj metimo std::bad_alloc , jis gali skambinti „ throw_bad_alloc() , todėl jis gali būti naudojamas ir įterptinėje aplinkoje be jokių išimčių.

0
04 февр. Atsakymas pateikiamas KovBal 04 vasaris. 2017-02-04 23:02 '17, 11:02 pm 2017-02-04 23:02