Je travaille sur un mmap-allocator qui permet aux vecteurs d'utiliser la mémoire d'un fichier mappé en mémoire. L'objectif est d'avoir des vecteurs qui utilisent le stockage qui sont directement dans la mémoire virtuelle mappés par mmap. Notre problème est d'améliorer la lecture de fichiers vraiment volumineux (> 10 Go) en mémoire sans surcharge de copie, j'ai donc 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 point de départ pour écrire ses propres allocateurs. N'hésitez pas à utiliser ce morceau de code comme vous le souhaitez:
#include <memory>
#include <stdio.h>
namespace mmap_allocator_namespace
{
// See StackOverflow replies to this answer for important commentary about inheriting from std::allocator before replicating this code.
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éclarez 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 enregistrer chaque fois que de la mémoire est allouée. Ce qui est nécessaire est la structure de rebind, sinon le conteneur vectoriel utilise les méthodes d'allocation / désallocation des superclasses.
Mise à jour: L'allocateur de mappage de mémoire est maintenant disponible sur https://github.com/johannesthoma/mmap_allocator et est LGPL. N'hésitez pas à l'utiliser pour vos projets.