σμ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.5·~1 سمتقدم

المخصصات وأحواض الذاكرة

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

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

  1. 01من أين تأتي العناوين؟
  2. 02الكائنات المؤقتة تبعثر عقدك
  3. 03ما ستبنيه

كل عقدة قائمة أو عقدة شجرة أو أمر ينشئه برنامج يأتي من مخصص والمخصص هو من يقرر عناوينها. يبعثر malloc العام الغرض الكائنات الصغيرة برؤوس وبالكائنات المؤقتة التي ينشئها البرنامج نفسه؛ أما الحوض فيرصّها. يضع هذا الدرس نموذجًا للاثنين ويعبر القائمة نفسها بإخفاقات ذاكرة مخبئية أقل بـ3.3 مرة من حوض.

01

من أين تأتي العناوين؟

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

main.pyPython
def round_up(n, align):    return -(-n // align) * aligndef malloc_addresses(sizes, header=HEADER_BYTES, align=ALIGN):    addresses = []    start = 0    for size in sizes:        addresses.append(start + header)1        start += round_up(size + header, align)    return addressesprint(malloc_addresses([24, 100, 24]))print([round_up(size + 16, 16) for size in (24, 100)])
[16, 64, 192]
[48, 128]
  1. 1الكتلة هي الطلب زائد الرأس مقرّبًا إلى مضاعف 16: 24 بايت تحتاج كتلة من 48 بايت و100 بايت تحتاج 128.

تحصل عقدة من 24 بايت (إغلاق وحجم ومؤشر تالٍ 8 بايت لكل منها) على كتلة من 48 بايت أي ضعف حاجتها ويحصل كائن مؤقت من 100 بايت على 128. العناوين الثلاثة 16 و64 و192: يبدأ الطلب الثاني بعد كتلة الأول ذات 48 بايت ويبدأ الثالث بعد كتلة الثاني ذات 128 بايت.

02

الكائنات المؤقتة تبعثر عقدك

لا تبني الشيفرة الحقيقية قائمة في الفراغ. بين عقدتين تنسّق رسالة أو تبني مفتاحًا أو تحلل سطرًا وهذه الكائنات المؤقتة تُخصَّص أيضًا. ومع مخصص بسيط لا يعيد استعمال الذاكرة أبدًا تجلس بين العقد. تبني الدالة الأولى أدناه خطة الطلبات: عقدة تليها ثلاثة كائنات مؤقتة من 100 بايت وتخدم الثانية الخطة وتحتفظ بعناوين العقد فقط. وللمقارنة نكتب أيضًا حوضًا يوزّع فتحات ثابتة واحدة بعد الأخرى مباشرة.

main.pyPython
def alloc_plan(n_nodes, garbage_per_node, garbage_bytes, node_bytes):    sizes = []    node_index = []    for _ in range(n_nodes):        node_index.append(len(sizes))        sizes.append(node_bytes)        sizes.extend([garbage_bytes] * garbage_per_node)    return sizes, node_indexdef node_addresses(n_nodes, garbage_per_node, garbage_bytes, node_bytes):    sizes, node_index = alloc_plan(n_nodes, garbage_per_node, garbage_bytes, node_bytes)    addresses = malloc_addresses(sizes)    return [addresses[i] for i in node_index]def pool_addresses(n, slot_bytes, base=0):    return [base + i * slot_bytes for i in range(n)]print(node_addresses(3, 3, 100, 24))print(node_addresses(3, 0, 100, 24))print(pool_addresses(3, 24))
[16, 448, 880]
[16, 64, 112]
[0, 24, 48]

مع ثلاثة كائنات مؤقتة لكل عقدة تتباعد العقد 432 بايت: 48 للعقدة و3 × 128 للمهملات. وبلا مؤقتات تتباعد 48 بايت. وفي الحوض تتباعد 24 بايت أي حجم العقدة بالضبط بلا رأس ولا مهملات. يحوي سطر من 64 بايت عقدة واحدة مبعثرة و1.3 عقدة مع الرؤوس فقط و2.7 عقدة في الحوض. نعبر الآن 3000 عقدة نقرأ أول بايت وآخر بايت من كل منها عبر ذاكرة الموضوعات السابقة.

main.pyPython
def traversal_misses(addresses, node_bytes):    cache = Cache()    for address in addresses:        cache.access(address)        cache.access(address + node_bytes - 1)    return cache.missesn = 3000for name, addresses in (("scattered", node_addresses(n, 3, 100, 24)), ("headers only", node_addresses(n, 0, 100, 24)), ("pool", pool_addresses(n, 24))):    print(name, traversal_misses(addresses, 24), "misses, last node at", addresses[-1] // 1024, "KB")
scattered 3750 misses, last node at 1265 KB
headers only 2250 misses, last node at 140 KB
pool 1125 misses, last node at 70 KB

تكلّف القائمة المبعثرة 3750 إخفاقًا وتمتد على 1265 كيلوبايت. أما الحوض الذي يحوي العقد الـ3000 نفسها فيكلّف 1125 إخفاقًا على 70 كيلوبايت: أقل بـ3.3 مرة وقد تتسع العقد حتى في ذاكرة مخبئية من المستوى الثاني. البرنامج والبيانات وترتيب العبور هي نفسها؛ تغيّرت العناوين فقط.

تعريفالحوض والساحة

يوزّع الحوض فتحات متساوية الحجم من قطعة متجاورة واحدة ويستردها في قائمة حرة. أما الساحة فتحرّك مؤشرًا إلى الأمام فقط وتعطي أي حجم بلا رأس وتحرّر كل شيء دفعة واحدة. وكلاهما يُبقي الكائنات المستعملة معًا متجاورة.

القصة نفسها في Python

تحتفظ قائمة Python من 3000 عدد عائم بمؤشرات إلى 3000 كائن عائم منفصل بعثرها المخصص بينما تخزّن مصفوفة NumPy القيم الـ3000 جنبًا إلى جنب. عبور المصفوفة يمسّ بضع مئات من الأسطر وعبور القائمة يمسّ الآلاف. وهذا سبب آخر لسرعة NumPy.

الأحواض تقايض المرونة بالمحلية

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

ما تقوله البيانات الحقيقيةقائمة من 3000 يوم لـ SPY، عقد من 24 بايت، ذاكرة 32 كيلوبايت بـ8 طرق
مبعثرة بالمؤقتات3,750إخفاق على 1265 كيلوبايت
رؤوس malloc فقط2,250إخفاق على 140 كيلوبايت
الحوض1,125إخفاق في 70 كيلوبايت
كسب الحوض3.3×إخفاقات أقل للعبور نفسه
إخفاقات عبور القائمة حسب المخصص
مبعثرة3750
رؤوس فقط2250
حوض1125
03

ما ستبنيه

يتبع المختبر الدرس: التقريب والمخصص العام البسيط والحوض وخطة الطلبات مع المؤقتات وعناوين العقد وعدّ إخفاقات عبور والدراسة على قائمة أيام SPY.

  • الدالة · السؤالتعتمد على
  • round_up(n, align)كم يساوي n مقرّبًا إلى مضاعف؟حساب بسيط
  • malloc_addresses(sizes)أين يضع المخصص العام كل كتلة؟round_up
  • pool_addresses(n, slot_bytes)والحوض؟حساب بسيط
  • alloc_plan(...)ما الطلبات التي يجريها البرنامج؟حساب بسيط
  • node_addresses(...)أين ينتهي المطاف بالعقد؟alloc_planmalloc_addresses
  • traversal_misses(addresses, node_bytes)كم إخفاقًا يكلّف عبور؟Cache
  • study(bars)كم يوفّر الحوض في قائمة SPY؟node_addressespool_addressestraversal_misses

أهم الخلاصات

  • المخصص يختار العناوين. تضاعف الرؤوس والتقريب عقدة من 24 بايت إلى 48 بايت وتبعد المؤقتات المخصصة بينها العقد 432 بايت.
  • العقد المبعثرة تكلّف إخفاقات. عبور العقد الـ3000 نفسها أخفق 3750 مرة وهي مبعثرة و1125 مرة من حوض.
  • ارصّ الكائنات الساخنة. تُبقي الأحواض والساحات الكائنات المستعملة معًا متجاورة؛ استعملها للبنى الساخنة القليلة واترك الباقي لـmalloc.
تحقق سريع
عقد من 24 بايت تتتالى في حوض. ما أقل عدد من أسطر 64 بايت تمسّه قراءة 3000 منها؟
اختر إجابة.

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

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

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

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

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

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