← Gestión de Memoria Bloque 5 · Paginación · Tema 22 de 52

Tema 22

Tablas multinivel y tablas invertidas

Una tabla de páginas plana para un espacio virtual de 256 TiB tendría miles de millones de entradas y ocuparía gigabytes. La solución es dividir la tabla en niveles, de modo que solo se creen las entradas necesarias. En este tema verás los cuatro niveles de x86-64, cómo se traduce una dirección, y las alternativas (tablas invertidas y con hash) usadas por otras arquitecturas.

1. El problema: una tabla plana no cabe

Con un espacio virtual de 248 bytes (256 TiB) y páginas de 4 KiB, se necesitan 236 entradas (unas 68.000 millones). Cada entrada ocupa 8 bytes, así que la tabla ocuparía 512 GiB — más que la RAM de cualquier equipo.

Además, la mayoría del espacio virtual está sin usar (huecos enormes entre código, heap y pila), por lo que la mayoría de las entradas estarían vacías. Una tabla plana desperdicia memoria masivamente.

2. Tablas multinivel

La solución es dividir la tabla en niveles: una tabla de primer nivel (directorio) cuyas entradas apuntan a tablas de segundo nivel, y así sucesivamente. Solo se crean las tablas de niveles inferiores para las regiones del espacio virtual que se usan.

Esto es como un árbol: la raíz cubre todo el espacio virtual, pero las ramas solo se crean donde hay datos. Un proceso típico usa solo unas pocas decenas de MiB, por lo que solo necesita unas pocas tablas de hoja.

Tabla multinivel es una estructura jerárquica de tablas de páginas, donde cada nivel divide el espacio virtual en bloques más pequeños, y solo se crean las entradas y tablas necesarias.

3. Los cuatro niveles de x86-64

En x86-64 (con páginas de 4 KiB), la dirección virtual de 48 bits se divide en 4 niveles de 9 bits cada uno, más 12 bits de desplazamiento:

NivelNombreBitsEntradas por tabla
4 (raíz)PML4 (Page Map Level 4)9512
3PDPT (Page Directory Pointer Table)9512
2PD (Page Directory)9512
1 (hoja)PT (Page Table)9512
—Desplazamiento12—

Cada tabla ocupa 4096 bytes (512 entradas × 8 bytes). Un proceso típico usa: 1 tabla PML4, 1-2 PDPT, unas pocas PD, y decenas de PT. Total: unas decenas de KiB en lugar de 512 GiB.

Los 16 bits superiores de la dirección virtual (48-63) son de extensión de signo (canonical form): deben ser copia del bit 47.

Traducción multinivel en x86-64: 4 niveles de tabla Dirección virtual PML4 | PDPT | PD | PT | d PML4 PDPT PD PT Marco 9 bits 9 bits 9 bits 9 bits 12 bits
Cada nivel usa 9 bits para indexar una tabla de 512 entradas. Los 12 bits finales son el desplazamiento dentro de la página.

4. Traducción con tablas multinivel

La MMU traduce la dirección en 4 pasos:

  1. PML4: usa los 9 bits más altos (47-39) para indexar el PML4. La entrada da la dirección base de una tabla PDPT.
  2. PDPT: usa los siguientes 9 bits (38-30) para indexar la PDPT. La entrada da la base de una tabla PD.
  3. PD: usa los siguientes 9 bits (29-21). La entrada da la base de una tabla PT (o, si es página grande, el marco directamente).
  4. PT: usa los siguientes 9 bits (20-12). La entrada da el marco físico.
  5. Desplazamiento: los 12 bits bajos (11-0) se concatenan al marco para formar la dirección física.

Cada paso requiere un acceso a memoria (leer la tabla). Con 4 niveles, son 4 accesos antes de acceder a la RAM. La TLB (tema 24) reduce esto a 1 acceso en el caso común.

5. Tablas invertidas

La tabla invertida (inverted page table) tiene una entrada por marco físico, no por página virtual. Cada entrada guarda qué proceso y qué página virtual ocupan ese marco. El número de entradas es el número de marcos (pequeño), pero buscar una página virtual requiere recorrer toda la tabla (o usar un hash).

6. Tablas con hash

Para acelerar la búsqueda en tablas invertidas, se usa una tabla hash: la clave es (proceso, página virtual) y el valor es el índice en la tabla invertida. Esto da búsqueda O(1) en promedio.

7. Ejemplo numérico

Dirección virtual de 48 bits: 0x00007F3A2C001234. Tamaño de página 4 KiB. Descomposición:

