σμ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 AcademyRoadmapsSkills
Ctrl K
AO
+1,2 Tsd. Lernende
AnmeldenBeitreten ↗
RoadmapsSkills
AO
+1,2 Tsd. Lernende
Anmelden
  • 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 AcademyRoadmapsSkills
Ctrl K
AO
+1,2 Tsd. Lernende
AnmeldenBeitreten ↗
RoadmapsSkills
AO
+1,2 Tsd. Lernende
Anmelden
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Cache locality-Skill›Modul 3 · Die ganze Maschine›Thema 3.2·~50 Min.Fortgeschritten

TLB und große Seiten

Position in der SkillModul 3 von 3 · Thema 2 von 7
3.2 TLB und große Seiten
—Lab-Punkte— / 100XP gesamt—Serie—

4 Min. Lesezeit3 Codebeispiele

  1. 01Zwei Arten von Adressen
  2. 02Ein Cache für Übersetzungen
  3. 03Datensätze zufällig lesen
  4. 04Was Sie bauen werden

Bevor ein Lesezugriff den Cache erreicht, braucht er eine physische Adresse, und die Übersetzung hat einen eigenen kleinen Cache, den TLB, mit nur etwa 64 Einträgen. Ein Programm, das zwischen mehr Seiten springt, kann bei fast jedem Lesezugriff den TLB verfehlen, selbst wenn seine Daten-Caches gut arbeiten. Diese Lektion baut einen TLB und zeigt, wie eine 2-MB-Seite 250 Seiten zu einer macht.

01

Zwei Arten von Adressen

Die Adressen, die ein Programm benutzt, sind virtuell: Jedes Programm glaubt, eine lange Reihe Speicher ab null zu besitzen. Die Maschine hält den echten Speicher in physischen Adressen und zerlegt beide Welten in Seiten. Eine Tabelle im Speicher, die Seitentabelle, sagt, welche physische Seite jede virtuelle Seite enthält. Jeder Lesezugriff braucht zuerst diese Übersetzung: die Seitennummer der virtuellen Adresse nehmen, nachschlagen und die Byteposition in der Seite behalten. Es ist dieselbe Aufteilung wie bei der Zeile eines Caches, nur mit einem größeren Block.

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. 1Die Seitennummer ist die Adresse geteilt durch die Seitengröße; der Rest ist das Byte in der Seite.
02

Ein Cache für Übersetzungen

Bei jedem Lesezugriff die Seitentabelle im Speicher zu durchlaufen würde die Kosten eines Speicherzugriffs verdoppeln, also hält der Prozessor seine letzten Übersetzungen in einer kleinen, schnellen Tabelle, dem TLB. Ein Lesezugriff, dessen Seite im TLB liegt, ist ein Treffer und kostet fast nichts. Ein Lesezugriff, dessen Seite nicht darin liegt, ist ein TLB-Fehlzugriff und löst einen Seitentabellen-Durchlauf aus, Dutzende Nanosekunden. Ein Daten-TLB der ersten Ebene fasst etwa 64 Einträge. Außer dass er Seiten statt Zeilen hält, arbeitet er wie die Caches zuvor: Die am längsten nicht benutzte geht zuerst.

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

Eine Schleife über 48 oder 64 Seiten verfehlt nur in der ersten Runde. Eine Seite mehr, 65, und der TLB verfehlt bei jedem Lesezugriff der 5 Runden: 325 Fehlzugriffe bei 325. Das ist dieselbe LRU-Klippe wie im Thema Arbeitsmengen, jetzt mit Seiten. Entscheidend ist die Reichweite: wie viel Speicher der TLB auf einmal abdeckt.

TLB reach = entries × page size(1)64 Einträge × 4 KB = 256 KB; mit 2-MB-Seiten reichen dieselben 64 Einträge für 128 MB
03

Datensätze zufällig lesen

Nehmen Sie eine Tabelle mit 2.000 Datensätzen zu je 512 Byte: ein Tag Daten plus Zusatzfelder. Sie belegt 1.000 KB, also 250 Seiten zu 4 KB, fast viermal so viele wie die 64 Seiten, die der TLB halten kann. Die Datensätze der Reihe nach zu lesen ist sanft: Acht Datensätze teilen sich jede Seite, der TLB verfehlt also einmal pro Seite, 250-mal. Sie in zufälliger Reihenfolge zu lesen ist hart: Jeder Lesezugriff kann auf jeder der 250 Seiten landen, und der TLB behält nur 64. Der Code unten misst beides, mit 4-KB- und mit 2-MB-Seiten.

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

In Reihenfolge kosten die 4-KB-Seiten 250 Fehlzugriffe. Gemischt kosten sie 1.541 Fehlzugriffe bei 2.000 Lesezugriffen, 77 % der Zugriffe, sechsmal so viel. Mit 2-MB-Seiten passen alle 1.000 KB in eine einzige Seite: ein Fehlzugriff, gleich welche Reihenfolge. Bei 30 ns pro Durchlauf verbringt das gemischte Lesen allein 46 Mikrosekunden mit Übersetzungen, genug für 100.000 Additionen.

Große Seiten in der Praxis

