سؤال

أريد بسهولة أداء الاتصالات الجماعية بشكل مستقل على كل آلة من مجموعة بلدي. دعني أقول لي 4 آلات مع 8 نوى على كل منها ، وسيقوم برنامج MPI الخاص بي بتشغيل 32 MPI. ما أود هو ، لوظيفة معينة:

  • في كل مضيف ، تقوم مهمة واحدة فقط بإجراء حساب ، والمهام الأخرى لا تفعل شيئًا أثناء هذا الحساب. في المثال الخاص بي ، ستقوم 4 مهام MPI بالحساب ، 28 آخرون ينتظرون.
  • بمجرد الانتهاء من الحساب ، ستؤدي كل مهام MPI على كل اتصال جماعي فقط للمهام المحلية (المهام التي تعمل على نفس المضيف).

من الناحية المفاهيمية ، أفهم أنه يجب علي إنشاء اتصال واحد لكل مضيف. لقد بحثت حولها ، ولم أجد شيئًا يفعل ذلك بشكل صريح. أنا لست مرتاحًا حقًا لمجموعات MPI والاتصالات. هنا أسئلتي:

  • هل mpi_get_processor_name فريد من نوعه لمثل هذا السلوك؟
  • بشكل عام ، هل لديك قطعة من الكود تفعل ذلك؟
هل كانت مفيدة؟

المحلول

المواصفات تقول ذلك MPI_Get_processor_name إرجاع "محدد فريد للعقدة الفعلية (على عكس الافتراضية)" ، لذلك أعتقد أنك ستكون على ما يرام مع ذلك. أعتقد أنك ستقوم بتجمع لتجميع جميع أسماء المضيف ، ثم تعيين مجموعات من المعالجات للانفصال وجعل اتصالاتهم ؛ أو DUP MPI_COMM_WORLD ، قم بتحويل الأسماء إلى تجزئة عدد صحيح ، واستخدم MPI_COMM_SPLIT لتقسيم المجموعة.

يمكنك أيضًا اتباع النهج الذي يقترحه Janneb ويستخدم خيارات التنفيذ الخاصة بـ Mpirun لضمان قيام تطبيق MPI بتعيين المهام بهذه الطريقة ؛ يستخدم OpenMPI -byslot لإنشاء هذا الطلب ؛ مع MPICH2 ، يمكنك استخدام -Print-RANK-MAP لمشاهدة التعيين.

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

نصائح أخرى

لا أعتقد (الفكر المتعلم ، وليس نهائيًا) أنك ستتمكن من فعل ما تريده بالكامل من داخل برنامج MPI الخاص بك.

استجابة النظام لدعوة إلى MPI_Get_processor_name يعتمد على النظام. على نظامك قد يعود node00, node01, node02, node03 حسب الاقتضاء ، أو قد تعود my_big_computer لأي معالج تقوم بتشغيله بالفعل. السابق أكثر احتمالا ، لكنه غير مضمون.

تتمثل إحدى الاستراتيجية في بدء 32 عملية ، وإذا كنت تستطيع تحديد العقدة التي يتم تشغيل كل منها ، فقم بتقسيم التواصل إلى 4 مجموعات ، واحدة على كل عقدة. وبهذه الطريقة ، يمكنك إدارة ما بين التواصل بينكما كما تشاء.

تتمثل الإستراتيجية الأخرى في بدء 4 عمليات ووضعها في العقد المختلفة. تعتمد كيفية تثبيت العمليات على العقد (أو المعالجات) على وقت تشغيل MPI وأي نظام لإدارة الوظائف قد يكون لديك ، مثل محرك الشبكة. من المحتمل أن يتضمن هذا وضع متغيرات البيئة-لكنك لا تخبرنا بأي شيء عن نظام وقت التشغيل الخاص بك ، لذلك لا يمكننا تخمين ما قد يكونون. يمكنك بعد ذلك أن تولد كل عملية من العمليات الأربعة ديناميكيًا 7 (أو 8) عمليات وعلانها في نفس العقدة مثل العملية الأولية. للقيام بذلك ، اقرأ موضوعًا بين intercommunicators ووثائق نظام التشغيل الخاص بك.

ستكون الإستراتيجية الثالثة ، التي أصبحت الآن مجنونة بعض الشيء ، هي بدء 4 برامج منفصلة MPI (8 عمليات لكل منها) ، واحدة على كل عقدة من المجموعة الخاصة بك ، والانضمام إليها أثناء تنفيذها. أقرأ عن MPI_Comm_connect و MPI_Open_port للتفاصيل.

أخيرًا ، من أجل المتعة الإضافية ، قد تفكر في التهجين برنامجك ، وتشغيل عملية MPI واحدة على كل عقدة ، وتنفيذ كل عملية من هذه العمليات على برنامج OpenMP المشترك في الذاكرة (الفرعية).

عادةً ما يمكن التحكم في بيئة وقت تشغيل MPI على سبيل المثال من خلال متغيرات البيئة كيف يتم توزيع المهام على العقد. يميل الافتراضي إلى التخصيص المتسلسل ، أي مثالك مع 32 مهمة موزعة على 4 آلات من 8 نواة لديك

  • الآلة 1: تصنيف MPI 0-7
  • الآلة 2: تصنيف MPI 8-15
  • الآلة 3: MPI يحتل 16-23
  • الآلة 4: MPI يحتل 24-31

ونعم ، يجب أن يحصل لك mpi_get_processor_name على اسم المضيف حتى تتمكن من معرفة مكان وجود الحدود بين المضيفين.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top