CampoBitsValor (hex)
PML4 index47-390x0FF (255)
PDPT index38-300x1D1 (465)
PD index29-210x151 (337)
PT index20-120x000 (0)
Desplazamiento11-00x234

La MMU indexa cada tabla con el índice correspondiente. Si todas las entradas están presentes, el marco final se concatena con el desplazamiento 0x234 para formar la dirección física.

8. Experimento en C

El programa siguiente descompone una dirección virtual de 48 bits en sus 4 niveles:

multinivel.c
#include <stdio.h>
#include <stdint.h>

int main(void)
{
    uint64_t v = 0x00007F3A2C001234ULL;
    uint64_t pml4 = (v >> 39) & 0x1FF;
    uint64_t pdpt = (v >> 30) & 0x1FF;
    uint64_t pd   = (v >> 21) & 0x1FF;
    uint64_t pt   = (v >> 12) & 0x1FF;
    uint64_t off  = v & 0xFFF;

    printf("virtual = 0x%016lX\\n", v);
    printf("PML4    = 0x%03lX (%lu)\\n", pml4, pml4);
    printf("PDPT    = 0x%03lX (%lu)\\n", pdpt, pdpt);
    printf("PD      = 0x%03lX (%lu)\\n", pd, pd);
    printf("PT      = 0x%03lX (%lu)\\n", pt, pt);
    printf("offset  = 0x%03lX\\n", off);
    return 0;
}
terminal · descomposición multinivel
$ gcc -std=c17 -Wall -Wextra -o multinivel multinivel.c
$ ./multinivel
virtual = 0x00007F3A2C001234
PML4    = 0x0FF (255)
PDPT    = 0x1D1 (465)
PD      = 0x151 (337)
PT      = 0x000 (0)
offset  = 0x234offset  = 0x234

9. Probar con un simulador

Este simulador descompone una dirección virtual de 48 bits en sus 4 niveles y muestra los índices.

Simulador · tablas multinivel x86-64

NivelÍndice (hex)Índice (dec)
PML4 (bits 47-39)
PDPT (bits 38-30)
PD (bits 29-21)
PT (bits 20-12)
Desplazamiento (bits 11-0)

10. En Linux

Linux usa tablas multinivel de 4 niveles (5 en sistemas con 5-level paging, para 57 bits de dirección virtual). Las herramientas para inspeccionar:

terminal · tablas de páginas en Linux
$ cat /proc/cpuinfo | grep -i 'address sizes'
address sizes   : 46 bits physical, 48 bits virtual

11. Resumen

12. Preguntas de repaso

Intenta responder cada una antes de abrir la respuesta.

1. ¿Por qué una tabla plana no es viable?

Porque ocuparía más memoria que la RAM disponible (512 GiB para un espacio de 256 TiB).

2. ¿Cuántos niveles tiene x86-64 y cuántos bits usa cada uno?

4 niveles, cada uno con 9 bits (más 12 de desplazamiento = 48 bits).

3. ¿Cuántas entradas tiene cada tabla en x86-64?

512 entradas (2^9), cada una de 8 bytes, ocupando 4096 bytes por tabla.

4. ¿Qué es una tabla invertida?

Una tabla con una entrada por marco físico, que guarda qué proceso y página ocupan ese marco.

5. ¿Qué ventaja tiene la tabla invertida?

Ocupa poco espacio (proporcional a la RAM, no al espacio virtual).

6. ¿Qué desventaja tiene la tabla invertida?

La búsqueda es lenta (O(n)), mitigada con tablas hash.

7. ¿Cuántos accesos a memoria requiere la traducción multinivel?

4 (uno por nivel) más el acceso a la RAM, mitigado por la TLB.

8. ¿Qué es el 5-level paging?

Una extensión de x86-64 que añade un quinto nivel, ampliando el espacio virtual a 57 bits.

Para practicar

  1. Descompón la dirección 0x0000123456789ABC en sus 4 niveles usando el simulador.
  2. Calcula cuántas tablas se necesitan para un proceso que usa 10 MiB con páginas de 4 KiB.
  3. Explica por qué las tablas multinivel ahorran memoria.
  4. Compara las tablas multinivel con las invertidas: ¿qué ventaja tiene cada una?
  5. Investiga cómo funciona el 5-level paging en Linux.
  6. Implementa en C la descomposición de una dirección de 48 bits en 4 niveles.
  7. Dibuja el árbol de tablas para un proceso con 3 páginas en regiones distintas.