¿Alguien puede explicar este diagrama sobre la asignación de losas?


10

Estoy tratando de entender cómo funciona la asignación de losas y por qué es diferente o mejor que la paginación normal.

Me encontré con este diagrama que creo que sería de gran ayuda si tenía más explicación.

Algunas preguntas:

  • ¿Qué representan los elementos de 3 KB y 7 KB? ¿Deben estar relacionados de alguna manera? ¿Por qué están empaquetados de esa manera?
  • En la columna de cachés, ¿son los cachés los cuadros grises o los cuadros blancos / azules dentro de los cuadros grises? ¿Son las cajas grises un paquete de cachés?
  • ¿Las losas son solo las cajas azules o las "páginas contiguas físicas" son una losa?

Realmente agradecería algo de ayuda. ¡Gracias!

Asignación de losas

Respuestas:


15

Puedo ver por qué estás confundido. El diagrama es un poco confuso y en realidad puede ser incorrecto.

En primer lugar, pensemos por qué un núcleo necesita un asignador de memoria por debajo del nivel de las páginas. Probablemente esto ya sea algo que la mayoría conoces, pero lo analizaré para completarlo.

Las páginas son la "unidad" típica de las operaciones de memoria. Cuando una aplicación de espacio de usuario asigna memoria, o asigna mapas de memoria a un archivo, o algo así, generalmente obtiene un múltiplo del tamaño de página de la máquina. Hay notables algunas excepciones; Windows usa 64k como la unidad de asignación de memoria virtual, sin importar el tamaño de página de la CPU. Sin embargo, pensemos de esta manera.

En una CPU moderna, en lo que respecta al código de espacio de usuario, tiene un espacio de dirección plano. Esto es en realidad una ilusión proporcionada por el sistema de memoria virtual. El sistema operativo proporciona páginas desde cualquier lugar en la RAM (o posiblemente no en la RAM, en el caso de la memoria intercambiada o los archivos asignados a la memoria) y los asigna a un espacio de direcciones virtual contiguo.

El punto de todo esto es que, aparte de algunos casos especiales para el sistema operativo en sí (tal vez búferes DMA, tal vez algunas estructuras de datos especiales configuradas en el momento del arranque, oh y la imagen del núcleo en sí), el núcleo del sistema operativo probablemente nunca tenga que administrar cualquier bloque de RAM más grande que una página. Esto simplifica enormemente las cosas, porque significa que, en lo que respecta a las páginas, cada asignación y desasignación es del mismo tamaño. También elimina efectivamente la fragmentación externa a nivel macro.

Sin embargo, los núcleos también necesitan implementar algunas estructuras de datos propias, y para eso, necesitan un tipo diferente de asignador de memoria. Estas estructuras de datos generalmente pueden considerarse como una colección de objetos individuales (por ejemplo, un objeto puede ser un "hilo" o un "mutex"). El tamaño de estos objetos suele ser mucho más pequeño que el tamaño de una página.

Entonces, por ejemplo, un objeto que representa las credenciales de seguridad de un proceso (piense en la identificación del usuario y la identificación del grupo en POSIX, por ejemplo) podría tener solo 16 bytes, mientras que un "proceso" o "subproceso" podría 1 kb de tamaño. Claramente, no desea utilizar una página completa para estos pequeños registros, por lo que la idea es implementar un asignador en la parte superior de las páginas.

El sistema de asignación de nivel inferior tiene que satisfacer muchos de los mismos problemas que el asignador de nivel de página: tiene que ser razonablemente rápido (incluso en sistemas multinúcleo), desea minimizar la fragmentación, etc. Pero, lo que es más importante, debe poder ajustarse y configurarse según el tipo de estructura de datos que esté almacenando.

Algunas estructuras de datos son inherentemente "tipo caché". Por ejemplo, muchos sistemas operativos mantienen un caché de nombres de ruta a los objetos del sistema de archivos para evitar largas cadenas de búsqueda en el directorio (llamado "caché de nombres" o "caché de namei" en Unix-speak). Estos objetos solo son necesarios para el rendimiento, no para la corrección, por lo que podría (en teoría) simplemente olvidar una página completa llena de entradas si la memoria es escasa y necesita liberar un marco de página rápidamente.

Otras estructuras de datos podrían intercambiarse al disco si la memoria es escasa y no las necesita pronto. ¡Pero no desea hacer eso con estructuras de datos que controlan el intercambio o el sistema de memoria virtual!

Algunas estructuras de datos se pueden mover en la memoria sin penalización (por ejemplo, si nadie se refiere a ellas con un puntero), por lo que podrían "compactarse" para evitar la fragmentación si es necesario.

Entonces, la idea principal del asignador de losas es que una página solo debe almacenar estructuras de datos del mismo "tipo". Esto marca todas las casillas: cada objeto en una página tiene el mismo tamaño, por lo que no hay fragmentación externa. Los objetos del mismo "tipo" tienen los mismos requisitos de rendimiento y la misma semántica.

Por cierto, es una historia similar con la asignación. Para algunos tipos de objetos, probablemente esté bien esperar si no hay memoria disponible inmediatamente para asignar ese objeto. Un objeto que representa un archivo abierto podría ser un ejemplo; abrir un archivo es una operación costosa en el mejor de los casos, por lo que esperar un poco más no hará mucho daño.

