41 votes

Quelles sont les meilleures pratiques pour réduire l'utilisation de la mémoire en C?

Quelles sont les meilleures pratiques pour la "programmation C mémoire efficace". Surtout pour les appareils intégrés / mobiles, quelles devraient être les directives pour avoir une faible consommation de mémoire?

Je suppose qu'il devrait y avoir des directives distinctes pour a) la mémoire de code b) la mémoire de données

28voto

Shane MacLaughlin Points 12765

En C, à un niveau plus simple, considérer les points suivants:

  • L'utilisation de #pragma pack(1) à l'octet aligner vos structures
  • L'utilisation des syndicats où une structure peut contenir différents types de données
  • Utiliser des champs de bits plutôt que ints pour stocker des drapeaux et des petits entiers
  • Évitez d'utiliser des tableaux de caractères de longueur fixe pour stocker des chaînes, de mettre en œuvre une chaîne de la piscine et de l'utilisation des pointeurs.
  • Où stocker les références à un énumérés liste de chaînes, par exemple, le nom de la police, de stocker un index dans la liste plutôt que de la chaîne
  • Lors de l'utilisation de l'allocation de mémoire dynamique, calculer le nombre d'éléments requis à l'avance pour éviter les reallocs.

22voto

ChrisN Points 10734

Quelques suggestions que j'ai trouvé utile dans le travail avec les systèmes embarqués:

  • S'assurer que toutes les tables de recherche ou d'autres données constantes sont effectivement déclarées à l'aide de const. Si const est utilisé, les données peuvent être stockées en lecture seule (e.g, flash ou EEPROM) de mémoire, sinon les données doit être copiée dans la mémoire vive au démarrage, ce qui nécessite à la fois flash et RAM de l'espace. Définir les options du linker pour qu'il génère un fichier de la carte, et l'étude de ce fichier pour voir exactement où vos données sont allouées dans la mémoire de la carte.

  • Assurez-vous que vous utilisez toutes les régions de la mémoire disponible pour vous. Par exemple, les microcontrôleurs ont souvent la mémoire embarquée qui vous pouvez faire usage de (qui peut également être plus rapide d'accès que l'externe RAM). Vous devriez être en mesure de contrôler les zones de mémoire à laquelle le code et les données sont affectés à l'aide du compilateur et de l'éditeur de liens paramètres de l'option.

  • Pour réduire la taille du code, vérifiez que votre compilateur d'optimisation de paramètres. La plupart des compilateurs des commutateurs à optimiser pour la vitesse ou de la taille du code. Il peut être intéressant d'expérimenter avec ces options pour voir si la taille du code compilé peut être réduite. Et évidemment, éliminer le double de code dans la mesure du possible.

  • De vérifier la quantité de mémoire de pile de votre système de besoins et d'ajuster l'éditeur de liens d'allocation de mémoire en conséquence (voir les réponses à cette question). Afin de réduire l'utilisation des piles, éviter de placer les grandes structures de données sur la pile (pour une valeur de "grand" est pertinent pour vous).

16voto

Dan Points 6319

Assurez-vous que vous utilisez des mathématiques à virgule fixe / entier dans la mesure du possible. De nombreux développeurs utilisent les mathématiques à virgule flottante (ainsi que les performances lentes et les grandes bibliothèques et l'utilisation de la mémoire) lorsque de simples mathématiques entières à l'échelle suffiront.

9voto

Mike Dunlavey Points 25419

Toutes les bonnes recommandations. Voici quelques approches de conception que j'ai trouvé utile.

  • Octet De Codage

Écrire un interprète pour un but spécial de byte-code du jeu d'instructions, et écrire le programme que possible dans ce jeu d'instructions. Si certaines opérations nécessitent des performances élevées, leur faire du code natif et de les appeler à partir de l'interprète.

  • La Génération De Code

Si une partie des données d'entrée change très rarement, vous pourriez avoir un externe générateur de code qui crée un groupe ad-hoc du programme. Qui sera plus petit qu'un plus générales sur le programme, ainsi qu'à courir plus vite et ne pas avoir à allouer du stockage pour les rarement-changement d'entrée.

  • Être un hater

Être prêts à perdre beaucoup de cycles si il vous permettra de stocker absolument minimum de structure de données. Habituellement, vous trouverez que les performances souffre très peu.

8voto

strager Points 41713

Très probablement, vous aurez besoin de choisir des algorithmes soigneusement. Objectif pour les algorithmes qui ont O(1) O(log n) l'utilisation de la mémoire (c'est à dire faible). Par exemple, continue de redimensionner les tableaux (par exemple, std::vector) dans la plupart des cas nécessitent moins de mémoire que les listes chaînées.

Parfois, en utilisant les tables de recherche peut être plus benefitial à la fois de la taille du code et de la vitesse. Si vous avez seulement besoin de 64 entrées dans un IUT, c'est 16*4 octets pour sin/cos/tan (utiliser la symétrie!) par rapport à un grand sin/cos/tan, fonction.

La Compression est parfois utile. Des algorithmes simples comme RLE sont faciles à compresser/décompresser quand ils sont lus de manière séquentielle.

Si vous faites affaire avec des graphiques ou audio, tenez compte des différents formats. Palettisées ou bitpacked* des graphiques peut être un bon compromis pour la qualité, et les palettes peuvent être partagées à travers de nombreuses images, outre la réduction de la taille des données. L'Audio peut être réduite de 16 bits à 8 bits ou même de 4 bits, stéréo et peut être converti en mono. Taux d'échantillonnage peut être réduite de 44,1 KHz à 22 khz ou 11kHz. Ces transformations audio de réduire considérablement leur taille des données (et, malheureusement, la qualité) et sont triviales (à l'exception de ré-échantillonnage, mais c'est ce que l'audio logiciel est pour =]).

* Je suppose que vous pourriez mettre cette sous compression. Bitpacking pour les graphiques se réfère généralement à réduire le nombre de bits par canal de sorte que chaque pixel peut correspondre aux deux octets (RGB565 ou ARGB155 par exemple) ou un (ARGB232 ou RGB332) à partir de l'original en trois ou quatre (RGB888 ou ARGB8888, respectivement).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X