مشاركة زائفة

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

ذاكرة التخزين المؤقت لوحدة المعالجة المركزية متعددة المعالجات

يُستخدم هذا المصطلح بشكل شائع في ذاكرة التخزين المؤقت لوحدات المعالجة المركزية الحديثة متعددة المعالجات ، حيث تُخزَّن البيانات في أسطر بحجم كلمة من مضاعفات العدد اثنين (مثل 64 بايت متجاورة ومُحاذية ). إذا عمل معالجان على بيانات مستقلة في نفس منطقة عنوان الذاكرة القابلة للتخزين في سطر واحد، فقد تُجبر آليات تماسك ذاكرة التخزين المؤقت في النظام على نقل السطر بأكمله عبر ناقل البيانات أو الربط البيني مع كل عملية كتابة بيانات، مما يُسبب توقفات في الذاكرة بالإضافة إلى هدر عرض نطاق النظام . في بعض الحالات، يُمكن أن يُؤدي التخلص من المشاركة الزائفة إلى تحسينات كبيرة في الأداء. [ 2 ] تُعد المشاركة الزائفة ظاهرة متأصلة في بروتوكولات ذاكرة التخزين المؤقت المُزامنة تلقائيًا، وقد توجد أيضًا في بيئات مثل أنظمة الملفات الموزعة أو قواعد البيانات، ولكن انتشارها الحالي يقتصر على ذاكرة التخزين المؤقت RAM.

مثال

#include <atomic> #include <chrono> #include <iostream> #include <latch> #include <thread> #include <vector>int main () { std :: vector < std :: jthread > threads ; const int hc = std :: jthread :: hardware_concurrency (); constexpr int testLimit = 256 ; // للتبسيط، اجعل الحد الأقصى للعناصر هو 256for ( int nThreads = 1 ; nThreads <= hc && nThreads <= testLimit ; ++ nThreads ) { // قياس دقيق عن طريق بدء جميع الخيوط في وقت واحد std :: latch sync ( nThreads );// بعض البيانات الفردية لكل سلسلة عمليات struct { std :: atomic_char mightBeShared ; } globaldata [ testLimit ];// التخفيف: شغل سطر ذاكرة تخزين مؤقت كامل // struct alignas(64) { std::atomic_char mightBeShared; } globaldata[testLimit];// مجموع أوقات تنفيذ جميع الخيوط std :: atomic_int64_t nsSum ( 0 );for ( int t = 0 ; t != nThreads ; ++ t ) { threads.emplace_back ( [ & ]( int i ) { sync.arrive_and_wait ( ); // مزامنة بداية تنفيذ الخيط على مستوى النواةبدء التشغيل التلقائي = std :: chrono :: high_resolution_clock :: now ();for ( std :: size_t r = 10000000 ; r-- ; ) globaldata [ i ] .mightBeShared.fetch_add ( 1 ) ;nsSum += std :: chrono :: duration_cast < std :: chrono :: nanoseconds > ( std :: chrono :: high_resolution_clock :: now () - start ). count ();}, t ); }threads.clear ( ); // دمج جميع الخيوطstd :: cout << nThreads << " : " << static_cast <double> ( nsSum / ( 1.0e7 * nThreads ) ) << std :: endl ; } }

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

توسع نطاق المشاركة الخاطئة
توسع نطاق المشاركة الخاطئة

كما يمكن للمرء أن يرى، فإن الوصول المتزامن بواسطة تلك الخيوط يتطلب حوالي 50 ضعف وقت الحوسبة مقارنة بالتخفيف حيث يتضاعف تقريبًا.

التخفيف

