Memoria virtual: hardware y fallo de página
🎯 Al terminar podrás
- Explicar por qué la memoria virtual funciona a pesar de que el disco es miles de veces más lento (localidad).
- Decir qué hace cada bit de la PTE (P, M, R) y qué pasa cuando P = 0.
- Seguir el orden TLB → tabla → page fault y calcular el EAT con k niveles, con y sin fallos de página.
- Enumerar los 6 pasos del page fault y distinguir page fault de segmentation fault.
Antes necesitas: Paginación simple: VPN y offset · Estados de un proceso (Bloqueado y Listo)
- Visual mira el diagrama o la tabla y explica qué cambia en cada paso
- Laboratorio sube la escalera: resuelto → completa → solo → variante
- Feynman explícalo en voz alta sin mirar y compara con la lista
Esta página cubre la parte de hardware y estructuras (Stallings §8.1). Lo básico de paginación, segmentación y la calculadora de tablas ya está en Paginación y Segmentación; aquí está lo que cambia cuando la memoria es virtual.
Las dos ideas que lo hacen posible
Sección titulada «Las dos ideas que lo hacen posible»Stallings parte de dos características de la paginación y la segmentación:
- Todas las referencias se traducen en tiempo de ejecución. Un proceso puede moverse de lugar en la RAM (o salir a disco y volver a otro sitio) sin que el programa lo note.
- El proceso no necesita estar contiguo: se parte en páginas o segmentos repartidos por la memoria.
Juntas permiten algo que antes no se podía: ejecutar un proceso sin tener todas sus páginas en RAM. La parte que sí está cargada se llama el conjunto residente (resident set).
Lo que se gana:
- Más procesos en memoria a la vez: cada uno ocupa solo lo que usa, así que es más probable que siempre haya alguno listo para ejecutar.
- Un proceso puede ser más grande que toda la RAM. El programador ya no se preocupa por los overlays.
Por eso se habla de memoria real (la RAM) y memoria virtual (lo que ve cada proceso, respaldado en disco).
Localidad: por qué no colapsa
Sección titulada «Localidad: por qué no colapsa»Si cada referencia cayera en una página distinta, el sistema pasaría todo el tiempo trayendo páginas del disco. Eso se llama thrashing (hiperpaginación): el procesador está ocupado intercambiando páginas en vez de ejecutar instrucciones.
No pasa gracias al principio de localidad: las referencias de un proceso se agrupan. Durante un intervalo, el programa usa unas pocas páginas: un bucle, una función, un arreglo. Así el SO puede adivinar qué páginas van a hacer falta pronto.
Cómo leerlo: cada punto es una referencia a memoria. El eje horizontal es el tiempo y el vertical, la página tocada. Los puntos no se reparten por todo el eje: se amontonan en franjas de pocas páginas (las zonas sombreadas) y saltan de franja cada tanto. Mientras dura una franja, basta con tener esas 4 o 5 páginas en RAM.
| Requisito | Por qué |
|---|---|
| Soporte de hardware para la paginación o segmentación | traducir cada dirección en software sería impracticable |
| Software del SO para mover páginas entre disco y RAM | las políticas de la página siguiente |
La PTE cuando la memoria es virtual
Sección titulada «La PTE cuando la memoria es virtual»Con paginación simple, la tabla solo decía «la página k está en el frame f». Con memoria virtual, la entrada necesita bits de control:
| Bit | Nombre | Para qué |
|---|---|---|
| P | presente / válido | ¿la página está en RAM? Si es 0, el acceso provoca un page fault |
| M | modificado (dirty) | ¿se escribió desde que se cargó? Si sí, hay que escribirla al disco antes de reemplazarla; si no, se descarta sin costo |
| R / U | referenciado / uso | ¿se accedió hace poco? Lo usa el algoritmo Clock y sus variantes |
| — | protección, compartición, bloqueo | lectura/escritura/ejecución, páginas compartidas, frames bloqueados (frame locking) |
| PFN | número de frame | dónde está, si P = 1 |
La dirección virtual se parte en nº de página | offset, y el nº de página elige una de estas entradas. Arriba de cada campo va la pregunta que responde y abajo, quién la usa.
Las tablas son enormes. Por ejemplo, Stallings toma la arquitectura VAX: 2 GB de espacio virtual con páginas de 512 B dan entradas por proceso. Por eso la tabla también vive en memoria virtual y aparecen dos estructuras:
- Tabla de dos (o más) niveles: un directorio raíz que siempre está en RAM y tablas de usuario que pueden estar en disco. Ejemplo típico: 32 bits con páginas de 4 KB y PTE de 4 B dan
10 | 10 | 12. - Tabla invertida: una entrada por frame físico (no por página virtual). Se busca con un hash de (nº de página, PID), y las colisiones se encadenan. Su tamaño depende de la RAM, no del espacio virtual. La usan PowerPC, UltraSPARC e IA-64.
Las fórmulas y la calculadora están en Paginación § multinivel.
TLB: la caché de traducciones
Sección titulada «TLB: la caché de traducciones»Cada referencia a memoria virtual podría costar dos accesos: uno para leer la PTE y otro para el dato. Con tablas de k niveles, son k + 1. La TLB (Translation Lookaside Buffer) es una caché pequeña y asociativa con las PTE usadas hace poco.
Flujo completo (Stallings fig. 8.8):
- La CPU genera la dirección virtual y busca la página en la TLB.
- Acierto en la TLB: se arma la dirección física. Si el bloque está en la caché de datos, se lee de ahí; si no, de RAM.
- Fallo en la TLB: se lee la PTE de la tabla en memoria.
- Si P = 1, se actualiza la TLB y se reintenta.
- Si P = 0, hay page fault. El SO toma el control, lee la página del disco, actualiza la tabla y el proceso vuelve a intentar la instrucción.
Asociativa quiere decir que el hardware compara el número de página con todas las entradas a la vez, porque la TLB no está indexada por página como la tabla.
Si la tabla de páginas cambia (cambio de proceso), la TLB se vacía, o cada entrada lleva un identificador de espacio de direcciones (ASID).
Cómo leerlo: son los tres caminos de la fig. 8.8. Hit (verde, arriba): la TLB da el marco. Miss: se lee la tabla en RAM y, si P = 1, la traducción se copia a la TLB (punteada). P = 0 (rojo): page fault. Los tiempos del dibujo (10 ns y 100 ns) son los de la página de paginación; el peldaño 1 de abajo usa una TLB de 20 ns.
TLB: tiempo efectivo de acceso
Sin TLB, cada referencia cuesta k accesos a la tabla + 1 al dato. Con TLB:
Fórmula del curso, con k niveles de tabla y TLB consultada siempre:
Peldaño 1 · Resueltolee cada paso y su porqué
Resuelto: 1 nivel, TLB de 20 ns, memoria de 100 ns y h = 0.9
- Acierto (90 %): TLB y luego el dato, 20 + 100 = 120 ns.
- Fallo de TLB (10 %): TLB, luego la PTE (1 nivel) y luego el dato, 20 + 100 + 100 = 220 ns.
- EAT = 0.9 · 120 + 0.1 · 220 = 108 + 22 = 130 ns.
- Interpretación: sin TLB cada acceso costaría 200 ns (PTE + dato). La TLB ahorra un 35 %.
Cómo leerlo: es el peldaño 1 dibujado a escala. Cada barra suma lo que se paga, y un fallo de TLB agrega una lectura de la PTE (la parte del medio). El EAT es un promedio ponderado: queda mucho más cerca de la barra de acierto (130 ns) porque el acierto ocurre el 90 % de las veces.
Peldaño 2 · Complétalofaltan pasos clave: llénalos tú
Complétalo: 2 niveles, TLB de 10 ns, memoria de 100 ns y h = 0.95
El acierto cuesta 10 + 100 = 110 ns. Completa: ¿cuánto cuesta un fallo de TLB con dos niveles?, ¿y el EAT?
Comparar
Fallo: 10 + 2 · 100 + 100 = 310 ns, porque hay que leer dos PTE (directorio y tabla) antes del dato. EAT = 0.95 · 110 + 0.05 · 310 = 104.5 + 15.5 = 120 ns.
Peldaño 3 · Solosin ayuda; luego compara
Solo: 3 niveles, TLB de 5 ns, memoria de 80 ns y h = 0.98
Comparar
Acierto: 5 + 80 = 85 ns. Fallo: 5 + 3 · 80 + 80 = 325 ns. EAT = 0.98 · 85 + 0.02 · 325 = 83.3 + 6.5 = 89.8 ns. Aunque hay 3 niveles, el EAT queda cerca del acierto porque h es alto.
Peldaño 4 · Variantecambia una condición: ¿sigue valiendo lo anterior?
Variante: el mismo sistema del peldaño 1, pero con page faults
Supón que uno de cada millón de accesos (p = 10⁻⁶) produce un page fault que cuesta 8 ms en total. ¿Cuánto sube el EAT? ¿Qué p máxima permite que el EAT suba menos de un 10 %?
Comparar
- EAT ≈ (1 − p) · 130 ns + p · 8 000 000 ns ≈ 130 + 8 = 138 ns. Un solo fallo por millón de accesos encarece todo un 6 %.
- Para subir menos de un 10 % (EAT < 143 ns), se necesita p · 8 000 000 < 13, es decir, p < 1.6 · 10⁻⁶.
- Lección: el disco domina todo. Por eso importan tanto la localidad y una buena política de reemplazo, mucho más que unos nanosegundos de TLB.
Tamaño de página: un compromiso
Sección titulada «Tamaño de página: un compromiso»| Página más pequeña | Página más grande |
|---|---|
| ✅ menos fragmentación interna | ✅ la tabla es más chica (menos entradas) |
| ✅ más páginas en RAM: se aprovecha mejor la localidad | ✅ transferir un bloque grande del disco es más eficiente |
| ❌ tablas más grandes, que pueden caer en disco | ❌ más fragmentación interna; con páginas muy grandes, la página trae mucho que no se usa |
La curva de fallos según el tamaño de página no es monótona (Stallings fig. 8.11):
- Con páginas muy chicas, caben muchas en RAM y hay pocos fallos.
- Al crecer, cada página trae datos lejanos a lo que se usa y los fallos suben.
- Cuando la página se acerca al tamaño del proceso, los fallos vuelven a bajar.
Cómo leerlo: con una cantidad fija de RAM, al agrandar la página primero suben los fallos (cada página trae datos que no se usan y desplaza a otras). En el extremo P, cuando una página es todo el proceso, vuelven a bajar.
Los tamaños típicos son 4 KB (x86), 8 KB (UltraSPARC) y las páginas grandes (2 MB o 1 GB en x86-64), que se usan para bases de datos y para reducir los fallos de TLB.
Segmentación con memoria virtual, y combinada
Sección titulada «Segmentación con memoria virtual, y combinada»- Segmentación sola: cada entrada de la tabla de segmentos también lleva un bit P y un bit M. Sirve para estructuras que crecen, para compilar módulos por separado, para compartir y para proteger.
- Segmentación + paginación (Stallings §8.1, «Combined Paging and Segmentation»):
- El programador ve segmentos.
- Cada segmento se divide en páginas del tamaño de un frame.
- La dirección es
(segmento, página, offset): la tabla de segmentos apunta a la tabla de páginas de ese segmento, y esa tabla da el frame. - Se ganan las ventajas de ambos: segmentos lógicos protegibles y compartibles, y sin fragmentación externa.
- Lo usaba x86 en modo protegido. Linux de 64 bits deja la segmentación casi apagada (ver Segmentación § procesadores modernos).
Cómo leerlo: la dirección tiene tres partes. El segmento elige una fila de la tabla de segmentos, pero esa fila ya no da una base: da dónde está la tabla de páginas de ese segmento. La página elige el marco en esa tabla y el offset se copia, como en la paginación normal.
Paginación por demanda y el page fault paso a paso
Sección titulada «Paginación por demanda y el page fault paso a paso»Paginación por demanda (demand paging): una página se trae a RAM solo cuando se referencia por primera vez. El proceso arranca con casi nada cargado y acumula fallos al inicio; después la localidad los vuelve raros.
Qué hace el SO en un page fault (clase 09, diap. 76):
- Trap. La referencia encuentra P = 0 y el hardware genera una interrupción hacia el SO. El proceso queda bloqueado.
- ¿Es válida? El SO mira otra tabla (la del espacio de direcciones del proceso). Si la dirección es inválida, aborta el proceso (segmentation fault). Si es válida pero la página no está en memoria, sigue.
- Busca un frame libre. Si no hay ninguno, la política de reemplazo elige una víctima. Si la víctima tiene M = 1, primero se escribe al disco.
- Lee la página del disco al frame. Es una operación de E/S que tarda milisegundos, así que mientras tanto el SO ejecuta otro proceso.
- Actualiza la tabla: P = 1 y el número de frame.
- Reinicia la instrucción que falló. El proceso vuelve a Listo; cuando se ejecuta, la referencia ahora sí encuentra la página.
Cómo leerlo: sigue los números. ① El proceso referencia M. ② La tabla dice P = 0 y el hardware hace trap al SO. ③ El SO comprueba que M sea válida y la busca en el disco. ④ El disco la copia a un frame libre (si no hay, antes se elige una víctima). ⑤ El SO pone P = 1 y el frame en la tabla. ⑥ La instrucción se reinicia y ahora sí encuentra la página.
Medición: la paginación por demanda en acción
Sección titulada «Medición: la paginación por demanda en acción»Basado en la actividad «Paging y TLB» de la guía de Valgrind. El programa reserva PAGESIZE × N bytes, los escribe y luego los lee, contando los fallos con getrusage (es lo mismo que mide perf stat -e page-faults). Página de 4096 B; resultado de la ejecución de prueba:
N= 1 malloc:+3 escribir:+0 leer:+0N= 8 malloc:+3 escribir:+7 leer:+0N= 32 malloc:+3 escribir:+31 leer:+0N= 64 malloc:+3 escribir:+64 leer:+0N= 1024 malloc:+3 escribir:+1024 leer:+0N= 16384 malloc:+3 escribir:+16384 leer:+0Cómo se lee:
mallocno provoca fallos proporcionales a N: reservar memoria virtual no trae páginas a la RAM. Los 3 fallos fijos son de la propia biblioteca.- La primera escritura sobre cada página provoca un fallo por página. Esa es la paginación por demanda: los frames se asignan recién cuando se tocan.
- Leer después no provoca ningún fallo, porque las páginas ya están residentes.
- Con N pequeño sale N − 1: la primera página ya estaba en RAM porque el heap se había inicializado antes. Desde unos 128 KB (N ≥ 32),
mallocusammap(ver memoria de un proceso) y los fallos son exactamente N.
Son los números de la fila N = 1024 de la medición. Reservar no cuesta fallos; tocar cada página por primera vez cuesta uno; volver a tocarla, ninguno.
Pregunta de análisis: ¿por qué la segunda pasada no falla nunca?
Porque después de la primera pasada todas las páginas del arreglo están en el conjunto residente, y la máquina tiene RAM de sobra (no hay presión para reemplazarlas). Si el arreglo fuera más grande que la RAM disponible, la segunda pasada sí fallaría. Con un recorrido secuencial y reemplazo LRU, de hecho fallaría en cada página: es el peor caso de LRU con un patrón cíclico más grande que la memoria.
Autoevaluación
0/7 correctas · 0 respondidas📈 ¿Qué tan bien lo dominas?
Elige pensando en lo que hiciste, no en lo que leíste. Para marcar 3 tienes que haber resuelto un ejercicio nuevo sin pistas y haberlo justificado. Si solo lo leíste y sientes que «ya entendí», todavía es un 1.
Fuente ·Stallings 9e §8.1 (Hardware and Control Structures) · sem_9/Sem9_09-OST-Memory.pdf (diap. 9–14, 48–76) · sem_9/10-OSL-Valgrind.pdf («Paging y TLB») · Prueba propia: pagefaults.c (getrusage, ejecución de prueba)