فهرس |
قد تجد نفسك يوماً ما، كمبرمج، بحاجة لحل مشاكل أضخم، وتتعامل مع مجال ذاكري اكبر، أو ربما قد تحتاج ببساطة لحل مشاكل بسرعة أكبر من الممكن تحقيقها على حواسيب تسلسلية. بإمكانك عندها الانتقال إلى البرمجة التفرعية و الحواسيب التفرعية للتعامل مع هذه الاحتياجات. إن استخدام أساليب البرمجة التفرعية على حواسيب تفرعية يمنحك الوصول لموارد ذاكرية أكبر وموارد وحدة المعالجة المركزية CPU غير متاحة على حواسيب تسلسلية. لذلك، ستكون قادراً على حل مشاكل ضخمة لا يمكن حلها بطرق أخرى وبسرعة أكبر. أحد الأساليب الأساسية في البرمجة التفرعية هو استخدام مكتبات تمرير الرسائل. تؤمن هذه المكتبات إدارة نقل المعطيات بين مقاطع من برامج تفرعية تعمل (عادةً) على معالجات متعددة في بنية حوسبية تفرعية
تم إعداد MPI كأداة قياسية لنموذج "تمرير الرسائل" في البرمجة التفرعية. - يتألف الحساب التفرعي من عدد من العمليات، تعمل كلُ منها على معطيات محلية. كل عملية تمتلك متحولات محلية خاصة بها، وليس هناك من آلية تمكّن أي عملية من الوصول المباشر لذاكرة العملية الأخرى. - تشارك المعطيات بين العمليات يتحقق عبر تمرير الرسائل، ويتم ذلك، عبر الإرسال والاستقبال الصريح للمعطيات بين العمليات. لاحظ أن النموذج يتضمن عمليات، والتي لا تحتاج –من ناحية المبدأ- لأن يتم تنفيذها على معالجات مختلفة. في هذا المنهاج التعليمي، سيتم عموماً افتراض أن عملياتٍ مختلفة يتم تنفيذها على معالجاتٍ مختلفة وأن المصطلحين "عمليات" و "معالجات" يتم استخدامهما بشكل قابل للتبادل (على سبيل المثال، عند الحديث عن اتصال المعالجات مع بعضها). السبب الأساسي في منفعة هذا النموذج هو عموميته المفرطة. أساساً، أي نوع من الحوسبة التفرعية يمكن أن يتم طرحه بأسلوب تمرير الرسائل. وبالإضافة، فإن هذا النموذج: - يمكن تحقيقه على تنوع كبير من المنصات، من بنية ذاكرة مشتركة متعددة المعالجات إلى شبكات محطات العمل وحتى الأجهزة ذات المعالج الوحيد. - يسمح عموماً بالمزيد من التحكم على موقع وتدفق المعطيات ضمن البرنامج التفرعي الموجود فيه، على سبيل المثال: بنية الذاكرة المشتركة. يمكن لمثل هذه البرامج أن تحقق أداءً أعلى باستخدام الأسلوب الصريح في تمرير الرسائل. و بالفعل، فإن الأداء هو سبب رئيسي في عدم اختفاء نموذج تمرير الرسائل من عالم البرمجة التفرعية
MPI هي اختصار لـ "Message passing interface". وهي مكتبة من التوابع (بلغة C) تقوم بتضمينها ضمن شيفرة المصدر لإنجاز اتصال للمعطيات بين المعالجات. تم تطوير MPI بعد عامان من المناقشة المقادة بواسطة منتدى MPI، مجموعة من حوالي 60 شخصاً يمثّلون حوالي 40 منظمة. تم تعريف النسخة القياسية MPI-1 في ربيع عام 1994. - عرّفت هذه النسخة كلاً من الأسماء، تسلسلات الاستدعاء، ونتائج التوابع و الروتينات الفرعية المستدعاة من قبل C. جميع وسائل MPI يجب أن تتبع لهذه القواعد المعرّفة، هذا يضمن تحسين المحمولية. يجب على جميع برامج MPI أن يتم ترجمتها وتنفيذها على أي منصة تدعم MPI القياسية. - التنفيذ التفصيلي الفعلي للمكتبة تم تركه للشركات الخاصة، والذين أصبحوا هكذا أحراراً في إنتاج نسخاً مصغّرة لآلاتهم. - أغلب إصدارات MPI القياسية هي متاحة لتنوع كبير من منصات العمل. أيضاً تم تعريف النسخة القياسية MPI-2. جاءت هذه النسخة بميزات إضافية غير محتواة في MPI-1، ويتضمن ذلك أدوات للدخل/الخرج التفرعي، دعم لغات C++ و Fortran90، وإدارة ديناميكية للعملية. في الوقت الحاضر، تتضمن بعض نسخ MPI أجزاءً من ميزات النسخة القياسية MPI-2 لكن النسخة الكاملة من MPI-2 غير متوفرة بعد.
جميع هذه النقاط أصبحت متاحة في نسخة MPI-2.
ينبغي عليك استخدام MPI عندما تكون بحاجة إلى:
لا ينبغي عليك استخدام MPI عندما:
تتألف برامج تمرير الرسائل من عدة مقاطع من برنامج تسلسلي والذي يتخاطب عبر استدعاءات مكتبية. هذه الاستدعاءات يمكن تصنيفها مبدأياً إلى أربعة أصناف:
الصنف الأول من الاستدعاءات: يتألف من استدعاءات لبدء عمليات الاتصال وتحديد عدد المعالجات المستخدمة وتكوين مجموعات جزئية من المعالجات وتحديد أياً من المعالجات يقوم بتنفيذ ذلك الجزء المحدد من البرنامج.
الصنف الثاني من الاستدعاءات:، يُدعى عمليات الاتصال من نوع نقطة-إلى-نقطة، ويتألف من أنواع مختلفة من عمليات الإرسال والاستقبال.
الصنف الثالث من الاستدعاءات: هو عبارة عن العمليات المتداخلة التي تؤمن التزامن أو أنواعاً أخرى محددة من عمليات الاتصال المعرّفة جيداً بين مجموعات من المعالجات إضافةً إلى استدعاءات تنجز عمليات الاتصال/الحساب المتداخلة.
الصنف الأخير من الاستدعاءات يؤمن مرونة في الاتصال مع بُنى المعطيات المعقدة.
بلغة C :
\#include <stdio.h> \#include <mpi.h>
int err; err = MPI_Init(&argc, &argv); printf("Hello world!\n"); err = MPI_Finalize();
|
ملاحظات سريعة على البرنامج:
Hello world! Hello world! Hello world! Hello world! |
if (I am processor 1) ...do something... if (I am processor 2) ...do something else... |
جميع برامج الـ MPI لها البنية العامة التالية :
و الآن لنرى ما معنى كل منها على حدا ملف الترويسة للـ MPI هو ملف يحتوي على التعريفات و نماذج التوابع الخاصة بـ الـ MPI التصريح عن المتغيرات و فيه يتم التصريح عن المتغيرات التي سوف نستخدمها في البرنامج تهيئة البيئة عن طريق استدعء التابع الخاص بذلك سنراه لاحقا جميع العمليات الحسابية و الاتصالات بين توابع الـ MPI يجب ان تتم بعد عملية التهيئة للبيئة و بعد ذلك يتم إلاق عملية التهئة عن طريق تابع خاص سنراه لاحقاو لا يجوز استدعاء اي تابع بعد أغلاق التهيئة كما أنه من الضروري ان نذكر أنّ اي عملية لا تصل ال مرحلة النهاية سيبدو البرنامج المنقذ لها كما لو أنه في حالة جمود
إنّ ملفات الترويسة للـ MPI تحتوي على نماذج التوابع و الإستدعاءات الخاصة بالـ MPI كما تحتوي على تعريفات الـ Macros و الثوابت الخاصة و الأنواع المستعملة في الـ MPI حيث تم استخدام كلمة Include مع اسم ملف الترويسة في اي ملف مصدر Source file من أجل تضمين التوابع و الثوابت الخاصة بالـ MPI على النحو التالي C :
\#include <mpi.h> |
مصطلحات التسمية المستخدمة في الـ MPI
MPI_Xxxxx(parameters….) و كمثال عليها MPI_Init(&argc,&argv). |
أمّا عن أسماء ثوابت الـ MPI فتستخدم الـ الأحرف الكبيرة و كمثال عليها : MPI_COMM_WORLD,MPI_REAL
إجراءات الـ MPI و القيم المعادة
يتم تمثيل إجراءات الـ MPI في لغة الـ C على شكل توابع Functions ومن جهة أخرى نلاحظ أنّه و بشكل عام يتم إعادة رقم الخطأ في حال حدوثه مما يسمح لك باختبار نجاح العملية التي تنفذ الإجراء أو فشلها . في لغة الـ C : تعيد توابع الـ MPI رقم صحيح من خلاله نستطيع تحديد حالة انتهاء الاستدعاء
Int err ; ......... ......... err = MPI_Init(&argc,&arcv); |
إنّ شيفرة الخطأ تعيد الـ MPI_SUCCESS اذا نجح الإستدعاء وهذا يعني أنّ قيمة العدد الصحيح تكون مساوية للقيمة المسندة بشكل سابق للـ MPI_SUCCESS و هكذا يمكن فحص نجاح العلمية أولا.
C: If ( err = MPI_SUCCESS) { ..... ..... Routines run correctly ..... ..... } |
و في حال حدوث الخطأ يمثل العدد الصحيح المعاد قيمة تدل على خطأ معين . الأنواع الأساسية لمعطيات الـ MPI في لغة الـ C الجدول التالي يوضح هذه الأنواع وتقاطعاتها مع الأنماط في C
نمط الـ C |
نمط الـ MPI |
Signed char |
MPI_CHAR |
Signed short int |
MPI_SHORT |
Signed int |
MPI_INT |
Signed long int |
MPI_LONG |
Unsigned char |
MPI_UNSIGNED_CHAR |
Unsigned short int |
MPI_UNSIGNED_SHORT |
Unsigned int |
MPI_UNSIGNED |
Unsigned long int |
MPI_UNSIGNED_LONG |
Float |
MPI_FLOAT |
Double |
MPI_DOUBLE |
Long double |
MPI_LONG_DOUBLE |
(none) |
MPI_BYTE |
(none) |
MPI_PACKED |
أنماط معطيات خاصة بـ MPI
في لغة الـ C تزود الـ MPI العديد من أنماط المعطيات الخاصة فعلى سبيل المثال
و تستخدم هذه الأنماط في التصريح عن المتحولات فعلى سبيل المثال MPI_Comm some_comm ;
إن إجراء الـ MPI الأول الذي يتم استدعاءه في أي برنامج للـ MPI يجب أن يكون اجراء التهيئة وهو MPI_INIT هذ1 الإجراء يقوم بتأسيس بيئة الـ MPI و يعيد شيفرة خطأ إذا كان هناك مشكلة . إن الإجراء MPI_INIT يتم استدعاءه مرة واحدة فقط في بداية البرنامج
C: int err; …. err = MPI_Init(&argc,&argv); |