توجد طرق للتخفيف من آثار المشاركة الخاطئة. على سبيل المثال، يمكن منع المشاركة الخاطئة في ذاكرة التخزين المؤقت لوحدة المعالجة المركزية عن طريق إعادة ترتيب المتغيرات أو إضافة حشو (بايتات غير مستخدمة) بينها. مع ذلك، قد تؤدي بعض هذه التغييرات البرمجية إلى زيادة حجم الكائنات، مما يؤدي إلى زيادة استخدام الذاكرة. [ 2 ] كما يمكن لتحويلات البيانات أثناء الترجمة أن تخفف من المشاركة الخاطئة. [ 3 ] مع ذلك، قد لا يُسمح ببعض هذه التحويلات دائمًا. على سبيل المثال، ينص مسودة معيار لغة البرمجة C++23 على ضرورة ترتيب عناصر البيانات بحيث يكون للعناصر اللاحقة عناوين أعلى. [ 4 ]

توجد أدوات لكشف عمليات المشاركة الخاطئة. [ 5 ] [ 6 ] كما توجد أنظمة تكشف وتصلح عمليات المشاركة الخاطئة في البرامج قيد التنفيذ. مع ذلك، تتسبب هذه الأنظمة في بعض التكاليف الإضافية للتنفيذ. [ 7 ] [ 8 ]

مراجع

  1. باترسون، ديفيد (2012). تنظيم وتصميم الحاسوب: واجهة الأجهزة/البرمجيات . والتهام، ماساتشوستس: مورغان كوفمان. ص  537. ISBN 978-0-12-374750-1. OCLC 746618653 . 
  2. 1 2 بولوسكي، ويليام جيه؛ سكوت، مايكل إل. (22-09-1993). "المشاركة الزائفة وتأثيرها على أداء الذاكرة المشتركة" . Sedms'93: أنظمة USENIX حول تجارب USENIX مع الأنظمة الموزعة ومتعددة المعالجات . 4. تم الاسترجاع في 11 يوليو 2021 .
  3. جيريمياسن، تور إي.؛ إيغرز، سوزان جيه. (1995). "الحد من المشاركة الخاطئة على المعالجات المتعددة ذات الذاكرة المشتركة من خلال تحويلات البيانات في وقت الترجمة" . إشعارات ACM SIGPLAN . 30 (8). رابطة آلات الحوسبة (ACM): 179-188 . doi : 10.1145/209937.209955 . ISSN 0362-1340 . 
  4. "مسودة عمل، معيار للغة البرمجة C++ [ فئة ] " . eel.is. تم الاسترجاع في 11-07-2021 .
  5. "perf-c2c(1)" . صفحة دليل لينكس . 2016-09-01 . تم الاطلاع عليه بتاريخ 2021-08-08 .
  6. شابي، ميليند؛ وين، شاشا؛ ليو، شو (10 فبراير 2018). "الكشف الفوري عن المشاركة الخاطئة باستخدام Featherlight". وقائع ندوة ACM SIGPLAN الثالثة والعشرين حول مبادئ وممارسات البرمجة المتوازية . نيويورك، نيويورك، الولايات المتحدة الأمريكية: ACM. الصفحات 152-167 . doi : 10.1145/3178487.3178499 . ISBN  9781450349826.
  7. نانافاتي، ميهير؛ سبير، مارك؛ تايلور، ناثان؛ راجاغوبالان، شري رام؛ ماير، داتش تي.؛ أييلو، ويليام؛ وارفيلد، أندرو (2013). "لمن هذا السطر في ذاكرة التخزين المؤقت؟". وقائع المؤتمر الأوروبي الثامن لجمعية ACM لأنظمة الحاسوب . نيويورك، نيويورك، الولايات المتحدة الأمريكية: مطبعة ACM. الصفحات 141-154 . doi : 10.1145/2465351.2465366 . ISBN  9781450319942.
  8. ليو، تونغ بينغ؛ بيرغر، إيمري د. (18 أكتوبر 2011). "SHERIFF: الكشف الدقيق والتخفيف التلقائي من المشاركة الخاطئة". إشعارات ACM SIGPLAN . 46 (10). رابطة آلات الحوسبة (ACM): 3-18 . doi : 10.1145/2076021.2048070 . ISSN 0362-1340 .