Toon posts:

[C/Pic32] Alternatief voor malloc

Pagina: 1
Acties:

Onderwerpen


  • ixi
  • Registratie: December 2001
  • Laatst online: 00:16
Howdy. Ik ben bezig met het schrijven van code voor een microchip pic32 op basis van FreeRTOS. Hierin lopen een aantal tasks (zeg: threads), die allemaal kleine (1 tot 16 bytes) messages naar elkaar doorsturen. Hiervoor gebruik ik per message een malloc-call voor de 'payload'. Nadat een message is afgehandeld volgt er een free(). Elke thread krijgt gegarandeerd elke 10ms tijd om z'n ding te doen.

Aangezien er 1000 tot 5000 pakketjes per seconde worden aangemaakt wil ik dit gaan optimaliseren. Nu heb ik me bedacht dat als ik, zeg, 8kb aan geheugen alloceer (dmv malloc of gewoon door een grote array te definieren), ik uit deze buffer geheugen kan toewijzen aan de messages. Aangezien de messages allemaal kort leven kan ik dan een circular buffer gebruiken, zonder bij de houden of het geheugen al vrijgegeven is. Dit zou moeten werken mits de buffer groot genoeg is. Een klein detail is dat ik interrupts en de task scheduler even stil moet zetten op het moment dat ik geheugen moet toewijzen.

Mijn vraag: is deze gedachte juist? Heeft iemand ervaring met dergelijke implementaties en wellicht tips of mogelijke valkuilen waar ik op moet letten? Zijn er betere manieren om de malloc/free overhead te voorkomen?

Dank!

  • PierreAronnax
  • Registratie: Maart 2002
  • Niet online
Ik heb zelf geen ervaring met FreeRTOS, maar wel met de PIC32 en andere RTOS-en. Wat voor systeem gebruik je voor je messages, is dit een feature van je RTOS? Bied die geen ondersteuning om tijdens initializatie een x aantal messages aan te maken, en daar elke keer een niet gebruikte van te pakken en weer vrij te geven?

Daarnaast, weet je dat malloc en free (en andere heap functies) niet thread-save is? Deze dien je te beveiligen met een mutex, maar ik zie dat FreeRTOS hier ook een wrapper voor heeft gemaakt: http://www.freertos.org/a00111.html

Pierre - Motormedia.nl - Motor-Forum.nl - Motorshopper.nl - Motormeuk.nl - Motorstek.nl


  • ixi
  • Registratie: December 2001
  • Laatst online: 00:16
PierreAronnax schreef op vrijdag 17 juni 2011 @ 20:16:
Wat voor systeem gebruik je voor je messages, is dit een feature van je RTOS? Bied die geen ondersteuning om tijdens initializatie een x aantal messages aan te maken, en daar elke keer een niet gebruikte van te pakken en weer vrij te geven? ... Daarnaast, weet je dat malloc en free (en andere heap functies) niet thread-save is?
FreeRTOS voorziet in 'queues' waarvoor het zelf voldoende geheugen reserveerd. Alles dat de queues in gaat wordt gekopieerd in dit geheugen, en moeten van hetzelfde type zijn (geen variabele lengte dus). Ik gebruik de queues echter om meerdere soorten berichten te versturen, en heb dus een eigen struct met daarin een pointer naar de payload (en daarnaast een lengte en identifier-char). Ik gebruik de queues zodat ik gebruik kan maken van de FreeRTOS features: wachten op berichten met timeout, thread safe, etc.

Ik ben op de hoogte van de FreeRTOS wrappers, welke ik ook gebruik momenteel. Dat maakt het hele zaakje ook niet sneller natuurlijk... In de wrapper gebruiken ze taskENTER_CRITICAL() en taskEXIT.. die als het goed is de task scheduler en interrupts tijdelijk uitschakeld. Dit zal ik ook nodig gaan hebben als ik een eigen variant maak.

Ik zou wellicht m'n messages kunnen opdelen in een beperkt aantal groepen (naar message-size), en voor elke groep een eigen queue. Dit voelt alleen beperkend aan, zeker aangezien ik nog niet precies weet wat ik in de toekomst allemaal voor messages ga krijgen en er incidenteel een message bij zit die veel groter is. Ook moet ik dan beter gaan kijken naar hoe groot de afzonderlijke queues minimaal moeten zijn, in plaats van het op 1 hoop te gooien.

Is het een idee om in (in debug builds) de circular buffer steeds 1 byte ertussen te laten, waarin ik aangeef of het al is vrijgegeven? Op deze manier kan ik in ieder geval detecteren als de buffer niet groot genoeg is. Als ik ook nog een lengte-byte erbij zou zetten zou ik eroverheen kunnen springen, maar dan wordt m'n implementatie weer een stuk trager (cq gaat het meer en meer op malloc lijken denk ik; ken de exacte implementatie niet). Ik wil zo efficient mogelijk geheugen alloceren, en ook nog flexibel blijven :) Met in het achterhoofd natuurlijk dat ze voornamelijk klein zijn en vrij snel weer gedumpt mogen worden.

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Heeft zo'n PIC32 geen atomic instructies?

Eventueel kun je per-thread free-pools maken. Allocaties en de-allocaties gaan allemaal naar de pool van die thread.
Als de pool leeg is ga je in een kritische sectie andere pools gaan plunderen (in de veronderstelling dat elke thread zowel ontvangt en verstuurt). Bij onbalans (producer/consumer) kun je ook een globale pool bijhouden en elke lokale pool een limiet geven waarbij buffers (ook binnen een kritische sectie) aan de globale pool teruggegeven worden.

Maak je buffers bij zulke kleine sizes ook fixed-size (in dit geval dan 16bytes). Binnen je free-pool gebruik je dan bvb de eerste bytes om een pointer naar het volgende free-item op te slaan. (zoals malloc het ook doet)

ASSUME makes an ASS out of U and ME



Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee