¿Cuál es el significado del término arena en relación con la memoria?

100

Estoy leyendo un libro sobre la memoria como concepto de programación. En uno de los últimos capítulos, el autor hace un uso intensivo de la palabra arena , pero nunca la define. Busqué el significado de la palabra y cómo se relaciona con la memoria, y no encontré nada. A continuación, se muestran algunos contextos en los que el autor usa el término:

"El siguiente ejemplo de serialización incorpora una estrategia llamada asignación de memoria desde un campo específico ".

"... esto es útil cuando se trata de pérdidas de memoria o cuando se asigna desde un campo específico ".

"... si queremos desasignar la memoria, desasignaremos toda la arena ".

El autor usa el término más de 100 veces en un capítulo. La única definición en el glosario es:

asignación desde la arena : técnica de asignar una arena primero y luego administrar la asignación / desasignación dentro de la arena por el programa mismo (en lugar de por el administrador de memoria del proceso); se utiliza para la compactación y serialización de estructuras y objetos de datos complejos, o para administrar la memoria en sistemas críticos para la seguridad y / o tolerantes a fallas.

¿Alguien puede definir arena para mí dados estos contextos?

Nocturno
fuente
¿Cuál es el nombre del libro?
yaobin
1
@yaobin La memoria como concepto de programación en C y C ++ por Frantisek Franek.
Nocturno

Respuestas:

111

Una arena es solo una pieza grande y contigua de memoria que se asigna una vez y luego se usa para administrar la memoria manualmente al distribuir partes de esa memoria. Por ejemplo:

char * arena = malloc(HUGE_NUMBER);

unsigned int current = 0;

void * my_malloc(size_t n) { current += n; return arena + current - n; }

El punto es que tienes control total sobre cómo funciona la asignación de memoria. Lo único que está fuera de su control es la llamada de biblioteca única para la asignación inicial.

Un caso de uso popular es donde cada campo solo se usa para asignar bloques de memoria de un solo tamaño fijo. En ese caso, puede escribir algoritmos de recuperación muy eficientes. Otro caso de uso es tener una arena por "tarea", y cuando haya terminado con la tarea, puede liberar toda la arena de una sola vez y no necesita preocuparse por rastrear las desasignaciones individuales.

Cada una de esas técnicas es muy especializada y, por lo general, solo es útil si sabe exactamente lo que está haciendo y por qué la asignación normal de la biblioteca no es lo suficientemente buena. Tenga en cuenta que un buen asignador de memoria ya hará mucha magia por sí mismo, y necesita una cantidad decente de evidencia de que eso no es lo suficientemente bueno antes de comenzar a manejar la memoria usted mismo.

Kerrek SB
fuente
25
Es una buena respuesta, pero considere eliminar o modificar el último párrafo. Realmente no necesitas ninguna prueba. Cada vez que sabe cómo va a usar la memoria, sabe más que un "buen" asignador de propósito general, y si usa este conocimiento, su asignador personalizado siempre ganará. Los asignadores no son mágicos. Una arena es útil si tiene muchos elementos que mueren en el mismo momento bien definido. Eso es prácticamente todo lo que necesitas saber. No es una ciencia exacta.
Andreas Haferburg
11
@AndreasHaferburg: El asignador de memoria de la biblioteca estándar tiene automáticamente una gran ventaja sobre la escritura personalizada, es decir, que no tiene que escribir / probar / depurar / mantener, etc. Incluso si está seguro sin evidencia de que puede mejorar el rendimiento al administrar su propia asignación, aún necesita una buena evidencia antes de decidir que esta mejora vale la pena.
ruakh
17
@ruakh Simplemente no me gusta esta mentalidad de culto al cargo que se repite un millón de veces en todas partes como "sabiduría". "Los dioses de C ++ nos lo dieron, así que tenemos que usarlo". Y mi favorito: "Es mágico". No. No es magia. Es solo un algoritmo que es tan simple que incluso una computadora puede ejecutarlo. En mi libro eso está bastante lejos de ser mágico. Mi conjetura: subestimas el impacto que puede tener la asignación de memoria en el rendimiento y sobreestimas lo complicadas que son las arenas. Si el rendimiento es más importante que el tiempo del desarrollador es una decisión empresarial que es un poco inútil discutir sobre SO.
Andreas Haferburg
8
@AndreasHaferburg: Claro, tcmalloc usa un algoritmo particular, y la idea detrás de él es bastante fácil de explicar, pero la implementación sigue siendo compleja y no trivial. Lo más importante es que se requieren conocimientos específicos de la plataforma para ordenar correctamente la memoria. Utilizo "magia" para cosas que el usuario no puede escribir de forma portátil (como un mutex eficiente, o tcmalloc, o el nombre de tipo de un lambda), o solo con heroísmo extremo (como std :: function); No lo digo como "no se puede entender".
Kerrek SB
12
@AndreasHaferburg: Y mi consejo final no es tanto decir que en principio es difícil "saber mejor que el predeterminado", sino que el costo de mantener una solución personalizada es alto (alguien tiene que escribirla, documentarla, obtenerla correcto, y alguien más tiene que corregir los errores, y todos tienen que revisar y volver a verificar las suposiciones originales a medida que el uso se extiende), y que necesita evidencia para justificar ese costo.
Kerrek SB
10

