جلب وإضافة
في علوم الحاسوب ، تقوم تعليمة جلب وإضافة ( FAA ) وحدة المعالجة المركزية بزيادة محتويات موقع الذاكرة بشكل ذري بقيمة محددة.
أي أن عملية الجلب والإضافة تقوم بالعملية التالية: زيادة القيمة عند العنوان xبمقدار a، حيث xيمثل موقع الذاكرة و هي قيمة ما، وإرجاع القيمة الأصلية عند x.
بطريقة بحيث إذا تم تنفيذ هذه العملية بواسطة عملية واحدة في نظام متزامن ، فلن ترى أي عملية أخرى نتيجة وسيطة.
يمكن استخدام تقنية الجلب والإضافة لتنفيذ هياكل التحكم في التزامن مثل أقفال التزامن والإشارات .
ملخص
يكمن الدافع وراء استخدام عملية جلب وإضافة ذرية في أن العمليات التي تظهر في لغات البرمجة على x = x + aأنها غير آمنة في نظام متزامن، حيث تعمل عمليات أو خيوط متعددة في وقت واحد (سواء في نظام متعدد المعالجات ، أو مُجدولة مسبقًا على بعض الأنظمة أحادية النواة). والسبب هو أن هذه العملية تُنفذ فعليًا على شكل تعليمات آلية متعددة.
- تحميل
xفي سجل؛ - أضف
aإلى السجل؛ - قم بتخزين قيمة السجل مرة أخرى في
x.
عندما تعمل عملية ما بالتزامن x = x + aمع عملية أخرى x = x + b، يحدث تضارب في البيانات . قد تقوم كلتا العمليتين بجلب قيمة x القديمة وإجراء عمليات عليها، ثم تقوم كلتاهما بتخزين نتائجها، مما يؤدي إلى استبدال إحداهما للأخرى، فتصبح القيمة المخزنة إما x القديمة + a أو x القديمة + b ، وليس x القديمة + a + b كما هو متوقع.
في الأنظمة أحادية المعالج التي لا تدعم مقاطعة النواة ، يكفي تعطيل المقاطعات قبل الوصول إلى قسم حرج . أما في الأنظمة متعددة المعالجات (حتى مع تعطيل المقاطعات)، فقد يحاول معالجان أو أكثر الوصول إلى نفس الذاكرة في الوقت نفسه. تسمح تعليمة الجلب والإضافة لأي معالج بزيادة قيمة في الذاكرة بشكل ذري، مما يمنع حدوث تصادمات بين المعالجات المتعددة.
أثبت موريس هيرليهي (1991) أن عملية الجلب والإضافة لها عدد توافق محدود ، على عكس عملية المقارنة والتبديل . تستطيع عملية الجلب والإضافة حل مشكلة التوافق بدون انتظار لما لا يزيد عن عمليتين متزامنتين. [ 1 ]
تطبيق
تتصرف تعليمة جلب البيانات وإضافتها كما في الدالة التالية. والأهم من ذلك، أن الدالة بأكملها تُنفذ بشكل ذري : لا يمكن لأي عملية مقاطعة الدالة أثناء تنفيذها، وبالتالي لا يمكنها رؤية حالة موجودة فقط خلال تنفيذ الدالة. هذا الكود يُستخدم فقط لتوضيح سلوك جلب البيانات وإضافتها؛ تتطلب الذرية دعمًا صريحًا من الأجهزة، وبالتالي لا يمكن تنفيذها كدالة بسيطة عالية المستوى.
باستخدام std :: atomic ;دالة `fetchAndAdd` تأخذ وسيطين : ` location` و` inc` . تقوم الدالة بإرجاع قيمة `location` المُمرَّرة إلى الدالة ` fetch_add` مع تمرير الوسيط ` inc` .يمكن تطبيق قفل الاستبعاد المتبادل باستخدام خوارزمية قفل التذاكر كما يلي:
استيراد std ؛باستخدام std :: atomic ؛ باستخدام std :: memory_order ؛class Lock { private : atomic <int> ticketNumber { 0 }; atomic <int> turn { 0 } ; public : void lock () { // يجب أن تكون العملية ذرية، حيث قد تطلب عدة سلاسل عمليات القفل في وقت واحد int myTurn = ticketNumber.fetch_add ( 1 , memory_order :: relaxed ) : while ( turn.load ( memory_order :: acquire ) ! = myTurn ) { // استمر في المحاولة حتى يتم الحصول على القفل } }void unlock () { // ليس بالضرورة أن تكون هذه العملية ذرية، حيث أن مالك القفل فقط هو من سينفذها في هذا الدور . fetch_add ( 1 , memory_order :: release ); } };دعم الأجهزة والبرامج
تظهر طريقة ذرية fetch_add()لـ في معيار C++11 . [ 2 ] وهي متاحة كإضافة خاصة للغة C في مواصفات Itanium ABI ، [ 3 ] وبنفس الصيغة في GCC . [ 4 ]std::atomic<T>
تنفيذ x86
في معمارية x86، تُعدّ تعليمة ADD، التي تُحدد موقعًا في الذاكرة كمعامل وجهة، تعليمة جلب وجمع موجودة منذ معالج 8086 (لكنها لم تكن تُسمى كذلك آنذاك)، ومع إضافة البادئة LOCK، تُصبح ذرية عبر معالجات متعددة. مع ذلك، لم تكن قادرة على إرجاع القيمة الأصلية لموقع الذاكرة (على الرغم من أنها كانت تُرجع بعض العلامات) حتى قدم معالج 486 تعليمة XADD.
فيما يلي تطبيق بلغة C لمترجم GCC ، لكل من منصات Intel x86 ذات 32 بت و 64 بت، استنادًا إلى asmبناء الجملة الموسع:
دالة مضمنة int fetchAndAdd ( int * variable , int value ) { asm volatile ( "lock; xaddl %0, %1" : "+r" ( value ), "+m" ( * variable ) // إدخال + إخراج : // بدون إدخال فقط : "memory" ); return value ; }تاريخ
تم تقديم تقنية الجلب والإضافة بواسطة مشروع Ultracomputer ، الذي أنتج أيضًا معالجًا متعددًا يدعم تقنية الجلب والإضافة ويحتوي على مفاتيح VLSI مخصصة قادرة على دمج مراجع الذاكرة المتزامنة (بما في ذلك عمليات الجلب والإضافة) لمنعها من التسلسل في وحدة الذاكرة التي تحتوي على المعامل الوجهة.
انظر أيضاً
مراجع
- ↑ هيرليهي، موريس (يناير 1991). "المزامنة بدون انتظار" (ملف PDF) . مجلة ACM للمعاملات في لغات البرمجة والأنظمة ، 13 (1): 124-149 . CiteSeerX 10.1.1.56.5659 . doi : 10.1145/114005.102808 . S2CID 2181446. تاريخ الاسترجاع: 20 مايو 2007 .
- ↑ "std::atomic::fetch_add" . cppreference.com . تم الاطلاع عليه في 1 يونيو 2015 .
- ↑ "واجهة التطبيقات الثنائية الخاصة بمعالج إنتل إيتانيوم (ABI)" (ملف PDF) . شركة إنتل . 2001.
- ↑ "الوظائف المدمجة الذرية" . استخدام مجموعة مترجمات جنو (GCC) . مؤسسة البرمجيات الحرة. 2005.
- الحساب الحاسوبي
- التحكم في التزامن
