OpenHMPP

OpenHMPP (اختصارًا لـ HMPP [ 1 ] ، أي البرمجة المتوازية الهجينة متعددة النوى) هو معيار برمجي للحوسبة غير المتجانسة . يعتمد هذا المعيار على مجموعة من توجيهات المُصرّف، وهو نموذج برمجي مصمم للتعامل مع مُسرّعات الأجهزة دون التعقيدات المرتبطة ببرمجة وحدات معالجة الرسومات (GPU ). وقد تم تطبيق هذا النهج القائم على التوجيهات لأنه يُتيح علاقة مرنة بين كود التطبيق واستخدام مُسرّع الأجهزة (HWA).

مقدمة

يوفر نموذج البرمجة القائم على التوجيهات في OpenHMPP صيغة لتفريغ العمليات الحسابية على مسرعات الأجهزة ولتحسين نقل البيانات من وإلى ذاكرة الأجهزة.

يعتمد النموذج على الأعمال التي بدأها مشروع CAPS (المترجم والهندسة المعمارية للمعالجات المدمجة والمعالجات فائقة القياس)، وهو مشروع مشترك من INRIA و CNRS وجامعة رين 1 وINSA في رين.

مفهوم OpenHMPP

يعتمد OpenHMPP على مفهوم وحدات البرمجة، وهي وظائف يمكن تنفيذها عن بعد على أجهزة HWAs.

مفهوم وحدة الكود OpenHMPP

يحتوي الكود المصغر على الخصائص التالية:

  1. إنها دالة خالصة .
    • لا يحتوي على تعريفات متغيرات ثابتة أو متقلبة ولا يشير إلى أي متغيرات عامة إلا إذا تم تعريفها بواسطة توجيه HMPP "resident".
    • لا يحتوي على أي استدعاءات لدوال ذات جسم غير مرئي (لا يمكن تضمينها مباشرةً). ويشمل ذلك استخدام المكتبات ودوال النظام مثل malloc و printf، ...
    • يجب أن يشير كل استدعاء دالة إلى دالة نقية ثابتة (بدون مؤشرات دوال).
  2. لا تُرجع أي قيمة (دالة فارغة في لغة C أو روتين فرعي في لغة Fortran ).
  3. يجب أن يكون عدد الوسائط ثابتًا (أي لا يمكن أن تكون دالة متغيرة الوسائط كما هو الحال في stdarg.h في لغة C).
  4. إنها ليست عملية تكرارية.
  5. يفترض أن تكون معلمات هذا النظام غير متداخلة (انظر التداخل (الحوسبة) وتداخل المؤشرات ).
  6. لا يحتوي على توجيهات موقع الاستدعاء (أي RPC إلى جزء كود آخر) أو توجيهات HMPP أخرى.

تضمن هذه الخصائص إمكانية تنفيذ استدعاء الإجراء عن بُعد (RPC) الخاص بوحدة التعليمات البرمجية عن بُعد بواسطة جهاز HWA. ويمكن أن يكون هذا الاستدعاء وعمليات نقل البيانات المرتبطة به غير متزامنة.

استدعاءات الإجراءات البعيدة (RPCs) باستخدام الكود المصغر

يوفر HMPP استدعاء الإجراءات عن بعد المتزامن وغير المتزامن. ويعتمد تنفيذ العملية غير المتزامنة على الأجهزة.

بروتوكول RPC المتزامن مقابل بروتوكول RPC غير المتزامن

نموذج ذاكرة HMPP

يأخذ HMPP في الاعتبار مساحتين للعناوين: مساحة المعالج المضيف وذاكرة HWA.

نموذج ذاكرة HMPP

مفهوم التوجيهات

يمكن اعتبار توجيهات OpenHMPP بمثابة "معلومات وصفية" تُضاف إلى شفرة المصدر للتطبيق. وهي معلومات وصفية آمنة، أي أنها لا تُغير سلوك الشفرة الأصلية. وتتناول هذه التوجيهات التنفيذ عن بُعد (RPC) للدالة، بالإضافة إلى عمليات نقل البيانات من وإلى ذاكرة الأجهزة.

يُقدّم الجدول أدناه توجيهات OpenHMPP. تُلبّي توجيهات OpenHMPP احتياجاتٍ مُختلفة: بعضها مُخصّص للتصريحات، والبعض الآخر مُخصّص لإدارة التنفيذ.

تعليمات التحكم في التدفقتوجيهات إدارة البيانات
الإقراراتمجموعة التعليمات البرمجيةخريطة السكان mapbyname
التوجيهات التشغيليةمزامنة منطقة موقع الاتصالتخصيص إصدار التحميل المتقدم مخزن البيانات المفوض

مفهوم مجموعة التوجيهات

إحدى النقاط الأساسية في نهج HMPP هي مفهوم التوجيهات والعلامات المرتبطة بها، مما يجعل من الممكن عرض بنية متماسكة لمجموعة كاملة من التوجيهات المنتشرة في تطبيق ما.

هناك نوعان من الملصقات:

  • واحد مرتبط بوحدة كود. بشكل عام، تقتصر التوجيهات التي تحمل هذا النوع من التصنيفات على إدارة وحدة كود واحدة فقط (تسمى وحدة كود مستقلة في بقية المستند لتمييزها عن مجموعة وحدات الكود).
  • يُشار إلى هذه التصنيفات على النحو التالي: "<LabelOfGroup>"، حيث "LabelOfGroup" هو اسم يُحدده المستخدم. وبشكل عام، ترتبط التوجيهات التي تحمل تصنيفًا من هذا النوع بالمجموعة بأكملها. يُستخدم مفهوم المجموعة في فئة من المشكلات التي تتطلب إدارة مُحددة للبيانات في جميع أنحاء التطبيق لتحسين الأداء.

بناء جملة توجيهات OpenHMPP

من أجل تبسيط الرموز، سيتم استخدام التعبيرات النمطية لوصف بناء جملة توجيهات HMPP.

يُستخدم نظام الألوان الموضح أدناه لوصف توجيهات بناء الجملة:

  • الكلمات الرئيسية المحجوزة لبرنامج HMPP باللون الأخضر ؛
  • عناصر القواعد التي يمكن تصريفها في الكلمات الرئيسية لـ HMPP تظهر باللون الأحمر ؛
  • تظل متغيرات المستخدم باللون الأسود.

بناء الجملة العام

الصيغة العامة لتوجيهات OpenHMPP هي:

  • بالنسبة للغة C:
#pragma hmpp < grp_label > [codelet_label]? directive_type [ , directive_parameters ]* [ & ]
  • للغة فورتران:
!$hmpp < grp_label > [codelet_label]? directive_type [ , directive_parameters ]* [ & ]

أين:

  • <grp_label>: هو مُعرّف فريد يُشير إلى مجموعة من وحدات البرمجة. في حال عدم تعريف أي مجموعات في التطبيق، يُمكن حذف هذا المُعرّف. يجب أن يتبع اسم المُعرّف الصحيح القواعد النحوية التالية: [a-zA-Z_][a-zA-Z0-9_]*. لاحظ أن الرمزين "< >" جزء من الصيغة وهما إلزاميّان لهذا النوع من المُعرّفات.
  • codelet_label: هو مُعرّف فريد يُشير إلى جزء من الكود. يجب أن يتبع اسم التسمية القانونية هذه القواعد النحوية:[a-zA-Z_][a-zA-Z0-9_]*
  • directive: هو اسم التوجيه؛
  • directive_parameters: يشير إلى بعض المعلمات المرتبطة بالتوجيه. قد تكون هذه المعلمات من أنواع مختلفة وتحدد إما بعض الوسائط المقدمة للتوجيه أو طريقة التنفيذ (غير متزامن مقابل متزامن على سبيل المثال)؛
  • [&]: هو حرف يستخدم لمواصلة التوجيه في السطر التالي (نفس الشيء بالنسبة للغة C ولغة FORTRAN).

معلمات التوجيه

قد تكون المعلمات المرتبطة بتوجيه ما من أنواع مختلفة. فيما يلي معلمات التوجيه المحددة في OpenHMPP:

  • version = major.minor[.micro]: يحدد إصدار توجيهات HMPP التي يجب على المعالج المسبق مراعاتها.
  • args[arg_items].size={dimsize[,dimsize]*}: يحدد حجم المعامل غير القياسي (مصفوفة).
  • args[arg_items].io=[in|out|inout]يشير الرمز : إلى أن وسائط الدالة المحددة هي إما مدخلات أو مخرجات أو كليهما. افتراضيًا، تكون الوسائط غير المؤهلة مدخلات.
  • cond = "expr": يحدد شرط التنفيذ كتعبير منطقي بلغة C أو Fortran يجب أن يكون صحيحًا لبدء تنفيذ المجموعة أو الأجزاء البرمجية.
  • target=target_name[:target_name]*: يحدد الأهداف التي يجب محاولة استخدامها بالترتيب المحدد.
  • asynchronous: يحدد أن تنفيذ الكود الصغير ليس حظرًا (الافتراضي متزامن).
  • args[<arg_items>].advancedload=trueيشير الرمز : إلى أن المعلمات المحددة مُحمّلة مسبقًا. لا يمكن تحميل سوى معلمات الإدخال أو الإدخال/الإخراج مسبقًا.
  • args[arg_items].noupdate=trueتُحدد هذه الخاصية أن البيانات متوفرة بالفعل على جهاز HWA، وبالتالي لا حاجة لنقلها. عند تعيين هذه الخاصية، لا يتم إجراء أي نقل على الوسيط المُحدد.
  • args[<arg_items>].addr="<expr>": <expr>هو تعبير يعطي عنوان البيانات المراد تحميلها.
  • args[<arg_items>].const=trueيشير الرمز : إلى أنه سيتم تحميل الوسيط مرة واحدة فقط.

توجيهات OpenHMPP

توجيهات لإعلان وتنفيذ جزء من التعليمات البرمجية

يُعلن التوجيه codeletعن تنفيذ عملية حسابية عن بُعد على مُسرِّع أجهزة. بالنسبة codeletللتوجيه:

  • يُعدّ رمز التعريف (codelet label) إلزاميًا ويجب أن يكون فريدًا في التطبيق.
  • لا يلزم تحديد اسم المجموعة إذا لم يتم تعريف أي مجموعة.
  • يتم إدراج توجيه الكود الصغير قبل تعريف الدالة مباشرة.

صيغة التوجيه هي:

#pragma hmpp < grp_label > codelet_label codelet [ , version = Major.minor[.micro]?]؟ [ , args[ arg_items ].io= [[ in | out | inout ]]* [ , args[ arg_items ].size={ dimsize[,dimsize]* } ]* [ , args[ arg_items ].const=true ]* [ , cond = "expr"] [ , target= target_name [: target_name ]*]

يمكن إضافة أكثر من توجيه كود برمجي إلى دالة لتحديد استخدامات مختلفة أو سياقات تنفيذ مختلفة. مع ذلك، لا يمكن أن يكون هناك سوى توجيه كود برمجي واحد لكل تسمية موقع استدعاء معينة.

يحدد التوجيه callsiteكيفية استخدام جزء من التعليمات البرمجية في نقطة معينة من البرنامج.

صيغة التوجيه هي:

#pragma hmpp < grp_label > codelet_label callsite [ , asynchronous ]? [ , args[ arg_items ].size={ dimsize[,dimsize]* } ]* [ , args[ arg_items ].advancedload= [[ true | false ]]* [ , args[ arg_items ].addr=" expr " ]* [ , args[ arg_items ].noupdate=true ]*

يُعرض هنا مثال على ذلك  :

/* تعريف الكود المصغر */ #pragma hmpp simple1 codelet, args[outv].io=inout, target=CUDA static void matvec ( int sn , int sm , float inv [ sm ], float inm [ sn ][ sm ], float * outv ){ int i , j ; for ( i = 0 ; i < sm ; i ++ ) { float temp = outv [ i ]; for ( j = 0 ; j < sn ; j ++ ) { temp += inv [ j ] * inm [ i ][ j ]; } outv [ i ] = temp ; } int main ( int argc , char ** argv ) { int n ; ........ /* استخدام الكوديت */ #pragma hmpp simple1 callsite, args[outv].size={n} matvec ( n , m , myinc , inm , myoutv ); ........ }

في بعض الحالات، يلزم إدارة محددة للبيانات في جميع أنحاء التطبيق (تحسين حركة بيانات وحدة المعالجة المركزية/وحدة معالجة الرسومات، والمتغيرات المشتركة ...).

يُتيح هذا groupالتوجيه تعريف مجموعة من وحدات الكود. تُطبَّق المعاملات المُحدَّدة في هذا التوجيه على جميع وحدات الكود التابعة للمجموعة. صيغة التوجيه هي:

#pragma hmpp < grp_label > group [ , version = <major>.<minor>[.<micro>]?]? [ , target = target_name [: target_name ]*]]? [ , cond = “ expr  ]?

توجيهات نقل البيانات لتحسين تكاليف الاتصال

عند استخدام وحدة معالجة الأجهزة (HWA)، غالبًا ما تكون عملية نقل البيانات بين وحدة المعالجة والمعالج الرئيسي هي العائق الرئيسي. وللحد من عبء الاتصال، يمكن تداخل عمليات نقل البيانات مع عمليات التنفيذ المتتالية لنفس الجزء البرمجي باستخدام خاصية عدم التزامن في وحدة المعالجة.

  • توجيه التخصيص

يقوم التوجيه allocateبقفل وحدة الأجهزة (HWA) وتخصيص مقدار الذاكرة اللازم.

#pragma hmpp < grp_label > allocate [ ,args[ arg_items ].size={ dimsize[,dimsize]* } ]*
  • توجيهات الإفراج

يحدد التوجيه releaseمتى يتم إصدار HWA لمجموعة أو لوحدة برمجية مستقلة.

#pragma hmpp < grp_label > release
  • توجيه التحميل المتقدم

يقوم التوجيه advancedloadبجلب البيانات مسبقًا قبل التنفيذ البعيد للوحدة البرمجية.

#pragma hmpp < grp_label > [codelet_label]? advancedload ,args[ arg_items ] [ ,args[ arg_items ].size={ dimsize[,dimsize]* } ]* [ ,args[ arg_items ].addr=" expr " ]* [ ,args[ arg_items ].section={ [ subscript_triplet , ]+ } ]* [ ،غير متزامن ]
  • توجيه المتجر المفوض

التوجيه delegatedstoreعبارة عن حاجز تزامن لانتظار اكتمال تنفيذ الكود غير المتزامن ثم تنزيل النتائج.

#pragma hmpp < grp_label > [codelet_label]؟ متجر مفوض ,args[ arg_items ] [ ,args[ arg_items ].addr=" expr " ]* [ ,args[ arg_items ].section={ [ subscript_triplet , ]+ } ]*
  • الحسابات غير المتزامنة

يُحدد هذا synchronizeالتوجيه الانتظار حتى اكتمال تنفيذ موقع الاستدعاء غير المتزامن. بالنسبة لتوجيه التزامن، يكون تصنيف الكود الصغير إلزاميًا دائمًا، كما أن تصنيف المجموعة مطلوب إذا كان الكود الصغير ينتمي إلى مجموعة.

#pragma hmpp < grp_label > مزامنة codelet_label
  • مثال

في المثال التالي، يتم تهيئة الجهاز وتخصيص الذاكرة وتحميل بيانات الإدخال مرة واحدة فقط خارج الحلقة وليس في كل تكرار للحلقة.

يسمح هذا synchronizeالتوجيه بالانتظار حتى يكتمل التنفيذ غير المتزامن للوحدة البرمجية قبل بدء تكرار آخر. وأخيرًا، delegatedstoreيقوم التوجيه الموجود خارج الحلقة بتحميل نتيجة sgemm.

