σμ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 Academyخرائط الطريقالمسارات
Ctrl K
AO
+1.2k متعلّم
تسجيل الدخولانضم ↗
خرائط الطريقالمسارات
AO
+1.2k متعلّم
تسجيل الدخول
  • 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 Academyخرائط الطريقالمسارات
Ctrl K
AO
+1.2k متعلّم
تسجيل الدخولانضم ↗
خرائط الطريقالمسارات
AO
+1.2k متعلّم
تسجيل الدخول
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
مسار Cache locality›الوحدة 3 · الجهاز بصورة أوسع›الموضوع 3.2·~50 دمتقدم

TLB والصفحات الكبيرة

الموضع في المسارالوحدة 3 من 3 · الموضوع 2 من 7
3.2 TLB والصفحات الكبيرة
—درجة المختبر— / 100إجمالي XP—التتابع—

4 دقيقة قراءة3 أمثلة برمجية

  1. 01نوعان من العناوين
  2. 02ذاكرة مخبئية للترجمات
  3. 03قراءة سجلات عشوائيًا
  4. 04ما ستبنيه

قبل أن تصل قراءة إلى الذاكرة المخبئية تحتاج إلى عنوان فعلي وللترجمة ذاكرة مخبئية صغيرة خاصة بها هي TLB فيها نحو 64 مدخلًا فقط. قد يخفق في TLB في كل قراءة تقريبًا برنامج يقفز بين صفحات أكثر من ذلك حتى لو كانت ذاكرات بياناته المخبئية جيدة. يبني هذا الدرس TLB ويبيّن كيف تحوّل صفحة 2 ميغابايت 250 صفحة إلى صفحة واحدة.

01

نوعان من العناوين

العناوين التي يستعملها البرنامج افتراضية: يظن كل برنامج أنه يملك صفًّا طويلًا من الذاكرة يبدأ من الصفر. وتحتفظ الآلة بالذاكرة الحقيقية بعناوين فعلية وتقطّع العالمين إلى صفحات. جدول في الذاكرة هو جدول الصفحات يقول أي صفحة فعلية تحوي كل صفحة افتراضية. تحتاج كل قراءة أولًا إلى هذه الترجمة: خذ رقم الصفحة من العنوان الافتراضي وابحث عنه واحتفظ بموضع البايت داخل الصفحة. إنه التقسيم نفسه لسطر الذاكرة المخبئية بكتلة أكبر.

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. 1رقم الصفحة هو العنوان مقسومًا على حجم الصفحة والباقي هو البايت داخل الصفحة.
02

ذاكرة مخبئية للترجمات

قد يضاعف تصفّح جدول الصفحات في الذاكرة عند كل قراءة كلفة الوصول إلى الذاكرة، لذا يحتفظ المعالج بآخر ترجماته في جدول صغير سريع اسمه TLB. قراءة صفحتها في TLB هي إصابة ولا تكلّف شيئًا تقريبًا. وقراءة لا توجد صفحتها فيه هي إخفاق TLB ويطلق تصفّحًا لجدول الصفحات يستغرق عشرات النانوثوانٍ. يحوي TLB للبيانات من المستوى الأول نحو 64 مدخلًا. وعدا أنه يحفظ صفحات بدل أسطر يعمل مثل الذاكرات المخبئية السابقة: يخرج أولًا الأقل استعمالًا مؤخرًا.

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

حلقة على 48 أو 64 صفحة لا تخفق إلا في الجولة الأولى. صفحة واحدة زائدة أي 65 فيخفق TLB في كل قراءة من الجولات الخمس: 325 إخفاقًا من 325. هذه هي الهاوية نفسها لسياسة LRU في موضوع مجموعات العمل لكن بالصفحات. المهم هو المدى: كم ذاكرة يغطي TLB دفعة واحدة.

TLB reach = entries × page size(1)64 مدخلًا × 4 كيلوبايت = 256 كيلوبايت؛ وبصفحات 2 ميغابايت تبلغ المداخل الـ64 نفسها 128 ميغابايت
03

قراءة سجلات عشوائيًا

خذ جدولًا من 2000 سجل حجم كل منها 512 بايت: بيانات يوم مع حقول إضافية. يشغل 1000 كيلوبايت أي 250 صفحة من 4 كيلوبايت وهو نحو أربعة أضعاف الصفحات الـ64 التي يتسع لها TLB. قراءة السجلات بالترتيب لطيفة: يتشارك ثمانية سجلات كل صفحة فيخفق TLB مرة لكل صفحة أي 250 مرة. وقراءتها بترتيب عشوائي صعبة: كل قراءة قد تقع على أي من 250 صفحة ويحتفظ TLB بـ64 منها فقط. يقيس الكود أدناه الحالتين بصفحات 4 كيلوبايت وبصفحات 2 ميغابايت.

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

بالترتيب تكلّف الصفحات 4 كيلوبايت 250 إخفاقًا. وعند خلطها تكلّف 1541 إخفاقًا من 2000 قراءة أي 77% من القراءات وبستة أضعاف. وبصفحات 2 ميغابايت تتسع الـ1000 كيلوبايت كلها في صفحة واحدة: إخفاق واحد مهما كان الترتيب. بكلفة 30 ns للتصفح تقضي القراءة المخلوطة 46 ميكروثانية في الترجمات وحدها وهو ما يكفي لـ100000 عملية جمع.

الصفحات الكبيرة عمليًا