Unter Linux lassen sich große Seiten über Transparent Huge Pages oder explizite hugetlbfs-Seiten anfordern, und Trading-Systeme legen ihre großen Tabellen oft dort ab. Der Gewinn zeigt sich bei großen Tabellen, die in unregelmäßiger Reihenfolge gelesen werden, nicht bei kleinen oder bei Durchläufen in Reihenfolge.

Große Seiten sind nicht gratis

Eine große Seite braucht 2 MB zusammenhängenden physischen Speicher, der auf einer Maschine, die seit Wochen läuft, schwer zu finden sein kann, und eine Tabelle, die kleiner als eine Seite ist, belegt trotzdem die ganze Seite. Reservieren Sie sie früh, beim Start, für die wenigen Tabellen, die sie brauchen.

Was die echten Daten sagen2.000 SPY-Datensätze zu 512 Byte (1.000 KB, 250 Seiten), TLB mit 64 Einträgen
In Tagesreihenfolge: 4-KB-Seiten250TLB-Fehlzugriffe, 7.500 ns Durchläufe
In Tagesreihenfolge: 2-MB-Seiten1eine Seite enthält die ganze Tabelle
Nach steigendem Volumen: 4-KB-Seiten78439 % der Lesezugriffe verfehlen den TLB
Nach steigendem Volumen: durch große Seiten gespart23,490ns783 Durchläufe vermieden
TLB-Fehlzugriffe nach Leseordnung und Seitengröße
Tage, 4 KB250
Volumen, 4 KB784
Beliebige Reihenfolge, 2 MB1
04

Was Sie bauen werden

Das Labor folgt der Lektion: die Seite einer Adresse, der TLB mit LRU-Ersetzung, die Zählung der Fehlzugriffe, die von einer Spur berührten Seiten, die Adressen von Datensätzen in einer Reihenfolge, der Vergleich der Seitengrößen und die Studie an den SPY-Datensätzen.

  • Funktion · FrageBaut auf
  • page_of(address, page_bytes)Welche Seite enthält diese Adresse?Die ganzzahlige Division
  • TLB(entries).access(address, page_bytes)Ist diese Übersetzung ein TLB-Treffer?page_of
  • tlb_misses(trace, entries, page_bytes)Wie viele TLB-Fehlzugriffe kostet eine Spur?TLB
  • pages_touched(trace, page_bytes)Wie viele verschiedene Seiten berührt eine Spur?page_of
  • record_trace(order, record_bytes)Welche Adressen berührt das Lesen der Datensätze in dieser Reihenfolge?Einfache Arithmetik
  • compare_pages(trace, entries)Wie viel helfen große Seiten?tlb_misses
  • study(bars)Was sparen große Seiten bei den SPY-Datensätzen?compare_pagespages_touchedrecord_trace

Das Wichtigste

  • Auch die Übersetzung hat einen Cache. Jeder Lesezugriff braucht die Übersetzung seiner Seite; der TLB hält etwa 64 aktuelle Übersetzungen, und ein Fehlzugriff löst einen langsamen Seitentabellen-Durchlauf aus.
  • Die Reichweite ist Einträge × Seitengröße. 64 Einträge zu 4 KB reichen für 256 KB; eine in zufälliger Reihenfolge gelesene Tabelle von 1.000 KB verfehlt bei den meisten Lesezugriffen.
  • Große Seiten dehnen die Reichweite. 2-MB-Seiten decken mit denselben 64 Einträgen 128 MB ab; die Tabelle passte in eine Seite, und die Fehlzugriffe sanken von 784 auf 1.
Schnelltest
Ein TLB hat 64 Einträge und die Seiten sind 2 MB groß. Wie viel Speicher deckt er auf einmal ab?
Wähle eine Antwort.

Nächstes Thema: Bisher gab es ein Programm und einen Kern. In False Sharing und Padding schreiben zwei Kerne in zwei verschiedene Variablen, die in derselben Cache-Zeile liegen, und die Zeile wandert zwischen ihnen hin und her. Sie zählen die Invalidierungen und beheben sie durch Padding.

Lab: Was bewertet wird

7 Aufgaben · 100 Pkt.
  • Die Seite einer Adresse10 Pkt.
  • Ein TLB mit LRU25 Pkt.
  • Die TLB-Fehlzugriffe einer Spur10 Pkt.
  • Berührte Seiten10 Pkt.
  • Datensätze in einer Reihenfolge lesen10 Pkt.
  • 4-KB- gegen 2-MB-Seiten15 Pkt.
  • Die Studie mit der SPY-Tabelle20 Pkt.
Explorer · lab-cl-8
▾ lab-cl-8
▾ data
…
bash · im Browser
learner@quantcraft:~/lab-cl-8$
Python noch nicht geladenPythonLn 1, Col 1Spaces: 4UTF-8

Dieses Thema zurücksetzen?

Alles in lab-cl-8 wird auf die Startdateien zurückgesetzt und das Terminal geleert. Ihre aktuelle Lösung geht verloren – das lässt sich nicht rückgängig machen.

Wird zurückgesetzt
  • main.py → Startcode
  • Terminal-Verlauf und Testausgabe
  • Nicht eingereichte Änderungen
Bleibt erhalten
  • Beste Lab-Punktzahl
  • Ihre XP und Ihre Serie
  • Vorlesungsfortschritt und Notizen