Question

Je cherche à écrire un gestionnaire de mémoire auto défragmenter où d'un simple tas incrémentiel allocateur est utilisé en combinaison avec un défragmenteur simple compactage.

Le schéma approximatif serait de répartir les starting-blocks à l'adresse mémoire la plus basse va vers le haut et la conservation des informations de maintien de livre à partir de l'adresse de la mémoire de travail vers le bas le plus.

Le gestionnaire de mémoire passerait retour des pointeurs intelligents - struct de Boost de intrusive_ptr semble la plus évidente à la tenue de livres qui seraient eux-mêmes alors pointer vers le bloc de mémoire réelle donnant ainsi un niveau d'indirection de sorte que les blocs peuvent être facilement déplacés.

Le défragmenteur se compacter sur le tas à partir de signets « génération » pour accélérer le processus et que la défragmentation d'une quantité fixe de mémoire à la fois. pointeurs premières aux blocs eux-mêmes seraient valides jusqu'au prochain passage de defrag et ainsi pourraient être passés librement jusqu'à ce temps l'amélioration des performances.

L'application spécifique pour ce jeu est la programmation de la console et ainsi au début ou à la fin de chaque trame une passe de defrag pourrait être fait de façon relativement sûre.

Alors, ma question est quelqu'un a utilisé ce type de système d'allocation en combinaison avec STL serait juste souffler complètement STL à part que je pense. Je peux voir std :: liste travail au niveau intrusive_ptr mais qu'en l'attribution de la liste des stl eux-mêmes nœuds est de toute façon de passer outre les pointeurs suivante / préc être intrusive_ptr eux-mêmes est ou suis-je vais juste avoir un tas norme allocateur le long du côté de cette une plus dynamique.

Était-ce utile?

La solution

Si vous allez être des objets en mouvement autour de la mémoire, alors vous ne pouvez pas le faire pleinement génériquement. Vous ne serez en mesure de le faire avec des objets que savoir qu'ils pourraient être déplacés. Vous aurez également besoin d'un mécanisme de verrouillage. Lorsqu'une fonction est appelée sur un objet, il ne peut pas être déplacé.

La raison en est que l'ensemble du modèle C ++ repose sur des objets assis à des points fixes dans la mémoire, de sorte que si un thread a appeler une méthode sur un objet, ce fil a été interrompue et l'objet déplacé, une catastrophe frappera quand le fil a repris.

Tout objet qui a tenu un pointeur de mémoire brute à un autre objet qui pourrait être déplacé (y compris un sous-objet lui-même) ne fonctionnerait pas.

Un tel système de gestion de la mémoire peut fonctionner, mais vous devez être très prudent. Vous devez être strict sur la mise en œuvre des poignées et la poignee> pointeur sémantique de verrouillage.

Pour les conteneurs STL, vous pouvez personnaliser l'allocateur, mais il doit encore renvoyer des pointeurs de mémoire brutes fixes. Vous ne pouvez pas retourner une adresse qui pourrait se déplacer. Pour cette raison, si vous utilisez des conteneurs STL, ils doivent être des conteneurs de poignées, et les nœuds seront eux-mêmes ordinaire la mémoire allouée dynamiquement. Vous trouverez peut-être que vous aussi bien dans les frais généraux dans le indirection de poignée et ont encore des problèmes dans la fragmentation des collections de poignée que vous gagnez en utilisant STL.

L'utilisation de contenants qui comprennent vos poignées peuvent directement être la seule voie à suivre, et même alors, il peut y avoir encore beaucoup de frais généraux par rapport à une application C ++ qui utilise des objets traditionnels fixes dans la mémoire.

Autres conseils

conteneurs STL sont mis en œuvre à l'aide des pointeurs nus.

Vous pouvez spécifier un allocateur personnalisé lorsque vous les instancier (afin qu'ils leur initialisez leurs pointeurs à l'aide de votre allocateur), mais (parce que les valeurs attribuées sont stockées dans des pointeurs nus), vous ne savez pas où ces pointeurs sont, et donc vous ne peut pas les changer plus tard.

Au lieu de cela, vous pourriez envisager de mettre en œuvre un sous-ensemble de la STL vous:. Vos versions des conteneurs STL pourrait alors être mis en œuvre avec des pointeurs gérés

Une autre technique qui est assez bien connue est . Vous devriez jeter un oeil à cette inspiration supplémentaire.

Si cela est pour la programmation de jeux de la console, il est beaucoup plus facile d'interdire les allocations de mémoire dynamique non scope lors de l'exécution. Et au moment du démarrage, mais c'est un peu difficile à atteindre.

Mon point de vue à ce sujet, est que si avoir peur de la fragmentation, cela signifie que vous jonglez autour avec des morceaux de données qui sont une grande partie de votre mémoire, et par cette vertu seule, vous ne pouvez pas avoir beaucoup d'entre eux. Savez-vous déjà ce que ce sera? Peut-être qu'il serait préférable de descendre un niveau et prendre des décisions plus spécifiques, entravant ainsi moins sur l'autre code et les performances générales de votre application?

Une liste est un exemple exceptionnellement mauvaise pour mettre en mémoire un gestionnaire de défragmenter, car il est un tas de petits morceaux, comme la plupart d'autres structures de données STL. Si vous faites cela, il aura toutes sortes de conséquences mauvaises évidentes - y compris les performances de votre défragmenteur aller vers le bas, aussi le coût de indirection etc. Les seules structures où il est logique sont OMI les contigious - tableau, deque, morceau principal de Hashtable , ces choses, et seulement au-delà d'une certaine taille, et seulement après qu'ils ne vont pas être redimensionnées plus longtemps. Ce genre de choses appellent, encore une fois, des solutions spécifiques, au lieu de génériques.

Commentaire de retour sur la façon dont tout cela se trouve.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top