Iré con esta como una posible respuesta.

•Memory Arena (also known as break space)--the area where dynamic runtime memory is stored. The memory arena consists of the heap and unused memory. The heap is where all user-allocated memory is located. The heap grows up from a lower memory address to a higher memory address.

Agregaré los sinónimos de Wikipedia : región, zona, arena, área o contexto de memoria.

Básicamente, es la memoria que obtiene del sistema operativo y la divide, luego se puede liberar de una vez. La ventaja de esto es que las pequeñas llamadas repetidas a malloc()pueden ser costosas (cada asignación de memoria tiene un costo de rendimiento: el tiempo que lleva asignar la memoria en el espacio de direcciones lógicas de su programa y el tiempo que lleva asignar ese espacio de direcciones a la memoria física) donde, como si conociera un parque de pelota, puede obtener una gran cantidad de memoria y luego entregarla a sus variables como / cómo lo necesite.

Miguel
fuente
5

Piense en ello como un sinónimo de "montón". Por lo general, su proceso solo tiene un montón / arena, y toda la asignación de memoria ocurre desde allí.

Pero, a veces, tiene una situación en la que debería agrupar una serie de asignaciones (por ejemplo, para el rendimiento, para evitar la fragmentación, etc.). En ese caso, es mejor asignar un nuevo montón / arena, y luego, para cualquier asignación, puede decidir desde qué montón asignar.

Por ejemplo, puede tener un sistema de partículas en el que se asignan y desasignan con frecuencia muchos objetos del mismo tamaño. Para evitar la fragmentación de la memoria, puede asignar cada partícula de un montón que solo se usa para esas partículas, y todas las demás asignaciones vendrían del montón predeterminado.

Adam Rosenfield
fuente
5

De http://www.bozemanpass.com/info/linux/malloc/Linux_Heap_Contention.html :

La biblioteca compartida libc.so.x contiene el componente glibc y el código del montón reside en su interior. La implementación actual del montón usa múltiples sub-montones independientes llamados arenas. Cada arena tiene su propio mutex para protección de concurrencia. Por lo tanto, si hay suficientes arenas dentro del montón de un proceso y un mecanismo para distribuir los accesos al montón de los subprocesos de manera uniforme entre ellos, entonces el potencial de contención por los mutex debe ser mínimo. Resulta que esto funciona bien para las asignaciones. En malloc (), se realiza una prueba para ver si el mutex para la arena de destino actual para el hilo actual es libre (trylock). Si es así, la arena ahora está bloqueada y la asignación continúa. Si el mutex está ocupado, entonces se prueba cada arena restante y se usa si el mutex no está ocupado. En el caso de que ninguna arena pueda bloquearse sin bloquear, se crea una nueva arena. Esta arena, por definición, aún no está bloqueada, por lo que la asignación ahora puede continuar sin bloqueo. Por último, el ID del campo utilizado por última vez por un hilo se conserva en el almacenamiento local del hilo y, posteriormente, se utiliza como el primer campo para probar cuando ese hilo llama a malloc (). Por lo tanto, todas las llamadas a malloc () continuarán sin bloquearse.

También puede consultar este enlace:

http://www.codeproject.com/Articles/44850/Arena-Allocator-DTOR-and-Embedded-Preallocated-Buf

Rahul Tripathi
fuente
3
Para su información, al publicar enlaces, debe publicar un resumen para que, si el artículo vinculado desaparece, su publicación siga siendo útil.
Stonemetal
5
Esto parece ser un copiar y pegar de bozemanpass.com/info/linux/malloc/Linux_Heap_Contention.html Por favor, crédito a sus fuentes cuando las use textualmente.
jscs