اذهب إلى المحتوى

نظرة عميقة على تسلسل الذواكر الهرمي والذاكرة المخبئية في معمارية الحاسوب


Ola Abbas

يمكن لوحدة المعالجة المركزية جلب التعليمات والبيانات مباشرةً من الذاكرة المخبئية Cache Memory الموجودة على شريحة المعالج فقط، لذا يجب تحميل الذاكرة المخبئية من ذاكرة النظام الرئيسية، أي ذاكرة الوصول العشوائي Random Access Memory -أو RAM اختصارًا-، ولكن تحتفظ الذاكرة RAM بمحتوياتها فقط عند الوصل بمصدر طاقة، لذلك يجب تخزينها على مساحة تخزين دائمة وغير متطايرة.

تسلسل الذواكر الهرمي

نطلق على طبقات الذواكر التالية اسم تسلسل الذواكر الهرمي Memory Hierarchy:

السرعة الذاكرة الوصف
الأسرع الذاكرة المخبئية Cache الذاكرة المخبئية هي ذاكرة مضمَّنة في وحدة المعالجة المركزية، وهي ذاكرة سريعة جدًا وتستغرق دورة واحدة فقط للوصول إليها، ولكن هناك حد لحجمها لأنها مُدمَجة مباشرةً في وحدة المعالجة المركزية، كما توجد هناك عدة مستويات فرعية من الذاكرة المخبئية تسمى L1 و L2 و L3 بسرعات متزايدة قليلًا عن بعضها البعض.
  الذاكرة RAM يجب أن تأتي جميع التعليمات وعناوين التخزين الخاصة بالمعالج من الذاكرة RAM، وتستغرق وحدة المعالجة المركزية بعض الوقت للوصول إلى الذاكرة RAM يسمى زمن التأخير Latency بالرغم من أنها ذاكرة سريعة جدًا، كما تُخزَّن الذاكرة RAM في شرائح منفصلة ومخصصة متصلة باللوحة الأم، مما يعني أنها أكبر بكثير من الذاكرة المخبئية.
الأبطأ القرص الصلب Disk جميعنا على دراية بالبرامج التي تصلنا على قرص مرن floppy disk أو قرص مضغوط، ونعلم كيفية حفظ ملفاتنا على القرص الصلب، ونعلم الوقت الطويل الذي يمكن أن يستغرقه البرنامج للتحميل من القرص الصلب، إذ يعني وجود آليات فيزيائية مثل الأقراص الدوارة والرؤوس المتحركة أن الأقراص الصلبة هي أبطأ وسيلة من وسائل التخزين، ولكنها أكبرها حجمًا.

النقطة المهمة التي يجب معرفتها حول تسلسل الذواكر الهرمي هي المقايضات بين السرعة والحجم على حساب بعضهما البعض، فكلما كانت الذاكرة أسرع، كان حجمها أصغر.

سبب فعالية الذواكر المخبئية هو أنّ شيفرة الحاسوب البرمجية تعرض شكلَين من أشكال المحلية Locality هما:

  1. تشير المحلية المكانية Spatial Locality إلى احتمالية الوصول إلى البيانات الموجودة ضمن الكتل مع بعضها بعضًا.
  2. تشير المحلية الزمانية Temporal Locality إلى أن البيانات المستخدَمة مؤخرًا يُحتمَل أن تُستخدَم مرة أخرى قريبًا.

يعني ذلك أنه يمكن الاستفادة من تنفيذ أكبر قدر ممكن من عمليات الوصول السريعة إلى الذاكرة أي المحلية الزمانية وتخزين كتل صغيرة من المعلومات ذات الصلة أي المحلية المكانية.

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

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

تجد الشركات المصنعة مزيدًا من الطرق لحشر مزيد من الترانزستورات على الشريحة، مما يؤدي إلى زيادة أحجام الذواكر المخبئية بصورة كبيرة، ولكن يُقدَّر حجم حتى أكبر الذواكر المخبئية بعشرات الميجابايتات بعكس حجم الذاكرة الرئيسية المقدَّر بالجيجابايتات أو حجم القرص الصلب المقدَّر بالتيرابايتات.

