سؤال

أقوم بتشغيل وظائف الحوسبة العلمية المتوازية بشكل كبير على كمبيوتر Linux المشترك مع 24 نوى. في معظم الأوقات ، تكون وظيفتي قادرة على التحجيم إلى 24 نوى عندما لا يتم تشغيل أي شيء آخر على هذا الكمبيوتر. ومع ذلك ، يبدو أنه عندما يتم تشغيل وظيفة واحدة من غيرها غير المنصوص عليها ، فإن وظيفتي التي تتسع من 24 عامًا (والتي حددتها للقيم اللطيفة العالية) تمكن فقط من الحصول على حوالي 1800 ٪ من وحدة المعالجة المركزية (باستخدام تدوين Linux). وفي الوقت نفسه ، فإن حوالي 500 ٪ من دورات وحدة المعالجة المركزية (مرة أخرى ، باستخدام تدوين Linux) تكون خاملة. هل يمكن لأي شخص أن يشرح هذا السلوك وما يمكنني فعله حيال ذلك للحصول على جميع النوى الـ 23 التي لا يستخدمها شخص آخر؟

ملاحظات:

  1. في حال كان الأمر مناسبًا ، فقد لاحظت ذلك على إصدارات kernel مختلفة قليلاً ، على الرغم من أنني لا أستطيع تذكر أي رأسي.

  2. بنية وحدة المعالجة المركزية هي x64. هل من الممكن على الإطلاق حقيقة أن وظائفي البالغة 24 نواة هي 32 بت والوظائف الأخرى التي أتنافس عليها مع 64 بت من الصلة؟

تحرير: هناك شيء واحد لاحظته للتو هو أن الوصول إلى 30 سلسلة خيوط يبدو أنه يخفف من المشكلة إلى حد ما. يحصل لي حتى ~ 2100 ٪ وحدة المعالجة المركزية.

هل كانت مفيدة؟

المحلول

من المحتمل أن يكون هذا ناتجًا عن محاولة جدولة إبقاء كل من مهامك تعمل على نفس وحدة المعالجة المركزية التي كانت تعمل عليها سابقًا (إنها تفعل ذلك لأن المهمة قد جلبت على الأرجح مجموعة عملها في ذاكرة التخزين المؤقت الخاصة بوحدة المعالجة المركزية - إنها "ذاكرة التخزين المؤقت الساخنة ").

إليك بعض الأفكار التي يمكنك تجربتها:

  • قم بتشغيل ضعف عدد الخيوط التي لديك النوى ؛
  • قم بتشغيل واحد أو اثنين من المواضيع أقل من النوى ؛
  • تقليل قيمة /proc/sys/kernel/sched_migration_cost (ربما وصولاً إلى الصفر) ؛
  • تقليل قيمة /proc/sys/kernel/sched_domain/.../imbalance_pct أسفل أقرب إلى 100.

نصائح أخرى

هل يجب أن تتم مزامنة المواضيع الخاصة بك؟ إذا كان الأمر كذلك ، فقد يكون لديك المشكلة التالية:

افترض أن لديك نظام 4-CPU ، ووظيفة من 4 تراكم. عند الركض بمفردك ، فإن Threads Fan Out لاستخدام جميع النوى الأربعة والاستخدام الكلي على وشك الكمال (سنطلق عليه 400 ٪).

إذا قمت بإضافة وظيفة تداخل واحدة متداخلة ، فقد يضع المجدول 2 من مؤشرات الترابط الخاصة بك على نفس وحدة المعالجة المركزية. هذا يعني أن 2 من خيوطك تعمل الآن بفعالية نصف وتيرتها العادية (التبسيط الدرامي) ، وإذا كانت مؤشرات الترابط الخاصة بك بحاجة إلى مزامنة بشكل دوري ، يمكن أن يكون تقدم وظيفتك محدودًا بأبطأ خيط ، والذي يعمل في هذه الحالة في هذه الحالة نصف السرعة العادية. سترى استخدام 200 ٪ فقط (من وظيفتك تشغيل 4x 50 ٪) بالإضافة إلى 100 ٪ (مهمة التدخل) = 300 ٪.

وبالمثل ، إذا افترضت أن المهمة المتداخلة تستخدم فقط 25 ٪ من وقت معالج واحد ، فقد ترى أحد خيوطك والمتداخل على نفس وحدة المعالجة المركزية. في هذه الحالة ، يتم تشغيل الخيط الأبطأ بسرعة 3/4 ، مما تسبب في أن يكون الاستخدام الكلي 300 ٪ (4x 75 ٪) + 25 ٪ = 325 ٪. العب بهذه الأرقام وليس من الصعب التوصل إلى شيء مشابه لما تراه.

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

هل يتواصل المواضيع الخاصة بك مع بعضها البعض؟

حاول ربط كل موضوع يدويًا بوحدة المعالجة المركزية ، مع sched_setaffinity أو pthread_setaffinity_np. يمكن أن يكون المجدول غبيًا إلى حد ما عند العمل مع الكثير من المواضيع المتعلقة.

قد يكون من المفيد الاستخدام mpstat (جزء من sysstat حزمة) لمعرفة ما إذا كان لديك وحدات المعالجة المركزية كاملة الجلوس في وضع الخمول بينما يتم استخدام الآخرين بالكامل. يجب أن يعطيك عرضًا أكثر تفصيلاً للاستخدام من Top أو Vmstat: Run mpstat -P ALL لرؤية خط واحد لكل وحدة المعالجة المركزية.

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

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

// COMPILE WITH: gcc threads.c -lpthread -o thread
#include <pthread.h>
#define NUM_CORES 24

void* loop_forever(void* argument) {
    int a;
    while(1) a++;
}

void main() {
    int i;
    pthread_t threads[NUM_CORES];

    for (i = 0; i < NUM_CORES; i++)
        pthread_create(&threads[i], 0, loop_forever, 0);

    for (i = 0; i < NUM_CORES; i++)
        pthread_join(threads[i], 0);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top