191 votes

Des exemples convaincants d'allocuteurs C ++ personnalisés?

Quelles sont les bonnes raisons d’abandonner std::allocator en faveur d’une solution personnalisée? Avez-vous rencontré des situations où l'exactitude, la performance, l'évolutivité, etc. étaient absolument nécessaires? Des exemples vraiment intelligents?

Les allocateurs personnalisés ont toujours été une fonctionnalité de la bibliothèque standard dont je n'avais pas vraiment besoin. Je me demandais si quelqu'un sur SO pouvait fournir des exemples convaincants pour justifier son existence.

134voto

timday Points 14860

Comme je le mentionne ici, j'ai vu Intel TBB personnalisé STL allocateur d'améliorer sensiblement les performances d'une application multithread, simplement en changeant un seul

std::vector<T>

pour

std::vector<T,tbb::scalable_allocator<T> >

(c'est un moyen rapide et pratique de commutation de l'allocateur d'utiliser TBB est chouette thread-privé tas; voir à la page 7 de ce document)

91voto

Grumbel Points 1296

Un domaine où la coutume allocateurs peut être utile, c'est le développement de jeux, notamment sur les consoles de jeu, comme ils l'ont seulement une petite quantité de mémoire et pas de swap. Sur ces systèmes, vous voulez vous assurer que vous avez un contrôle serré sur chaque sous-système, de sorte que l'on critique le système ne peut pas voler la mémoire d'une critique. D'autres choses comme la piscine allocateurs peut aider à réduire la fragmentation de la mémoire. Vous pouvez trouver un long document détaillé sur le sujet:

EASTL -- Electronic Arts Modèle Standard de la Bibliothèque

79voto

Johannes Thoma Points 384

Je suis en train de travailler sur un mmap-allocateur qui permet vecteurs pour utiliser la mémoire de un fichier mappé en mémoire. Le but est d'avoir des vecteurs que l'utilisation de stockage que sont directement dans la mémoire virtuelle obtenue par mmap. Notre problème est de améliorer la lecture de gros fichiers (>10GB) dans la mémoire avec aucune copie les frais généraux, donc j'ai besoin de cet allocateur personnalisé.

Jusqu'à présent j'ai le squelette d'un allocateur personnalisé (qui dérive de std::allocator), je pense que c'est un bon départ point d'écrire propre allocateurs. N'hésitez pas à utiliser ce bout de code quelle que soit la façon dont vous le souhaitez:

#include <memory>
#include <stdio.h>

namespace mmap_allocator_namespace
{
        template <typename T>
        class mmap_allocator: public std::allocator<T>
        {
public:
                typedef size_t size_type;
                typedef T* pointer;
                typedef const T* const_pointer;

                template<typename _Tp1>
                struct rebind
                {
                        typedef mmap_allocator<_Tp1> other;
                };

                pointer allocate(size_type n, const void *hint=0)
                {
                        fprintf(stderr, "Alloc %d bytes.\n", n*sizeof(T));
                        return std::allocator<T>::allocate(n, hint);
                }

                void deallocate(pointer p, size_type n)
                {
                        fprintf(stderr, "Dealloc %d bytes (%p).\n", n*sizeof(T), p);
                        return std::allocator<T>::deallocate(p, n);
                }

                mmap_allocator() throw(): std::allocator<T>() { fprintf(stderr, "Hello allocator!\n"); }
                mmap_allocator(const mmap_allocator &a) throw(): std::allocator<T>(a) { }
                template <class U>                    
                mmap_allocator(const mmap_allocator<U> &a) throw(): std::allocator<T>(a) { }
                ~mmap_allocator() throw() { }
        };
}

Pour l'utiliser, déclarer un conteneur STL comme suit:

using namespace std;
using namespace mmap_allocator_namespace;

vector<int, mmap_allocator<int> > int_vec(1024, 0, mmap_allocator<int>());

Il peut être utilisé par exemple pour ouvrir une session chaque fois que la mémoire est allouée. Ce qui est nécessaire est le relier struct, sinon le vecteur contenant utilise le super-classes allouer/désallouer des méthodes.

Mise à jour: Le mappage de la mémoire de l'allocateur est maintenant disponible à https://github.com/johannesthoma/mmap_allocator et LGPL. N'hésitez pas à utiliser pour vos projets.

29voto

Thomas Jones-Low Points 4987

Je travaille avec un moteur de stockage MySQL qui utilise c ++ pour son code. Nous utilisons un allocateur personnalisé pour utiliser le système de mémoire MySQL plutôt que de concurrencer MySQL pour la mémoire. Cela nous permet de nous assurer que nous utilisons la mémoire comme utilisateur a configuré MySQL, et non "extra".

24voto

Martin Cote Points 12762

Il peut être utile d'utiliser des allocateurs personnalisés pour utiliser un pool de mémoire au lieu du tas. C'est un exemple parmi beaucoup d'autres.

Dans la plupart des cas, il s'agit certainement d'une optimisation prématurée. Mais cela peut être très utile dans certains contextes (appareils embarqués, jeux, etc.).

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