σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyHojas de rutaRutas
Ctrl K
AO
+1,2 k estudiantes
Iniciar sesiónUnirse ↗
Hojas de rutaRutas
AO
+1,2 k estudiantes
Iniciar sesión
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyHojas de rutaRutas
Ctrl K
AO
+1,2 k estudiantes
Iniciar sesiónUnirse ↗
Hojas de rutaRutas
AO
+1,2 k estudiantes
Iniciar sesión
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Ruta de Cache locality›Módulo 3 · La máquina en conjunto›Tema 3.2·~50 minAvanzado

TLB y páginas grandes

Posición en la rutaMódulo 3 de 3 · Tema 2 de 7
3.2 TLB y páginas grandes
—Puntuación del lab— / 100XP total—Racha—

5 min de lectura3 ejemplos de código

  1. 01Dos clases de direcciones
  2. 02Una caché de traducciones
  3. 03Leer registros al azar
  4. 04Lo que va a construir

Antes de que una lectura llegue a la caché necesita una dirección física, y la traducción tiene su propia caché pequeña, el TLB, con solo unas 64 entradas. Un programa que salta entre más páginas que esas puede fallar en el TLB en casi cada lectura, aunque sus cachés de datos vayan bien. Esta lección construye un TLB y muestra cómo una página de 2 MB convierte 250 páginas en una.

01

Dos clases de direcciones

Las direcciones que usa un programa son virtuales: cada programa cree poseer una larga fila de memoria que empieza en cero. La máquina guarda la memoria real en direcciones físicas y corta ambos mundos en páginas. Una tabla en memoria, la tabla de páginas, dice qué página física contiene cada página virtual. Toda lectura necesita primero esta traducción: tomar el número de página de la dirección virtual, buscarlo y conservar la posición del byte dentro de la página. Es la misma división que la línea de una caché, con un bloque mayor.