int main ( int argc , char ** argv ) { #pragma hmpp sgemm allocate, args[vin1;vin2;vout].size={size,size} #pragma hmpp sgemm advancedload, args[vin1;vin2;vout], args[m,n,k,alpha,beta] for ( j = 0 ; j < 2 ; j ++ ) { #pragma hmpp sgemm callsite, asynchronous, args[vin1;vin2;vout].advancedload=true, args[m,n,k,alpha,beta].advancedload=true sgemm ( size , size , size , alpha , vin1 , vin2 , beta , vout ); #pragma hmpp sgemm synchronize } #pragma hmpp sgemm delegatedstore, args[vout] #pragma hmpp sgemm release

مشاركة البيانات بين أجزاء الكود

تقوم هذه التوجيهات بربط جميع الوسائط التي تشترك في الاسم المحدد لجميع المجموعات.

يجب أن تكون أنواع وأبعاد جميع الوسائط المُعينة متطابقة.

يقوم التوجيه mapبتعيين عدة وسائط على الجهاز.

#pragma hmpp < grp_label > الخريطة، args[ arg_items ]

هذا التوجيه مشابه تمامًا للتوجيه mapالسابق، باستثناء أن الوسائط المراد ربطها تُحدد مباشرةً بأسمائها. هذا mapbynameالتوجيه يُعادل عدة mapتوجيهات.

#pragma hmpp < grp_label > mapbyname [ , variableName]+

متغير عالمي

يُعرّف هذا residentالتوجيه بعض المتغيرات كمتغيرات عامة ضمن مجموعة. ويمكن الوصول إلى هذه المتغيرات مباشرةً من أي جزء من التعليمات البرمجية ينتمي إلى المجموعة. وينطبق هذا التوجيه على عبارة التعريف التي تليه مباشرةً في التعليمات البرمجية المصدرية.

صيغة هذا التوجيه هي:

#pragma hmpp < grp_label > resident [ , args[:: var_name ].io= [[ in | out | inout ]]* [ , args[:: var_name ].size={ dimsize[,dimsize]* } ]* [ , args[:: var_name ].addr=" expr " ]* [ , args[:: var_name ].const=true ]*

يشير الرمز ::var_name الذي يبدأ بالبادئة ::إلى متغير التطبيق المعلن عنه كمتغير مقيم.

تسريع المناطق

المنطقة هي دمج لتوجيهات الكود المصغر/موقع الاستدعاء. والهدف هو تجنب إعادة هيكلة الكود لإنشاء الكود المصغر. لذلك، يمكن استخدام جميع السمات المتاحة لتوجيهات codeletأو على التوجيهات.callsiteregions

بلغة سي:

#pragma hmpp [< MyGroup >] [ label ] region [ , args[ arg_items ].io= [[ in | out | inout ]]* [ , cond = " expr "] < [ , args[ arg_items ].const=true ]* [ , target= target_name [ : target_name ]*] [ , args[ arg_items ].size={ dimsize[ , dimsize]* } ]* [ , args[ arg_items ].advancedload= [[ true | false ]]* [ , args[ arg_items ].addr=" expr " ]* [ , args[ arg_items ].noupdate=true ]* [ ، غير متزامن ]؟ [ , private=[ arg_items ] ]* { بيانات الكتلة ج }

التطبيقات

يعتمد معيار OpenHMPP المفتوح على الإصدار 2.3 من HMPP (مايو 2009، CAPS entreprise).

يتم تطبيق نموذج البرمجة القائم على التوجيهات في OpenHMPP في:

  • مُجمّعات CAPS، مُجمّعات CAPS Enterprise للحوسبة الهجينة
  • مجموعة برامج PathScale ENZO Compiler Suite (تدعم وحدات معالجة الرسومات NVIDIA)

يستخدم OpenHMPP من قبل الجهات الفاعلة في مجال الحوسبة عالية الأداء في قطاعات النفط والغاز والطاقة والتصنيع والتمويل والتعليم والبحث.

انظر أيضاً

مراجع

  1. دولبو، رومان؛ بيهان، ستيفان؛ بودان، فرانسوا (4 أكتوبر 2007). HMPP: بيئة برمجة متوازية هجينة متعددة النوى (ملف PDF) . ورشة عمل حول المعالجة للأغراض العامة على وحدات معالجة الرسومات . مؤرشف من الأصل (ملف PDF) في 16 يناير 2014. تم الاطلاع عليه في 14 يناير 2014 .