Estoy trabajando en un mmap-allocator que permite a los vectores usar la memoria de un archivo mapeado en memoria. El objetivo es tener vectores que usen almacenamiento que estén directamente en la memoria virtual mapeados por mmap. Nuestro problema es mejorar la lectura de archivos realmente grandes (> 10 GB) en la memoria sin sobrecarga de copia, por lo tanto, necesito este asignador personalizado.
Hasta ahora tengo el esqueleto de un asignador personalizado (que se deriva de std :: allocator), creo que es un buen punto de partida para escribir asignadores propios. Siéntase libre de usar este código de la forma que desee:
#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() { }
};
}
Para usar esto, declare un contenedor STL de la siguiente manera:
using namespace std;
using namespace mmap_allocator_namespace;
vector<int, mmap_allocator<int> > int_vec(1024, 0, mmap_allocator<int>());
Se puede usar, por ejemplo, para iniciar sesión cada vez que se asigna memoria. Lo que es necesario es la estructura de reenlace, de lo contrario, el contenedor de vectores utiliza los métodos de asignación / desasignación de superclases.
Actualización: El asignador de asignación de memoria ahora está disponible en https://github.com/johannesthoma/mmap_allocator y es LGPL. Siéntase libre de usarlo para sus proyectos.