Ir al contenido

Memoria virtual: hardware y fallo de página

🎯 Al terminar podrás

  1. Explicar por qué la memoria virtual funciona a pesar de que el disco es miles de veces más lento (localidad).
  2. Decir qué hace cada bit de la PTE (P, M, R) y qué pasa cuando P = 0.
  3. Seguir el orden TLB → tabla → page fault y calcular el EAT con k niveles, con y sin fallos de página.
  4. 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.

Stallings parte de dos características de la paginación y la segmentación:

  1. 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.
  2. 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).

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.

nº depáginatiempo (referencias sucesivas) →zona 1zona 2zona 3el código (pág. 1) se usa siempreIlustrativo (ejemplo propio, no medido): en cada tramo el programa toca 4 o 5 páginas, no todas.

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.

RequisitoPor qué
Soporte de hardware para la paginación o segmentacióntraducir cada dirección en software sería impracticable
Software del SO para mover páginas entre disco y RAMlas políticas de la página siguiente

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:

BitNombrePara qué
Ppresente / válido¿la página está en RAM? Si es 0, el acceso provoca un page fault
Mmodificado (dirty)¿se escribió desde que se cargó? Si sí, hay que escribirla al disco antes de reemplazarla; si no, se descarta sin costo
R / Ureferenciado / uso¿se accedió hace poco? Lo usa el algoritmo Clock y sus variantes
—protección, compartición, bloqueolectura/escritura/ejecución, páginas compartidas, frames bloqueados (frame locking)
PFNnúmero de framedónde está, si P = 1
una entrada de la tabla (PTE)PMRR W X · U/Snúmero de marco (PFN)¿en RAM?¿se escribió?¿se usó?¿qué se permite?¿dónde está?page faultguardar a discoreemplazoprotecciónla traducciónSi P = 0, el resto de la entrada no sirve: hay page fault y el SO toma el control.

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 2222^{22} 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.

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):

  1. La CPU genera la dirección virtual y busca la página en la TLB.
  2. 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.
  3. 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).

CPUpágina | offsetTLB (asociativa)0x12 → 70x2A → 50x03 → 9compara todas a la vezhit: ~10 nsmarco | offsetdirección físicamisstabla de páginasen RAM: +100 ns¿P = 1?síse copia la PTE a la TLBnopage fault → SOE/S de disco, proceso BlockedCon 90 % de hits: 0.9 · 110 + 0.1 · 210 = 120 ns por acceso, casi lo mismo que la RAM sola.

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: EAT=h (tTLB+tm)+(1−h) (tTLB+k tm+tm)\text{EAT} = h\,(t_{TLB} + t_m) + (1-h)\,(t_{TLB} + k\,t_m + t_m)

Sin TLB
200.0 ns
Con TLB (EAT)
103.0 ns
Ideal (solo el dato)
100.0 ns
Acierto TLB101 ns
Fallo TLB (página en RAM)201 ns
Penalización vs ideal+3.0 %
Si la página no está en RAM (bit P = 0), hay un page fault: el SO bloquea al proceso, lee la página de disco (milisegundos, órdenes de magnitud más que todo lo anterior), actualiza la tabla y lo pasa a Listo.

Fórmula del curso, con k niveles de tabla y TLB consultada siempre:

EAT=h (tTLB+tm)+(1−h) (tTLB+k tm+tm)\text{EAT} = h\,(t_{TLB} + t_m) + (1-h)\,(t_{TLB} + k\,t_m + t_m)

Peldaño 1 · Resueltolee cada paso y su porqué

Resuelto: 1 nivel, TLB de 20 ns, memoria de 100 ns y h = 0.9

  1. Acierto (90 %): TLB y luego el dato, 20 + 100 = 120 ns.
  2. Fallo de TLB (10 %): TLB, luego la PTE (1 nivel) y luego el dato, 20 + 100 + 100 = 220 ns.
  3. EAT = 0.9 · 120 + 0.1 · 220 = 108 + 22 = 130 ns.
  4. Interpretación: sin TLB cada acceso costaría 200 ns (PTE + dato). La TLB ahorra un 35 %.
acierto TLB90 %120 nsfallo TLB10 %220 nsEAT = 0.9 · 120 + 0.1 · 220 = 130 nsTLB (20 ns)leer la PTE (100 ns)leer el dato (100 ns)Un page fault de 8 ms, a esta escala, sería unas 36 000 veces más larga que la barra del fallo de TLB.

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.
Página más pequeñaPá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.
tasa defallostamaño de página →Pchicas: muchas en RAM,la localidad ayudamedianas: cada una trae datos lejanosuna página = todo el proceso:casi no hay fallosForma cualitativa de la curva de Stallings: sin datos medidos.

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).
direccións = 2segmentop = 3páginadoffset0 → tabla en 0x1001 → tabla en 0x1802 → tabla en 0x240tabla de segmentos0 → marco 9⋮3 → marco 14tabla de páginas del seg. 2marco 14ddirección físicaLas direcciones 0x100, 0x180, 0x240 y los marcos son un ejemplo propio.

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):

  1. Trap. La referencia encuentra P = 0 y el hardware genera una interrupción hacia el SO. El proceso queda bloqueado.
  2. ¿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.
  3. 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.
  4. 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.
  5. Actualiza la tabla: P = 1 y el número de frame.
  6. Reinicia la instrucción que falló. El proceso vuelve a Listo; cuando se ejecuta, la referencia ahora sí encuentra la página.
sistema operativoprocesoload Mqueda Blockedhasta el paso 6tabla de páginasM · P = 0 → 1discoaquí está la página MRAMocupadoocupadopágina Mocupado1referencia2trap3buscar la página4traer al frame5P = 16reiniciar la instrucciónSi en el paso 2 la dirección resulta inválida, el SO aborta el proceso: segmentation fault.

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:+0
N= 8 malloc:+3 escribir:+7 leer:+0
N= 32 malloc:+3 escribir:+31 leer:+0
N= 64 malloc:+3 escribir:+64 leer:+0
N= 1024 malloc:+3 escribir:+1024 leer:+0
N= 16384 malloc:+3 escribir:+16384 leer:+0

Cómo se lee:

  • malloc no 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), malloc usa mmap (ver memoria de un proceso) y los fallos son exactamente N.
page faults medidos con N = 1024 páginas de 4 KBmalloc+31.ª escritura+1024lectura+0Un fallo por página, recién al tocarla: eso es la paginación por demanda.

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
1. ¿Qué permite ejecutar un proceso sin cargar todas sus páginas?
2. El bit M (dirty) de una página víctima vale 0. Al reemplazarla…
3. Una tabla de páginas invertida tiene una entrada por…
4. En un page fault, ¿qué hace el proceso mientras se lee la página del disco?
5. Thrashing es…
6. ¿Por qué funciona la memoria virtual pese a que el disco es miles de veces más lento?
7. Páginas más grandes implican…

📈 ¿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)