Conception et codage d’un pool de mémoire statique non fragmentant

J’ai déjà entendu le terme et j’aimerais savoir comment en concevoir et en coder un.
Devrais-je utiliser l’allocateur STL s’il est disponible?
Comment cela peut-il être fait sur des appareils sans OS?
Quels sont les compromis entre l’utiliser et utiliser le compilateur standard implémenté malloc / new?

    Je vais essayer de décrire ce qui est essentiellement un pool de mémoire – je ne fais que taper cela par tête, cela fait longtemps que je n’en ai pas mis en place un, si quelque chose est évidemment stupide, c’est juste une suggestion! 🙂

    1. Pour réduire la fragmentation, vous devez créer un pool de mémoire spécifique au type d’object que vous y allouez. En gros, vous limitez ensuite la taille de chaque allocation à celle de l’object qui vous intéresse. Vous pouvez implémenter une classe basée sur un modèle contenant une liste de blocs alloués de manière dynamic (la raison en est que vous pouvez augmenter la quantité d’espace. disponible). Chaque bloc alloué dynamicment serait essentiellement un tableau de T.

    Vous auriez alors une liste “libre”, qui est une liste à liens simples, où la tête pointe vers le prochain bloc disponible. L’allocation revient alors simplement à la tête. Vous pouvez superposer la liste liée dans le bloc lui-même, c’est-à-dire que chaque “bloc” (qui représente la taille alignée de T) serait essentiellement une union de T et un nœud de la liste liée. Lorsqu’il est alloué, il s’agit de T lorsqu’il est libéré. un noeud dans la liste. !! Il y a des dangers évidents !! Vous pouvez également allouer un bloc séparé (et un bloc protégé, ce qui ajoute davantage de temps système) pour contenir un tableau d’adresses dans le bloc.

    L’atsortingbution est sortingviale, parcourez la liste des blocs et allouez-la en premier, libérez-la également, la vérification supplémentaire consiste à rechercher le bloc à partir duquel elle est allouée, puis à mettre à jour le pointeur principal. (notez que vous devez utiliser le nouveau placement ou remplacer l’opérateur nouveau / supprimer dans T – il existe des moyens de contourner ce problème, Google est votre ami)

    Le “statique” implique, je crois, un pool de mémoire unique pour tous les objects de type T. L’inconvénient est que pour chaque T, vous devez disposer d’un pool de mémoire séparé. Vous pourriez être intelligent et avoir un seul object qui gère des pools de taille différente (en utilisant un tableau de pointeurs pour regrouper des objects dont l’index est la taille, par exemple).

    Le paragraphe précédent a pour but de préciser la complexité de la procédure. Comme RC le dit plus haut, assurez-vous d’en avoir besoin avant de le faire, car cela risque d’introduire plus de douleur que nécessaire!

    2. Si l’allocateur STL répond à vos besoins, utilisez-le, il est conçu par des personnes très intelligentes qui savent ce qu’elles font. Qu’il en soit ainsi pour le cas générique et si vous savez comment vos objects sont alloués, vous pouvez exécuter les actions décrites ci-dessus. plus rapide.

    3. Vous devez être capable d’allouer de la mémoire d’une manière ou d’une autre (support matériel ou une sorte de HAL – peu importe) – sinon je ne sais pas comment votre programme fonctionnerait?

    4. Le malloc / new habituel fait beaucoup plus de choses sous la couverture (google est votre ami, ma réponse est déjà un essai!) Le simple allocateur que je décris ci-dessus n’est pas ré-entrant, bien sûr, vous pouvez l’envelopper avec un mutex pour fournir un peu de couverture, et même alors, je risquerais que le simple allocateur exécute des ordres de grandeur plus rapidement que malloc / free normal.

    Mais si vous en êtes à ce stade de l’optimisation – vous avez probablement épuisé la possibilité d’optimiser vos algorithmes et l’utilisation de la structure de données?

    Je suggérerais que vous sachiez que vous avez besoin d’un allocateur de mémoire non fragmentant avant de vous donner beaucoup de mal à écrire le vôtre. Celui fourni par la bibliothèque std est généralement suffisant.

    Si vous en avez besoin, l’idée générale de réduire la fragmentation est de saisir de gros blocs de mémoire à la fois et de les allouer à partir du pool plutôt que de demander au système d’exploitation de vous fournir de la mémoire de manière sporadique et à des emplacements très variables dans le tas et entrecoupés objects de différentes tailles. Étant donné que l’auteur de l’allocateur de mémoire spécialisé a davantage de connaissances sur la taille des objects alloués à partir du pool et sur la façon dont ces allocations sont effectuées, il peut utiliser la mémoire plus efficacement qu’un allocateur à usage général tel que celui fourni par le STL.

    Vous pouvez consulter des allocateurs de mémoire, tels que Hoard, qui, tout en réduisant la fragmentation de la mémoire, peuvent également améliorer les performances en fournissant des tas spécifiques à chaque thread, qui permettent de réduire les conflits. Cela peut aider votre application à évoluer de manière plus linéaire, en particulier sur les plates-formes multicœurs.

    Vous trouverez plus d’informations sur les allocateurs multithreads ici .