8
votes

Devrais-je m'inquiéter de la fragmentation de la mémoire avec std :: vecteur?

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.

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?

Merci pour tout conseil!


1 commentaires

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.


6 Réponses :


1
votes

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.


3 commentaires

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.



13
votes

La réponse à vos inquiétudes peut être std :: deque . Il vous donne une interface similaire à celle de std :: vecteur , 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 dans certains aspects, mais pour votre cas, il peut s'agir d'un bon compromis.


2 commentaires

Pouvez-vous site une source pour les revendications que vous faites? de préférence une référence standard? MISE À JOUR 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 à 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 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.



2
votes

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>

  1. Pré-allocation de capacité: p>

     std::vector<int> x(1000); // size() is 1000
    
     std::vector<int> y;
     y.reserve(1000); // size() is 0, capacity is 1000
    
  2. Utilisez un allocator personnalisé p>


0 commentaires

3
votes

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 nouveau manutention.

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.

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.

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.


0 commentaires

6
votes

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.

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.

Voici le sujet sur Stackoverflow qui peut être intéressant pour vous: what-is-fragmentation .


0 commentaires

2
votes

Un bon moyen de minimiser l'allocation de mémoire répétée et la réaffectement avec std :: vecteur est de faire une utilisation libérale de std :: vecteur :: réserve () 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 () . .


0 commentaires