تتكون الذاكرة المخبئية من قطع صغيرة تعكس محتوى أجزاء من الذاكرة الرئيسية، إذ يُطلَق على حجم هذه القطع بحجم الخط Line Size، ويساوي تقريبًا 32 أو 64 بايتًا، ومن الشائع التحدث عن حجم الخط أو خط الذاكرة المخبئية عند الحديث عن الذاكرة المخبئية، والذي يشير إلى قطعة واحدة تعكس محتوى قطعة من الذاكرة الرئيسية، كما يمكن للذاكرة المخبئية فقط تحميل وتخزين الذاكرة بأحجام مضاعفة من خط الذاكرة المخبئية.

تحتوي الذواكر المخبئية على تسلسلها الهرمي الخاص، ويطلق عليه عادةً L1 و L2 و L3، إذ تُعَدّ الذاكرة المخبئية L1 هي الأسرع والأصغر و L2 أكبر وأبطأ منها و L3 هي الأكبر والأبطأ، كما تُقسَم الذاكرة المخبئية L1 إلى ذواكر مخبئية خاصة بالتعليمات وأخرى بالبيانات، وتُعرف باسم معمارية هارفارد Harvard Architecture بعد أن قدمها حاسوب Harvard Mark-1 القائم على المُرحّلات Relay.

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

01_sets.png

ترابط الذاكرة المخبئية: يمكن أن يجد خط ذاكرة مخبئية معيّن مكانًا صالحًا في أحد الإدخالات المظللة.

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

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

  • الذواكر المخبئية المربوطة مباشرةً Direct mapped Caches التي تسمح لخط الذاكرة المخبئية بالتواجد فقط في إدخال واحد في الذاكرة المخبئية، ويُعَدّ ذلك أبسط تطبيق في العتاد، ولكن -كما هو موضح في الشكل السابق- لا توجد إمكانية لتجنب استخدام الأسماء البديلة لأن العنوانَين المظلَّلين يجب عليهما التشارك في خط الذاكرة المخبئية نفسه.
  • الذواكر المخبئية الترابطية بالكامل Fully Associative Caches التي تسمح بوجود خط الذاكرة المخبئية في أيّ إدخال منها، مما يؤدي إلى تجنّب مشكلة الأسماء البديلة، لأن أيّ إدخال يكون متاحًا للاستخدام، لكن يُعَدّ تطبيق ذلك في العتاد مكلفًا للغاية لأنه يجب البحث عن كل موقع محتمَل في الوقت نفسه لتحديد ما إذا كانت القيمة موجودةً في الذاكرة المخبئية.
  • الذواكر المخبئية التجميعية Set Associative Caches التي تُعَدّ عبارةً عن مزيج من الذواكر المخبئية المربوطة مباشرةً والذواكر المخبئية الترابطية بالكامل، وتسمح بوجود قيمة معينة للذاكرة المخبئية في بعض المجموعات الفرعية من الخطوط الموجودة ضمن هذه الذاكرة المخبئية، كما تُقسَم الذاكرة المخبئية إلى مناطق تسمَّى طرقًا Ways، ويمكن وجود عنوان معيّن في أيّ طريق، وبالتالي ستسمح الذاكرة المخبئية التجميعية المؤلفة من مجموعة من الطرق عددها n لخط الذاكرة المخبئية بالتواجد ضمن مجموعة الإدخالات التي عددها يساوي باقي قسمة مجموعة الكتل الإجمالية ذات الحجم المحدد على n، ويظهِر الشكل السابق عينةً من ذاكرة تجميعية مؤلفة من 8 عناصر و 4 طرق، إذ يكون للعنوانَين أربعة مواقع محتملة، مما يعني أنه يجب البحث عن نصف الذاكرة المخبئية فقط في كل عملية بحث، وكلما زاد عدد الطرق، زادت المواقع الممكنة ونقصت الأسماء البديلة، مما يؤدي إلى أداء أفضل.

يجب أن يتخلص المعالِج من الخط بمجرد امتلاء الذاكرة المخبئية لإفساح المجال لخط جديد، وهناك العديد من الخوارزميات التي يمكن للمعالج من خلالها اختيار الخط الذي سيتخلص منه مثل خوارزمية الأقل استخدامًا مؤخرًا Least Recently Used -أو LRU اختصارًا- والتي تُعَدّ خوارزميةً يجري فيها التخلص من أقدم خط غير مستخدَم لإفساح المجال للخط الجديد.