في Linux يمكنك طلب صفحات كبيرة بالصفحات الكبيرة الشفافة أو بصفحات hugetlbfs الصريحة وكثيرًا ما تثبّت أنظمة التداول جداولها الكبيرة فيها. يظهر الكسب في الجداول الكبيرة المقروءة بترتيب غير منتظم لا في الصغيرة ولا في المسوح بالترتيب.

الصفحات الكبيرة ليست مجانية

تحتاج الصفحة الكبيرة إلى 2 ميغابايت من الذاكرة الفعلية المتجاورة وقد يصعب إيجادها على جهاز يعمل منذ أسابيع، والجدول الأصغر من صفحة يشغل الصفحة كلها مع ذلك. خصّصها مبكرًا عند بدء التشغيل للجداول القليلة التي تحتاجها.

ما تقوله البيانات الحقيقية2000 سجل لـ SPY بحجم 512 بايت (1000 كيلوبايت، 250 صفحة)، TLB من 64 مدخلًا
بترتيب الأيام: صفحات 4 كيلوبايت250إخفاقات TLB و7500 ns من التصفح
بترتيب الأيام: صفحات 2 ميغابايت1صفحة واحدة تحوي الجدول كله
بحجم متصاعد: صفحات 4 كيلوبايت78439% من القراءات تخفق في TLB
بحجم متصاعد: ما توفره الصفحات الكبيرة23,490nsتجنّب 783 تصفحًا
إخفاقات TLB حسب ترتيب القراءة وحجم الصفحة
الأيام، 4 كيلوبايت250
الحجم، 4 كيلوبايت784
أي ترتيب، 2 ميغابايت1
04

ما ستبنيه

يتبع المختبر الدرس: صفحة العنوان وTLB باستبدال LRU وعدّ الإخفاقات والصفحات التي يمسّها تتبّع وعناوين السجلات بترتيب ما ومقارنة أحجام الصفحات والدراسة على سجلات SPY.

  • الدالة · السؤالتعتمد على
  • page_of(address, page_bytes)أي صفحة تحوي هذا العنوان؟القسمة الصحيحة
  • TLB(entries).access(address, page_bytes)هل هذه الترجمة إصابة TLB؟page_of
  • tlb_misses(trace, entries, page_bytes)كم إخفاق TLB يكلّف تتبّع؟TLB
  • pages_touched(trace, page_bytes)كم صفحة مختلفة يمسّ تتبّع؟page_of
  • record_trace(order, record_bytes)ما العناوين التي تمسّها قراءة السجلات بهذا الترتيب؟حساب بسيط
  • compare_pages(trace, entries)كم تفيد الصفحات الكبيرة؟tlb_misses
  • study(bars)ماذا توفّر الصفحات الكبيرة في سجلات SPY؟compare_pagespages_touchedrecord_trace

أهم الخلاصات

  • للترجمة ذاكرة مخبئية أيضًا. تحتاج كل قراءة إلى ترجمة صفحتها؛ ويحتفظ TLB بنحو 64 ترجمة حديثة والإخفاق يطلق تصفحًا بطيئًا لجدول الصفحات.
  • المدى هو المداخل × حجم الصفحة. 64 مدخلًا بحجم 4 كيلوبايت تبلغ 256 كيلوبايت؛ وجدول من 1000 كيلوبايت يُقرأ بترتيب عشوائي يخفق في معظم القراءات.
  • الصفحات الكبيرة توسّع المدى. تغطي صفحات 2 ميغابايت 128 ميغابايت بالمداخل الـ64 نفسها؛ اتسع الجدول في صفحة واحدة وهبطت الإخفاقات من 784 إلى 1.
تحقق سريع
TLB فيه 64 مدخلًا والصفحات 2 ميغابايت. كم ذاكرة يغطي دفعة واحدة؟
اختر إجابة.

الموضوع التالي: كان حتى الآن برنامج واحد ونواة واحدة. في المشاركة الزائفة والحشو تكتب نواتان في متغيرين مختلفين يقعان في سطر الذاكرة المخبئية نفسه فيتنقل السطر ذهابًا وإيابًا بينهما. تعدّ عمليات الإبطال وتصلحها بالحشو.

المختبر: ما الذي يُقيَّم

7 مهام · 100 نقطة
  • صفحة عنوان10 نقطة
  • TLB بسياسة LRU25 نقطة
  • إخفاقات TLB لتتبّع10 نقطة
  • الصفحات الممسوسة10 نقطة
  • قراءة سجلات بترتيب10 نقطة
  • صفحات 4 كيلوبايت مقابل 2 ميغابايت15 نقطة
  • الدراسة على جدول SPY20 نقطة
المستكشف · lab-cl-8
▾ lab-cl-8
▾ data
…
bash · داخل المتصفح
learner@quantcraft:~/lab-cl-8$
لم يتم تحميل Python بعدPythonLn 1, Col 1Spaces: 4UTF-8

هل تريد إعادة ضبط هذا الموضوع؟

سيعود كل ما في lab-cl-8 إلى الملفات الابتدائية وستُمسح الطرفية. ستفقد حلّك الحالي ولا يمكن التراجع عن ذلك.

سيُعاد ضبطه
  • main.py ← الشيفرة الابتدائية
  • سجل الطرفية ومخرجات الاختبارات
  • التغييرات غير المُرسلة
سيُحتفظ به
  • أفضل درجة في المختبر
  • نقاط XP والتتابع
  • تقدّم المحاضرة والملاحظات