الدرس 23: العمليات الذرية: atomicAdd والمدرّجات التكرارية
عندما تحاول آلاف الـ threads تحديث نفس خلية الذاكرة في وقت واحد، ينشأ تعارض تسابق (race condition). خذ مثال المدرّج التكراري: يقرأ كل thread قيمة ويريد زيادة العدّاد bins[v] بمقدار واحد. تبدو العملية bins[v]++ ذرّية، لكنها في الواقع ثلاث خطوات منفصلة: قراءة القيمة الحالية، إضافة واحد، ثم كتابتها مرة
تخيّل جرّة عدّ مشتركة. بدون atomic، يرى شخصان الرقم 5، ويضيف كلاهما 1 في رأسه، ويكتب كلاهما 6 — لكنه كان يجب أن يصل إلى 7، فضاعت عدّة. atomic أشبه بالسماح لشخص واحد فقط في كل مرة بأن يمسك الجرّة، ويضيف، ويعيدها — لا أحد يدوس على أحد.
- تعارض التسابق (race condition)
- عندما تصل عمليتان متوازيتان إلى نفس الذاكرة وتكتب واحدة منهما على الأقل، فتعتمد النتيجة على الترتيب العشوائي الذي تُنفَّذان به.
- عملية ذرّية (atomic)
- عملية read-modify-write ينفّذها العتاد كوحدة واحدة غير قابلة للتجزئة — لا يتسلل أي thread آخر في المنتصف. على سبيل المثال atomicAdd.
- read-modify-write
- الخطوات الثلاث لـ ++: قراءة القيمة، التعديل، الكتابة مرة أخرى. على التوازي، دون حماية، تتداخل هذه الخطوات بين الـ threads.
- المدرّج التكراري (histogram)
- عدّ كم مرة تظهر كل قيمة. يزيد كل thread قيمة bins[v]؛ وتتطلّب threads كثيرة على نفس الـ bin استخدام atomicAdd.