main.pyPython
page_bytes = 4096for address in (0, 4095, 4096, 123456789):    print(address, "-> page", address // page_bytes, "byte", address % page_bytes)1
0 -> page 0 byte 0
4095 -> page 0 byte 4095
4096 -> page 1 byte 0
123456789 -> page 30140 byte 3349
  1. 1El número de página es la dirección dividida por el tamaño de página; el resto es el byte dentro de la página.
02

Una caché de traducciones

Recorrer la tabla de páginas en memoria en cada lectura duplicaría el coste de un acceso a memoria, así que el procesador guarda sus últimas traducciones en una tabla pequeña y rápida llamada TLB. Una lectura cuya página está en el TLB es un acierto y casi no cuesta nada. Una lectura cuya página no está es un fallo de TLB y dispara un recorrido de la tabla de páginas, decenas de nanosegundos. Un TLB de datos de primer nivel guarda unas 64 entradas. Salvo por guardar páginas en lugar de líneas, funciona como las cachés anteriores: sale primero la menos recientemente usada.

main.pyPython
class TLB:    def __init__(self, entries):        self.entries = entries        self.pages = []        self.hits = 0        self.misses = 0    def access(self, address, page_bytes):        page = address // page_bytes        if page in self.pages:            self.pages.remove(page)            self.pages.append(page)            self.hits += 1            return True        self.misses += 1        self.pages.append(page)        if len(self.pages) > self.entries:            self.pages.pop(0)        return Falsedef tlb_misses(trace, entries, page_bytes):    tlb = TLB(entries)    for address in trace:        tlb.access(address, page_bytes)    return tlb.missesfor n_pages in (48, 64, 65, 80):    trace = [page * 4096 for page in range(n_pages)] * 5    print(n_pages, "pages, 5 rounds:", tlb_misses(trace, 64, 4096), "misses")
48 pages, 5 rounds: 48 misses
64 pages, 5 rounds: 64 misses
65 pages, 5 rounds: 325 misses
80 pages, 5 rounds: 400 misses

Un bucle sobre 48 o 64 páginas solo falla en la primera ronda. Una página más, 65, y el TLB falla en cada lectura de las 5 rondas: 325 fallos de 325. Es el mismo precipicio LRU del tema de los conjuntos de trabajo, ahora con páginas. Lo que importa es el alcance: cuánta memoria cubre el TLB a la vez.

TLB reach = entries × page size(1)64 entradas × 4 KB = 256 KB; con páginas de 2 MB las mismas 64 entradas alcanzan 128 MB
03

Leer registros al azar

Tome una tabla de 2000 registros de 512 bytes cada uno: un día de datos más campos extra. Ocupa 1000 KB, es decir 250 páginas de 4 KB, casi cuatro veces las 64 páginas que cabe en el TLB. Leer los registros en orden es suave: ocho registros comparten cada página, así que el TLB falla una vez por página, 250 veces. Leerlos en orden aleatorio es duro: cada lectura puede caer en cualquiera de las 250 páginas y el TLB conserva solo 64. El código siguiente mide ambos, con páginas de 4 KB y de 2 MB.

main.pyPython
import randomorder = list(range(2000))shuffled = random.Random(7).sample(order, len(order))for name, records in (("in order", order), ("shuffled", shuffled)):    trace = [record * 512 for record in records]    print(name, "4 KB pages:", tlb_misses(trace, 64, 4096), "- 2 MB pages:", tlb_misses(trace, 64, 2 * 1024 * 1024))
in order 4 KB pages: 250 - 2 MB pages: 1
shuffled 4 KB pages: 1541 - 2 MB pages: 1

En orden, las páginas de 4 KB cuestan 250 fallos. Mezcladas, cuestan 1541 fallos de 2000 lecturas, el 77 % de las lecturas, seis veces más. Con páginas de 2 MB los 1000 KB caben en una sola página: un fallo sea cual sea el orden. A 30 ns por recorrido, la lectura mezclada gasta 46 microsegundos solo en traducciones, lo que daría para 100 000 sumas.

Las páginas grandes en la práctica

En Linux se pueden pedir páginas grandes con las páginas grandes transparentes o con páginas hugetlbfs explícitas, y los sistemas de trading suelen fijar en ellas sus tablas grandes. La ganancia se ve en tablas grandes leídas en orden irregular, no en las pequeñas ni en recorridos en orden.

Las páginas grandes no son gratis

Una página grande necesita 2 MB de memoria física contigua, que puede ser difícil de encontrar en una máquina que lleva semanas funcionando, y una tabla menor que una página ocupa igualmente la página entera. Resérvelas pronto, al arrancar, para las pocas tablas que las necesitan.

Qué dicen los datos reales2000 registros de SPY de 512 bytes (1000 KB, 250 páginas), TLB de 64 entradas
En orden de días: páginas de 4 KB250fallos de TLB, 7500 ns de recorridos
En orden de días: páginas de 2 MB1una página contiene toda la tabla
Por volumen creciente: páginas de 4 KB784el 39 % de las lecturas falla en el TLB
Por volumen creciente: ahorrado por páginas grandes23,490ns783 recorridos evitados
Fallos de TLB según el orden de lectura y el tamaño de página
Días, 4 KB250
Volumen, 4 KB784
Cualquier orden, 2 MB1
04

Lo que va a construir

El laboratorio sigue la lección: la página de una dirección, el TLB con reemplazo LRU, el recuento de fallos, las páginas que toca una traza, las direcciones de registros en un orden, la comparación de tamaños de página y el estudio sobre los registros de SPY.

  • Función · preguntaSe apoya en
  • page_of(address, page_bytes)¿Qué página contiene esta dirección?La división entera
  • TLB(entries).access(address, page_bytes)¿Esta traducción es un acierto de TLB?page_of
  • tlb_misses(trace, entries, page_bytes)¿Cuántos fallos de TLB cuesta una traza?TLB
  • pages_touched(trace, page_bytes)¿Cuántas páginas distintas toca una traza?page_of
  • record_trace(order, record_bytes)¿Qué direcciones toca leer los registros en este orden?Aritmética simple
  • compare_pages(trace, entries)¿Cuánto ayudan las páginas grandes?tlb_misses
  • study(bars)¿Qué ahorran las páginas grandes en los registros de SPY?compare_pagespages_touchedrecord_trace

Ideas clave

  • La traducción también tiene una caché. Toda lectura necesita que se traduzca su página; el TLB guarda unas 64 traducciones recientes y un fallo dispara un lento recorrido de la tabla de páginas.
  • El alcance es entradas × tamaño de página. 64 entradas de 4 KB alcanzan 256 KB; una tabla de 1000 KB leída en orden aleatorio falla en la mayoría de las lecturas.
  • Las páginas grandes amplían el alcance. Las páginas de 2 MB cubren 128 MB con las mismas 64 entradas; la tabla cabía en una página y los fallos bajaron de 784 a 1.
Comprobación rápida
Un TLB tiene 64 entradas y las páginas son de 2 MB. ¿Cuánta memoria puede cubrir a la vez?
Elige una respuesta.

Siguiente tema: hasta ahora había un programa y un núcleo. En Falso compartir y relleno dos núcleos escriben en dos variables distintas que están en la misma línea de caché y la línea rebota entre ellos. Cuenta las invalidaciones y las arregla con relleno.

Lab: qué se califica

7 tareas · 100 pts
  • La página de una dirección10 pts
  • Un TLB con LRU25 pts
  • Los fallos de TLB de una traza10 pts
  • Páginas tocadas10 pts
  • Leer registros en un orden10 pts
  • Páginas de 4 KB frente a 2 MB15 pts
  • El estudio con la tabla de SPY20 pts
Explorador · lab-cl-8
▾ lab-cl-8
▾ data
…
bash · en el navegador
learner@quantcraft:~/lab-cl-8$
Python aún no cargadoPythonLn 1, Col 1Spaces: 4UTF-8

¿Restablecer este tema?

Todo lo que hay en lab-cl-8 vuelve a los archivos iniciales y se limpia el terminal. Tu solución actual se perderá: no se puede deshacer.

Se restablecerá
  • main.py → código inicial
  • Historial del terminal y salida de pruebas
  • Cambios sin enviar
Se conservará
  • Mejor puntuación del lab
  • Tu XP y tu racha
  • Progreso de la lección y notas