2010-11-12 10 views
11

Busco una respuesta definitiva (si es que existe uno) de la cantidad de memoria debe asignarse al crear unos trozos estáticos de memoria compartida a través de boost::interprocess 's managed_shared_memory. Incluso official examples parecen asignar arbitrarily large trozos de memoria.¿Cuánta memoria debe asignar 'managed_shared_memory'? (Impulso)

Considérese la siguiente estructura:

// Example: simple struct with two 4-byte fields 
struct Point2D { 
    int x, y; 
}; 

Mi reacción inicial es que el tamaño necesario sería de 8 bytes, o sizeof(Point2D). Esto falla miserablemente cuando intento construir un objeto, dándome seg-faults en tiempo de ejecución.

// BAD: 8 bytes is nowhere near enough memory allocated. 
managed_shared_memory segment(create_only, "My shared memory", sizeof(Point2D)); 

¿Qué operación de lectura/escritura está causando seg-faults? Operaciones de pila? ¿Asignaciones temporales dentro de segment.construct()? ¿Cuánta sobrecarga es necesaria al asignar memoria compartida?

Por prueba y error Descubrí que multiplicar el tamaño por 4 puede funcionar para la estructura anterior, pero se desmorona cuando empiezo a agregar más campos a mi struct. Entonces, eso apesta a un hack malo.

Algunos podrían argumentar que "la memoria es barata" en la PC moderna, pero estoy en desacuerdo con esta filosofía y no me gusta asignar más de lo que necesito, si puedo evitarlo. Cavé alrededor de los documentos de Boost ayer y no pude encontrar ninguna recomendación. ¡Aquí hay algo de aprendizaje hoy!

+1

La gente puede estar en desacuerdo conmigo aquí, pero nunca en mi vida he codificado la frase "la memoria es barata". Comprar memoria no es necesariamente caro comparado con lo que solía ser, pero se parece mucho al dinero. Cuanto más tienes, más gastas. Cada actualización de memoria que compré para mi computadora, ya me he agotado bastante rápido ahora que puedo "ejecutar más cosas". Siempre he tratado de codificar de manera conservadora a este respecto porque no es necesariamente barato * para mi aplicación *. De todos modos, solo mi 2c en eso :) –

+0

Estoy de acuerdo 100%! Y ese es el motivo ** completo ** por el que hago esta pregunta. Solo lancé ese comentario para disuadir a cualquiera que dijera "a quién le importa, solo asigne 1k y termine con eso". Trataré de dejarlo más claro en la publicación. –

+0

Ah ok :) "Algunos podrían argumentar" ¡es mucho mejor! –

Respuesta

8

De this paragraph de la documentación:

El algoritmo de la memoria es un objeto que se coloca en los primeros bytes de un segmento de archivo memoria compartida/memoria mapeada.

diseño del segmento de memoria:

____________ __________ ____________________________________________ 
|   |   |           | 
| memory | reserved | The memory algorithm will return portions | 
| algorithm |   | of the rest of the segment.    | 
|____________|__________|____________________________________________| 

La biblioteca cuenta con una memoria adicional sobrecarga reunión al comienzo del segmento, por lo que ocupan unos pocos bytes de su tamaño solicitado. De acuerdo con this post y this post, este número exacto de bytes adicionales que no se puede determinar:

no se puede calcular, porque no son memoria bookeeping asignación y problemas de fragmentación que cambian en tiempo de ejecución en función de su asignación /patrón de desasignación. Y de memoria compartida se asigna por páginas por el sistema operativo (4K en 64k Linux en ventanas), por lo que cualquier asignación será en la práctica asignada redondeado a una página :

managed_shared_memory segment(create_only, "name", 20); 

será un desperdicio de la misma memoria que :

managed_shared_memory segment(create_only, "name", 4096); 
+0

Buen trabajo para encontrar esa publicación anterior; Busqué por un tiempo y salí seco. Entonces, por "de verdad" ¿quieres decir que ** no hay una respuesta concreta? ** Eso es lo que recibo de la respuesta de Ion Gaztañaga ... Además, gracias por ese enlace a los documentos de Boost. El mapa de memoria ASCII art me ayuda, aunque no tuve la suerte de determinar programáticamente 'algoritmo de memoria' +' reservado'. Pero, en última instancia, es un punto discutible ya que mi implementación actual almacena 5-10 instancias de estructura (también mencionadas por Gaztañaga). Aún así, parece una pregunta válida, incluso si es principalmente "académica". –

+0

Ah, * allí * vamos. Sabía que el tamaño de página del sistema operativo debe ser un detalle relevante; la cita anterior confirma mis sospechas. Parece que la asignación de "mejor suposición" tendrá que hacer. Gracias de nuevo. –

2

Algo así como el uso de las obras de tamaño de página de memoria OS'es. En mi caso, esto funciona ...

off_t size = sizeof(class1) + (sizeof(class2) * 3); 
// round up to the OS page size. 
long page_size = sysconf(_SC_PAGE_SIZE); 
size = ((size/page_size) + (size % page_size ? 1 : 0)) * page_size; 

El uso de boost :: managed_shared_memory le permite construir objetos en el espacio resultante. Algo así como ...

shared_memory_object::remove(m_name.c_str()); 
m_shared.reset(new managed_shared_memory(create_only, "myspace", size)); 
m_class1 = m_shared->construct<class1>("class1")(); 
m_class2 = m_shared->construct<class2>("class2")[3](); 
+0

+1 Me gusta la idea de redondear al tamaño de página del sistema. Sin embargo, todavía parece que estamos creando ** una cantidad arbitraria de relleno **. En este caso "3" - tres veces 'sizeof (class2)'. ¿Estoy en lo correcto? Desde entonces he pasado a otros proyectos, pero todavía estoy interesado en la mejor manera de asignar memoria compartida con la menor cantidad de desperdicio. –

+0

No puedo ver de todos modos para moverme usando el tamaño de página para el área de memoria compartida. (Se corrigió un error en el segundo bit de código.) Sin embargo, puede hacer el tipo de subasignación que estaba usando en el segundo bit de código dentro del área de memoria compartida. mira en http://en.highscore.de/cpp/boost/interprocesscommunication.html#interprocesscommunication_managed_shared_memory da una buena idea de las muchas formas en que se puede realizar la subasignación. Será mejor que aprenda este editor para poder enlazar más limpiamente * suspiro * – lprent

Cuestiones relacionadas