devrais-je m'inquiéter de la fragmentation de la mémoire avec std :: vecteur? Si oui, existe-t-il des moyens d'aider à l'empêcher? Je ne prédis pas toujours que mes programmes doivent être exécutés sur un PC, ils peuvent également être exécutés sur des dispositifs intégrés / consoles de jeux, donc je ne pourrai pas toujours compter sur la mémoire virtuelle. P>
Ensuite, je crois qu'il serait plus efficace d'utiliser une matrice de taille dynamique plutôt que d'une matrice statique, de sorte que la mémoire ne serait attribuée que si nécessaire. Cela simplifierait également le processus de conception de mon programme. Y a-t-il des moyens d'atteindre cela efficacement? P>
Merci pour tout conseil! p>
6 Réponses :
non, std :: vecteur garantit un stockage contigu. Vous pouvez utiliser vecteur :: réserve () pour éviter les rétroglocations lorsque la taille du vecteur augmente cependant. P>
C'est précisément pourquoi vous avez besoin de vous inquiéter de la fragmentation de la mémoire. Si nouveau ne peut pas trouver, par exemple. Un bloc contigu de rechange 4K, il ne peut pas allouer un vecteur de 1000 INTS.
Comment cela voudrait-il même se rapporter à la fragmentation des tas? La fragmentation de tas ne dépend pas de la mise en page d'une classe. Cela dépend des modèles d'allocation et de la politique / des algorithmes d'allocation.
Je prends "inquiétant de la fragmentation de la mémoire" pour signifier "inquiétant que la mémoire accessible soit fragmentée", car l'accès à la mémoire non contiguë signifie que vous n'obtenez probablement pas les avantages de la performance de la préfettration et autres.
La réponse à vos inquiétudes peut être std :: deque code>. Il vous donne une interface similaire à celle de
std :: vecteur code>, mais fonctionne mieux avec la mémoire fragmentée, car elle alloue plusieurs petites tableaux au lieu d'un grand. Il est effectivement moins efficace que
std :: vecteur code> dans certains aspects, mais pour votre cas, il peut s'agir d'un bon compromis. P>
Pouvez-vous site une source pour les revendications que vous faites? de préférence une référence standard? MISE À JOUR B> Trouvé un démarrage moi-même: gotw.ca/gotw/054.htm
@sehe: J'ai bien peur que la norme a tendance à ne pas appliquer les implémentations afin de permettre des optimisations inconnues. Il ne force même pas std :: vecteur code> à mettre en œuvre à l'aide d'un tableau interne, bien que je doute fort que tout le monde puisse la mettre en œuvre autrement. Mais généralement
std :: deque code> est implémenté à l'aide de petits tableaux. Voir Cplusplus.com/reference/stl/Deque , par exemple, pour une courte durée Discussion indépendante de la bibliothèque.
Vous devez toujours vous inquiéter de la performance et de l'efficacité lorsque votre profileur vous dit em> (vous pouvez être ce profileur, mais vous devez «mesurer», ne pas deviner). choses que vous pouvez faire : p> Pré-allocation de capacité: p>
Utilisez un allocator personnalisé p>
La première option est clairement la victoire rapide; La deuxième option est plus impliquée et je ne le recommande que lorsque votre profileur de tas vous dit que la fragmentation provoque des problèmes. P> pour profilage de tas, je suggère p>
std::vector<int> x(1000); // size() is 1000
std::vector<int> y;
y.reserve(1000); // size() is 0, capacity is 1000
std :: vecteur est seulement aussi bon que neuf. Il gère simplement l'allocation de mémoire sous-jacente pour vous
Un couple de choses que vous pouvez faire - en supposant que vous ne voulez pas écrire une nouvelle nouvelle Pré-allocation de vecteurs ou redimensionnez () Si vous savez de quelle taille éventuelle ils seront, cela cesse d'utiliser des copies de mémoire gaspillées au fur et à mesure de leur croissance. P>
Si vous allez utiliser à nouveau le vecteur de même taille, il vaut mieux le garder et le remplir que de le supprimer et de le recréer. P>
Généralement sur des cibles intégrées Si vous connaissez les exigences de la mémoire, il est préférable d'allouer de manière statique à toute la mémoire au début et de la diviser soi-même - ce n'est pas comme si un autre utilisateur va en vouloir. P>
Si votre vecteur sera réaffecté plusieurs fois, il peut provoquer une fragmentation de la mémoire.
Le moyen le plus simple d'éviter que cela utiliserait std :: vecteur :: réserve () < / a> Si vous savez plus ou moins à quel point votre matrice peut augmenter. P>
Vous pouvez également envisager d'utiliser std :: deque au lieu de vecteur, donc Vous n'aurez pas de problème avec la fragmentation de la mémoire du tout. P>
Voici le sujet sur Stackoverflow qui peut être intéressant pour vous: what-is-fragmentation a>. p>
Un bon moyen de minimiser l'allocation de mémoire répétée et la réaffectement avec std :: vecteur code> est de faire une utilisation libérale de
std :: vecteur :: réserve () code> si vous Avoir une idée du nombre d'éléments que votre vecteur utilisera. Cela prévenillera la capacité et empêchera le redimensionnement de la matrice interne Le vecteur est de maintenir lorsque vous ajoutez des éléments via
push_back () code>. P>.
Il existe un paramètre de modèle d'allocator optionnel que vous pouvez spécifier pour obtenir un contrôle plus strict sur la manière dont les allocations de mémoire sont effectuées.