ليس هناك داع لضمان التوافق مع الذاكرة الرئيسية عندما تكون البيانات للقراءة فقط من الذاكرة المخبئية، لكن يحتاج المعالج لاتخاذ بعض القرارات حول كيفية تحديث الذاكرة الرئيسية الأساسية عندما يبدأ في الكتابة في خطوط الذاكرة المخبئية، إذ ستكتب طريقة التخزين الخاصة بالذاكرة المخبئية التي تُسمَّى Write-through Cache التغييرات مباشرةً في ذاكرة النظام الرئيسية عندما يحدّث المعالج الذاكرة المخبئية، ويُعَدّ ذلك أبطأ لأن عملية الكتابة في الذاكرة الرئيسية أبطأ، في حين تؤخر طريقة التخزين الخاصة بالذاكرة المخبئية التي تُسمَّى Write-back Cache كتابةَ التغييرات على الذاكرة RAM حتى الضرورة القصوى، والميزة الواضحة لذلك هي أنّ الوصول إلى الذاكرة الرئيسية مطلوب عند كتابة إدخالات الذاكرة المخبئية.

يُشار إلى خطوط الذاكرة المخبئية المكتوبة دون وضعها في الذاكرة على أنها متسخة Dirty، فعيبها هو أنه يمكن أن يتطلب الأمر وصولَين إلى الذاكرة أحدهما لكتابة بيانات الذاكرة الرئيسية المتسخة والآخر لتحميل البيانات الجديدة عند التخلص من إدخال معيّن من الذاكرة المخبئية.

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

عنونة الذاكرة المخبئية

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

02_tags.png

وسوم الذاكرة المخبئية Cache Tags: يجب التحقق من الوسوم على التوازي للحفاظ على وقت الاستجابة منخفضًا، إذ يتطلب المزيدُ من بتات الوسوم (أي ارتباطات مجموعات أقل) عتادًا أكثر تعقيدًا لتحقيق ذلك. بينما تعني ارتباطاتُ المجموعات الأكثر وسومًا أقل، ولكن يحتاج المعالج الآن إلى عتاد لمضاعفة خرج العديد من المجموعات التي يمكن أن تضيف زمن تأخير أيضًا.

يمكن تحديد ما إذا كان العنوان موجودًا في الذاكرة المخبئية بسرعة من خلال فصله إلى ثلاثة أجزاء هي الوسم Tag والفهرس Index والإزاحة Offset.

تعتمد بتات الإزاحة على حجم خط الذاكرة المخبئية، إذ يمكن استخدام خط بحجم 32 بايت مثلًا آخر 5 بتات أي 2‎5‎ من العنوان بوصفه إزاحةً في الخط، ويُعَدّ الفهرس خط ذاكرة مخبئية معيّن يمكن أن يتواجد فيه الإدخال، فلنفترض أنه لدينا ذاكرة مخبئية تحتوي على 256 إدخالًا مثلًا، فإذا كانت هذه الذاكرة هي ذاكرة مخبئية مربوطة مباشرةً، فيمكن أن تكون البيانات موجودة في خط واحد محتمَل فقط، لذا تصف 8 بتات التالية (2‎8‎) بعد الإزاحة الخط المراد التحقق منه بين 0 و 255.

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

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

إذا كان هناك طرق متعددة، فيجب إجراء هذا التحقق على التوازي في كل طريق، ثم تُمرَر النتيجة بعد ذلك إلى معدد إرسال Multiplexor ينتج عنه نتيجة وصول صحيحة hit أو خاطئة miss، وكلما كانت الذاكرة المخبئية أكثر ارتباطًا، قل عدد البتات المطلوبة للفهرس وزاد عدد البتات المطلوبة للوسم، حتى الوصول إلى أقصى حد للذاكرة المخبئية الترابطية بالكامل حيث لا تُستخدَم بتات كبتات للفهرس، كما تُعَدّ المطابقة على التوازي لبتات الوسوم مكونًا باهظًا لتصميم الذاكرة المخبئية وهي عمومًا العامل المحدّد لعدد الخطوط -أي حجمها- التي يمكن أن تنمو إليها الذاكرة المخبئية.

ترجمة -وبتصرُّف- للقسم Memory من الفصل Computer Architecture من كتاب Computer Science from the Bottom Up لصاحبه Ian Wienand.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...