حاجز الذاكرة
في مجال الحوسبة ، يُعرف حاجز الذاكرة ، أو ما يُسمى أيضًا بسياج الذاكرة أو تعليمات السياج ، بأنه نوع من تعليمات الحاجز التي تُجبر وحدة المعالجة المركزية أو المُترجم على فرض قيد ترتيبي على عمليات الذاكرة التي تُنفذ قبل وبعد تعليمة الحاجز. وهذا يعني عادةً أن العمليات التي تُنفذ قبل الحاجز مضمونة التنفيذ قبل العمليات التي تُنفذ بعده.
تُعدّ حواجز الذاكرة ضرورية لأن معظم وحدات المعالجة المركزية الحديثة تستخدم تقنيات تحسين الأداء التي قد تؤدي إلى تنفيذ العمليات خارج الترتيب . عادةً ما يمرّ هذا التغيير في ترتيب عمليات الذاكرة (التحميل والتخزين) دون أن يُلاحظ ضمن سلسلة تنفيذ واحدة ، ولكنه قد يتسبب في سلوك غير متوقع في البرامج المتزامنة وبرامج تشغيل الأجهزة ما لم يتم التحكم فيه بدقة. وتختلف طبيعة قيود الترتيب باختلاف العتاد، ويتم تحديدها من خلال نموذج ترتيب الذاكرة الخاص بالبنية . توفر بعض البنى حواجز متعددة لفرض قيود ترتيب مختلفة.
تُستخدم حواجز الذاكرة عادةً عند تنفيذ تعليمات برمجية منخفضة المستوى تعمل على ذاكرة مشتركة بين أجهزة متعددة. تشمل هذه التعليمات البرمجية أدوات التزامن وهياكل البيانات غير القابلة للقفل على أنظمة المعالجات المتعددة ، وبرامج تشغيل الأجهزة التي تتواصل مع مكونات الحاسوب المادية .
مثال
عند تشغيل برنامج على جهاز بمعالج واحد، يقوم الجهاز بإدارة الذاكرة اللازمة لضمان تنفيذ البرنامج كما لو أن جميع عمليات الذاكرة نُفذت بالترتيب الذي حدده المبرمج (ترتيب البرنامج)، لذا لا حاجة لحواجز الذاكرة. مع ذلك، عند مشاركة الذاكرة مع أجهزة متعددة، مثل معالجات أخرى في نظام متعدد المعالجات، أو أجهزة طرفية مُرتبطة بالذاكرة ، قد يؤثر الوصول غير المتسلسل على سلوك البرنامج. على سبيل المثال، قد يرى معالج ثانٍ تغييرات الذاكرة التي أجراها المعالج الأول بتسلسل يختلف عن ترتيب البرنامج.
يُشغَّل البرنامج عبر عملية يمكن أن تكون متعددة الخيوط (أي خيط برمجي مثل pthreads ، وليس خيطًا ماديًا). لا تتشارك العمليات المختلفة مساحة الذاكرة، لذا لا ينطبق هذا النقاش على برنامجين، كل منهما يعمل في عملية مختلفة (وبالتالي مساحة ذاكرة مختلفة). ينطبق هذا النقاش على خيطين برمجيين أو أكثر تعمل في عملية واحدة (أي مساحة ذاكرة واحدة حيث تتشارك خيوط برمجية متعددة مساحة ذاكرة واحدة). قد تعمل خيوط برمجية متعددة، ضمن عملية واحدة، بشكل متزامن على معالج متعدد النوى .
يُقدّم البرنامج متعدد الخيوط التالي، الذي يعمل على معالج متعدد النوى، مثالاً على كيفية تأثير هذا التنفيذ خارج الترتيب على سلوك البرنامج:
في البداية، تحتوي كل من موقعي الذاكرة x و f على القيمة 0. يقوم خيط البرنامج الذي يعمل على المعالج رقم 1 بالتكرار طالما أن قيمة f تساوي صفرًا، ثم يطبع قيمة x . يقوم خيط البرنامج الذي يعمل على المعالج رقم 2 بتخزين القيمة 42 في x ثم يخزن القيمة 1 في f . يظهر أدناه رمز زائف لجزئي البرنامج.
تتوافق خطوات البرنامج مع تعليمات المعالج الفردية.
الخيط رقم 1 النواة رقم 1:
بينما ( f == 0 ) { استمر ; } // حاجز الذاكرة مطلوب هنا printf ( "%d" , x );الخيط 2 النواة 2:
x = 42 ; // يلزم وجود حاجز ذاكرة هنا f = 1 ;قد يتوقع المرء أن تقوم عبارة الطباعة دائمًا بطباعة الرقم "42"; ومع ذلك، إذا تم تنفيذ عمليات التخزين الخاصة بالخيط رقم 2 خارج الترتيب، فمن الممكن تحديث f قبل x ، وبالتالي قد تطبع عبارة الطباعة "0وبالمثل، قد تُنفَّذ عمليات تحميل الخيط رقم 1 خارج الترتيب، ومن الممكن قراءة قيمة x قبل التحقق من قيمة f ، وبالتالي قد تُطبع عبارة الطباعة قيمة غير متوقعة. بالنسبة لمعظم البرامج، لا يُعد أيٌّ من هذين الوضعين مقبولًا. يجب إدراج حاجز ذاكرة قبل إسناد الخيط رقم 2 قيمة f لضمان أن تكون القيمة الجديدة لـ x مرئية للمعالجات الأخرى عند أو قبل تغيير قيمة f . ومن النقاط المهمة الأخرى أنه يجب أيضًا إدراج حاجز ذاكرة قبل وصول الخيط رقم 1 إلى x لضمان عدم قراءة قيمة x قبل رؤية تغيير قيمة f .
مثال آخر هو عندما يقوم السائق بتنفيذ التسلسل التالي:
// تجهيز البيانات لوحدة الأجهزة // يلزم هنا حاجز الذاكرة // تشغيل وحدة الأجهزة لمعالجة البياناتإذا تم تنفيذ عمليات تخزين المعالج خارج الترتيب، فقد يتم تشغيل وحدة الأجهزة قبل أن تصبح البيانات جاهزة في الذاكرة.
للحصول على مثال توضيحي آخر (وهو مثال غير تافه يظهر في الممارسة العملية الفعلية)، انظر إلى القفل المزدوج التحقق .
في حالة معالج PowerPC، eieioتضمن تعليمة "فرض التنفيذ المتسلسل للإدخال/الإخراج" (Enforce In-order Execution of I/O)، كحاجز للذاكرة، إتمام جميع عمليات التحميل أو التخزين التي بدأها المعالج مسبقًا بالكامل فيما يتعلق بالذاكرة الرئيسية قبل أن تصل أي عمليات تحميل أو تخزين لاحقة يبدأها المعالج إلى الذاكرة الرئيسية. [ 1 ] [ 2 ]
في حالة عائلة معمارية ARM ، يتم استخدام تعليمات DMB [ 3 ] و DSB [ 4 ] و ISB [ 5 ] . [ 6 ]
في حالة بنية RISC-V، يتم استخدام تعليمة FENCE .
في حالة بنية x86، يتم استخدام تعليمات MFENCE و LFENCE و SFENCE .
التنفيذ خارج الترتيب مقابل تحسينات إعادة ترتيب المُصرّف
لا تعالج تعليمات حاجز الذاكرة تأثيرات إعادة ترتيب التعليمات إلا على مستوى العتاد. وقد تقوم المترجمات أيضًا بإعادة ترتيب التعليمات كجزء من عملية تحسين البرنامج . ورغم أن التأثيرات على سلوك البرنامج المتوازي قد تكون متشابهة في الحالتين، فإنه من الضروري عمومًا اتخاذ تدابير منفصلة لمنع تحسينات إعادة ترتيب التعليمات التي تُجريها المترجمات للبيانات التي قد تتشاركها عدة خيوط تنفيذ.
في لغتي C و C++ ، صُممت الكلمة المفتاحية volatile لتمكين برامج C و C++ من الوصول المباشر إلى عمليات الإدخال/الإخراج المُرتبطة بالذاكرة . تتطلب عمليات الإدخال/الإخراج المُرتبطة بالذاكرة عمومًا أن تتم عمليات القراءة والكتابة المُحددة في شفرة المصدر بالترتيب الدقيق المُحدد دون أي حذف. أي حذف أو إعادة ترتيب لعمليات القراءة والكتابة من قِبل المُترجم سيؤدي إلى انقطاع الاتصال بين البرنامج والجهاز الذي يتم الوصول إليه عبر عمليات الإدخال/الإخراج المُرتبطة بالذاكرة. لا يجوز لمُترجم AC أو C++ حذف عمليات القراءة من مواقع الذاكرة المُتغيرة أو الكتابة إليها، كما لا يجوز له إعادة ترتيب عمليات القراءة/الكتابة بالنسبة إلى عمليات أخرى مماثلة لنفس الموقع المُتغير (المتغير). لا تضمن الكلمة المفتاحية volatile وجود حاجز ذاكرة لفرض اتساق ذاكرة التخزين المؤقت. لذلك، فإن استخدام volatile وحده غير كافٍ لاستخدام متغير للاتصال بين الخيوط على جميع الأنظمة والمعالجات. [ 7 ]
لا تتناول معايير لغتي C و C++ السابقة لإصداري C11 و C++11 معالجة الخيوط المتعددة (أو المعالجات المتعددة)، [ 8 ] وبالتالي، تعتمد فائدة استخدام volatile على المُصرّف والعتاد. مع أن volatile يضمن تنفيذ عمليات القراءة والكتابة المتغيرة بالترتيب المحدد في الشيفرة المصدرية، إلا أن المُصرّف قد يُولّد شيفرة (أو قد يُعيد المعالج ترتيب التنفيذ) بحيث يُعاد ترتيب عملية القراءة أو الكتابة المتغيرة بالنسبة لعمليات القراءة أو الكتابة غير المتغيرة، مما يُحدّ من فائدتها كعلامة بين الخيوط أو كقفل تبادلي.
انظر أيضاً
- ميلتداون (ثغرة أمنية) – ثغرة أمنية في المعالج الدقيق
- نموذج الذاكرة (البرمجة) – تفاعلات الخيوط عبر الذاكرة
- نقطة التسلسل – مفهوم في برمجة الحاسوب
مراجع
- ↑ ماي، كاثي؛ سيلها، إد؛ سيمبسون، إيك؛ وارن، هانك (1993). بنية PowerPC: مواصفات لعائلة جديدة من معالجات RISC . دار نشر مورغان كوفمان. ص 350. ISBN 1-55860-316-6.
- ↑ كاتشمارسيك، كاري (1995). تحسين كود PowerPC . شركة أديسون-ويسلي للنشر. ص 188. ISBN 0-201-40839-2.
- ↑ "DMB" . Developer.ARM.com . تم الاطلاع عليه بتاريخ 12 يناير 2025 .
- ↑ "DSB" . Developer.ARM.com . تم الاطلاع عليه بتاريخ 12 يناير 2025 .
- ↑ "ISB" . Developer.ARM.com . تم الاطلاع عليه بتاريخ 12 يناير 2025 .
- ↑ "DMB وDSB وISB" . Developer.ARM.com . تم الاطلاع عليه بتاريخ 12 يناير 2025 .
- ↑ كوربيت، جوناثان. "لماذا لا ينبغي استخدام فئة النوع 'Volatile'" . Kernel.org . تم الاطلاع عليه في 13 أبريل 2023 .
- ↑ بوهم، هانز (يونيو 2005). لا يمكن تنفيذ الخيوط كمكتبة . وقائع مؤتمر ACM SIGPLAN لعام 2005 حول تصميم لغات البرمجة وتنفيذها . رابطة آلات الحوسبة . ص 261. CiteSeerX 10.1.1.308.5939 . doi : 10.1145/1065010.1065042 . ISBN 1595930566.
للمزيد من القراءة
- ماكيني، بول إي. (30 يونيو 2005). "ترتيب الذاكرة في المعالجات الدقيقة الحديثة، الجزء الأول" . مجلة لينكس . مؤرشف من الأصل في 12 يونيو 2026. تم الاطلاع عليه في 9 يوليو 2026 .
- ماكيني، بول إي. (28 يوليو 2005). "ترتيب الذاكرة في المعالجات الدقيقة الحديثة، الجزء الثاني" . مجلة لينكس . مؤرشف من الأصل في 12 يونيو 2026. تم الاطلاع عليه في 9 يوليو 2026 .
- "معالجة ترتيب الذاكرة في التطبيقات متعددة الخيوط باستخدام Oracle Solaris Studio 12 Update 2: الجزء 1، حواجز المُصرّف" (ملف PDF) . أوراكل . سبتمبر 2010. تم الاطلاع عليه في 9 يوليو 2026 .
- "معالجة ترتيب الذاكرة في التطبيقات متعددة الخيوط باستخدام Oracle Solaris Studio 12 Update 2: الجزء 2، حواجز الذاكرة وأسوار الذاكرة" (ملف PDF) . أوراكل. سبتمبر 2010. تم الاطلاع عليه في 9 يوليو 2026 .
- ذاكرة الحاسوب
- نماذج الاتساق
- معالجة التعليمات