Para otros tipos de objeto (p. Ej., Un objeto que representa un evento en tiempo real que debe suceder en un momento determinado a partir de ahora), realmente no desea esperar. Por lo tanto, tiene sentido que algunos tipos de objetos se sobreasignen (por ejemplo, tengan algunas páginas libres en reserva) para que las solicitudes puedan satisfacerse sin esperar.

Lo que básicamente está haciendo es permitir que cada tipo de objeto tenga su propio asignador, que se puede configurar para las necesidades de ese objeto. Estos asignadores por objeto se denominan confusamente "cachés". Usted asigna un caché por tipo de objeto. (Sí, normalmente implementaría también un "caché de cachés"). Cada caché solo almacena objetos del mismo tipo (por ejemplo, solo estructuras de hilos o solo estructuras de espacio de direcciones).

Cada caché, a su vez, gestiona "losas". Una losa es un marco de página que contiene una matriz de objetos del mismo tipo. Las losas pueden estar "llenas" (todos los objetos en uso), "vacías" (sin objetos en uso) o "parciales" (algunos objetos en uso).

Las losas parciales son probablemente las más interesantes, ya que el asignador de losas mantiene una lista libre para cada losa parcial. (Las losas completas y las losas vacías no necesitan una lista libre). Los objetos se asignan primero de las losas parciales (y probablemente de las losas parciales "más completas" primero) para tratar de evitar la asignación de páginas que no son necesarias.

Lo bueno de la asignación de losas es que todas estas opciones de política de asignación (así como la semántica de memoria) se pueden ajustar para cada tipo de objeto. Algunos cachés pueden retener un grupo de losas vacías y otros no. Algunos podrían intercambiarse a un almacenamiento secundario y otros no.

Linux tiene tres tipos diferentes de asignador de losas, dependiendo de si necesita o no compacidad, capacidad de almacenamiento en caché o velocidad bruta. Hubo una buena presentación sobre esto hace un par de años que explica bien las compensaciones.

El asignador de losas Solaris (consulte el documento para obtener más detalles ) tiene algunos detalles más para exprimir aún más el rendimiento. Para empezar, en Solaris, todo se hace con la asignación de losas, incluida la asignación de marcos de página. (Esta es la solución de Solaris para asignar objetos que tienen un tamaño mayor a la mitad de una página). Maneja objetos más pequeños anidando asignadores de losas en el espacio asignado por losas.

Algunos objetos en Solaris requieren una construcción y destrucción compleja y costosa (por ejemplo, objetos que tienen un bloqueo del núcleo), por lo que podrían estar "parcialmente libres" (es decir, construidos pero no asignados). Solaris también optimiza la asignación de losas libres al mantener listas libres por CPU, asegurando que algunas operaciones estén completamente libres de esperas.

Para admitir la asignación de propósito general (por ejemplo, para matrices cuyo tamaño no se conoce en tiempo de compilación), la mayoría de los sistemas operativos de tipo macrokernel también tienen cachés que representan tamaños de objeto en lugar de tipos de objeto . FreeBSD, por ejemplo, mantiene cachés para objetos desconocidos cuyos tamaños son potencias de 2 bytes, de 4 a 256.

Lo que espero que puedan ver es que la asignación de losas es un marco muy flexible que puede ajustarse a las necesidades de diferentes tipos de datos. No compite con la paginación, pero la complementa (aunque en Solaris, los marcos de página se asignan con losas).

Espero que esto ayude. Avíseme si algo necesita aclaración.


6

La idea debajo del asignador de losas es que el sistema operativo necesita estructuras de datos específicas pero algo estándar (por ejemplo, PCB de proceso, semáforos, metadatos de archivos, etc.) que sugieren el uso de memoria que es necesario para ellos.

El algoritmo de asignación de losas proporciona reservas de áreas de memoria cuyas dimensiones e inicialización están optimizadas para estas estructuras de datos estándar. Por ejemplo, como puede ver en la imagen, pueden existir objetos de 3kb y de 7kb. Sin embargo, sabemos que el núcleo solo asigna memoria en múltiplos del tamaño de página.

Para evitar el desperdicio de tiempo y memoria, el sistema operativo mantiene en diferentes cachés grupos de áreas de memoria que pueden asignarse rápidamente a pedido, y las dimensiones de caché son diferentes para cada tipo de objeto y estructura. Sin embargo, los cachés no contienen y administran directamente estas áreas de memoria, y ni siquiera se garantiza que residan en la memoria contigua. En cambio, se dividen en losas, páginas contiguas de memoria, cuyo número generalmente se elige para reducir la fragmentación de la memoria. Es en la losa donde residen las diferentes instancias de objeto, ya sean asignadas o libres. Si un caché está lleno, se asigna una nueva losa en algún lugar de la memoria primaria y se agrega al caché.

En resumen, las cosas que puede ver en la imagen son ejemplos de objetos que el sistema operativo sabe que son 3-7, cualquiera que sea el KB grande. El núcleo no asigna una memoria de página específicamente para ellos, ya que eso aumentaría exponencialmente la fragmentación de la memoria, sino que los "redirigirá" a un caché (el cuadro gris). En el caché debe haber direcciones que indiquen áreas de memoria físicamente contiguas, las losas (los conjuntos de cajas blancas / azules) y los objetos finalmente se asignan en un área de la losa (una parte que está coloreada en azul, libre de áreas de memoria análogas completas de la misma losa).

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.