2008-09-29 7 views
37

Me gusta desarrollar algoritmos usando STL, sin embargo, tengo este problema recurrente donde mis conjuntos de datos son demasiado grandes para el montón.Clases de contenedor STL con respaldo de disco?

He estado buscando sustitutos para contenedores STL y algoritmos que están respaldados por disco, es decir, las estructuras de datos están almacenadas en el disco en lugar de en el montón.

Un amigo me señaló recientemente hacia stxxl. Antes de involucrarme demasiado ... ¿Hay otros reemplazos de STL respaldados por disco disponibles que debería considerar?

NOTA: No estoy interesado en la persistencia o las bases de datos incrustadas. Por favor, no mencione boost :: serialization, POST ++, Relational Template Library, Berkeley DB, sqlite, etc. Conozco estos proyectos y los uso cuando son apropiados para mis propósitos.

ACTUALIZACIÓN: Varias personas han mencionado los archivos de mapeo de memoria y el uso de un asignador de costumbre, buenas sugerencias BTW, pero me gustaría señalar que la discusión here donde David Abraham sugiere que se necesitarían iteradores personalizados para contenedores de disco con respaldo . Lo que significa que no es probable que el enfoque del asignador personalizado funcione.

+0

Si sus conjuntos de datos son demasiado grandes para el almacenamiento dinámico, debe considerar si la arquitectura de su sistema es correcta (por ejemplo, si se mueve a un sistema de 64 bits; estos son más comunes ahora que cuando se formuló la pregunta). También debe considerar si el STL es el enfoque correcto; puede hacer suposiciones sobre el tamaño del conjunto de datos que no son válidas para usted. –

+0

@Donal Puede que no esté reservando la cantidad correcta de memoria. –

Respuesta

10

He implementado algo muy similar. Implementar los iteradores es el más desafiante. Usé boost::iterator_facade para implementar los iteradores. Utilizando boost::iterator_facade puede easy adaptar cualquier en caché en estructuras de datos de disco para tener una interfaz de contenedor STL.

+0

Uso Boost, pero iterator_facade es nuevo para mí. Tendré que echarle un vistazo a eso, gracias por compartir. – paxos1977

+0

¿Te importa compartir la implementación? –

+0

Desafortunadamente no puedo compartir ese código. Sin embargo, si tiene alguna pregunta, estaría encantado de ayudarlo. – Ted

2

No sé mucho sobre el tema, pero podría ser posible escribir una interfaz similar a STL en un archivo mapeado en memoria?

editar: Este enfoque puede ser adecuado si intenta acceder a una parte específica de un archivo enorme. Si intenta hacer algo con todo el archivo, es probable que genere una gran cantidad de fallas de página al leer en partes no guardadas en caché del archivo.

+0

He considerado hacer esto ... pero prefiero no escribirlo si algo ya se puede usar. – paxos1977

+0

Puedo apreciar que no quiero reinventar la rueda. No estoy familiarizado con una biblioteca que hace esto; con suerte alguien puede recomendar uno. – luke

+0

Creo que Boost.Interprocess se puede utilizar para escribir en un archivo mapeado en la memoria. No lo he probado, sin embargo. –

3

Si (como usted escribe) no le interesa la persistencia, la solución más simple sería aumentar su tamaño de almacenamiento dinámico y usar las instalaciones de memoria virtual de su sistema operativo. La parte del montón que no cabe en la memoria física de su computadora terminará siendo paginada en el disco, proporcionándole exactamente lo que desea: acceso STL normal a los datos almacenados a menudo en el disco. El sistema operativo se encargará de almacenar en caché las páginas más usadas en la memoria física y desalojar en disco las que no usa mucho. Su código seguirá siendo el mismo, y puede aumentar su rendimiento simplemente agregando más memoria física.

Para aumentar su tamaño de almacenamiento dinámico, verifique los parámetros de su sistema operativo, como ulimit (1) en sistemas Unix y Propiedades del sistema - Avanzado - Rendimiento - Avanzado - Memoria virtual en Windows XP. Si alcanzas el límite de 4 GB de 32 bits, considera moverte a una arquitectura de 64 bits o compila tu programa para 64 bits.

+0

Soy un administrador de sistemas competente, he considerado el enfoque que sugirió. Tengo una máquina amd64 que ejecuta Unix. No puedo permitirme agregar más memoria física. Mi espacio de intercambio es de 2 GB, mi conjunto de datos es de 42 GB, mi disco duro es de 1 TB ... – paxos1977

+1

Entonces, ¿qué hay de aumentar el espacio de intercambio? – Arkadiy

+0

Claro, he pensado en reconstruir mi servidor para acomodar este proyecto. Sin embargo, esto no es hardware dedicado, sino una máquina utilizada para investigación general. Más allá de eso, eventualmente los colaboradores necesitarán ejecutar el código también, y no creo que requerirles que reconstruyan sus máquinas funcionará. – paxos1977

8

Nunca he tenido que hacer algo como esto, pero podría ser posible hacer lo que quiera haciendo escribiendo un asignador personalizado que haga uso de una memoria de archivos asignados para respaldar sus datos.

Ver boost::interprocesses de documentos en su fácil de usar aplicación de la memoria, los archivos this Dr. Dobbs article para una discusión detallada sobre los asignadores de escritura, y this IEEE Software column asignada para una descripción del problema y example code.

+0

Conozco el artículo DDJ, buen artículo. Sin embargo, hubo una discusión sobre la lista de correo de boost entre Terpstra, Kuehl y Abraham sugiriendo que se necesitarían iteradores personalizados para tratar con las estructuras de datos en disco ... lo cual descarta el enfoque del asignador personalizado. – paxos1977

Cuestiones relacionadas