SIMD التمديد إلى C ++ OpenMP في Visual Studio

في عصر تطبيقات الذكاء الاصطناعي في كل مكان ، هناك طلب ناشئ على كود التعلم الآلي المكثف للحوسبة المترجم للأجهزة الحالية. عادةً ما يقوم هذا الكود بالحساب الرياضي مثل تحويل المصفوفة والتلاعب ، ويكون عادةً في شكل حلقات. يوفر امتداد SIMD لبرنامج OpenMP للمستخدمين طريقة سهلة لإسراع الحلقات من خلال الاستفادة بوضوح من وحدة مكافحة ناقلات المعالجات الحديثة. نحن فخورون ببدء تقديم ناقل C / C ++ OpenMP SIMD في Visual Studio 2019.


تم تصميم واجهة برنامج تطبيق OpenMP C / C ++ في الأصل لتحسين أداء التطبيق من خلال تمكين تنفيذ التعليمات البرمجية بشكل فعال بالتوازي على معالجات متعددة في التسعينيات. على مر السنين ، تم توسيع معيار OpenMP لدعم المفاهيم الإضافية مثل التوازي القائم على المهام ، وتوجه SIMD ، وتفريغ المعالج. منذ عام 2005 ، دعم Visual Studio المعيار OpenMP 2.0 الذي يركز على التوازي متعدد مؤشرات الترابط. بينما ينتقل العالم إلى عصر الذكاء الاصطناعى ، نرى فرصة متزايدة لتحسين جودة الكود من خلال توسيع دعم معيار OpenMP في Visual Studio. نواصل رحلتنا في Visual Studio 2019 بإضافة الدعم لـ OpenMP SIMD.




OpenMP SIMD ، الذي تم تقديمه لأول مرة في معيار OpenMP 4.0 ، يستهدف بشكل رئيسي توجيه الحلقات. إنها حتى الآن أكثر ميزات OpenMP استخدامًا في التعلم الآلي وفقًا لبحثنا. من خلال إضافة تعليق توضيحي إلى حلقة بتوجيه OpenMP SIMD ، يمكن للمترجم أن يتجاهل تبعيات المتجه ويوجه الحلقة إلى أقصى حد ممكن. يحترم المترجم نية المستخدمين لتنفيذ تكرارات متعددة للحلقات في وقت واحد.


#pragma omp simd for (i = 0; i < count; i++) { a[i] = b[i] + 1; } 

كما تعلم ، فإن C ++ في Visual Studio يوفر بالفعل نسخًا متشابهة غير متقطعة من حلقات OpenMP مثل #pragma vector و # pragma ivdep . ومع ذلك ، يمكن للمترجم أن يفعل المزيد باستخدام OpenMP SIMD. على سبيل المثال:


  1. يسمح للمترجم دائمًا بتجاهل أي تبعيات متجهة موجودة.
  2. / fp: يتم تمكين سريع داخل الحلقة.
  3. الحلقات مع استدعاءات الوظائف هي vectorizable.
  4. الحلقات الخارجية هي vectorizable.
  5. يمكن دمج الحلقات المتداخلة في حلقة واحدة وتوجيهها.
  6. يمكن تحقيق التسارع الهجين مع #pragma omp لـ simd لتمكين تعدد مؤشرات الحبيبات الخشنة وتوجه الحبيبات الدقيقة.

بالإضافة إلى ذلك ، يمكن أن يتبع توجيه OpenMP SIMD البنود التالية لزيادة تحسين الاتجاه:


  • simdlen ( الطول ): حدد عدد ممرات المتجهات
  • safelen ( الطول ): تحديد المسافة التبعية ناقلات
  • خطي ( قائمة [ : خطية خطوة] ): رسم الخرائط الخطية من متغير الحث حلقة إلى الاشتراك صفيف
  • محاذاة ( قائمة [ : المحاذاة] ): محاذاة البيانات
  • خاص ( قائمة ): تحديد خصخصة البيانات
  • lastprivate ( قائمة ): تحديد خصخصة البيانات مع القيمة النهائية من التكرار الأخير
  • التخفيض ( معرف التخفيض : قائمة ): تحديد عمليات التخفيض المخصصة
  • انهيار ( ن ): حلقة حلقة التحالف

جديد -فتح: التبديل التجريبي


يمكن تجميع برنامج توضيحي لبرنامج OpenMP-SIMD باستخدام مفتاح CL جديد مفتوح: تجريبي. يعمل هذا المحول الجديد على تمكين ميزات OpenMP الإضافية غير المتاحة أسفل- فتح . على الرغم من أن اسم رمز التبديل هذا "تجريبي" ، فإن المحول نفسه والوظائف التي يدعمها مدعومة تمامًا وجاهزة للإنتاج. يعكس الاسم أنه لا يمكّن أي مجموعة فرعية أو إصدار كامل من معيار OpenMP. التكرار في المستقبل من المحول البرمجي قد تستخدم رمز التبديل هذا لتمكين ميزات OpenMP إضافية ويمكن إضافة رموز تبديل OpenMP جديدة. -openmp: التبديل التجريبي يستوعب رمز التبديل -openmp مما يعني أنه متوافق مع جميع ميزات OpenMP 2.0. لاحظ أنه لا يمكن ترجمة توجيه SIMD وعباراته باستخدام مفتاح التبديل -openmp .


بالنسبة للحلقات التي لا يتم توجيهها ، سيصدر المترجم رسالة لكل منها على النحو التالي. على سبيل المثال ،


cl -O2 -openmp: mycode.cpp التجريبية


mycode.cpp (84): info C5002: حلقة Omp simd غير متجهة بسبب السبب "1200"


mycode.cpp (90): info C5002: حلقة Omp simd غير متجهة بسبب السبب "1200"


بالنسبة إلى الحلقات التي يتم توجيهها ، يبقى المحول البرمجي صامتًا ما لم يتم توفير مفتاح تسجيل تسجيل vectorization:


cl -O2 -openmp: التجريبية -Qvec- التقرير: 2 mycode.cpp


mycode.cpp (84): info C5002: حلقة Omp simd غير متجهة بسبب السبب "1200"


mycode.cpp (90): info C5002: حلقة Omp simd غير متجهة بسبب السبب "1200"


mycode.cpp (96): info C5001: Omp simd loctorized


كخطوة أولى لدعم OpenMP SIMD ، قمنا بشكل أساسي بتوصيل براغمات SIMD مع متجه الواجهة الخلفية تحت المحول الجديد. ركزنا على vectorizing الحلقات الأعمق عن طريق تحسين ناقلات وتحليل الاسم المستعار. أي من الجمل SIMD فعالة في Visual Studio 2019 في وقت كتابة هذا التقرير. سيتم تحليلها ولكن يتم تجاهلها من قبل المترجم مع تحذير صدر لوعي المستخدم. على سبيل المثال ، سوف يصدر برنامج التحويل البرمجي


تحذير C4849: تم تجاهل جملة "simdlen" لـ OpenMP في توجيه "simd"


للرمز التالي:


 #pragma omp simd simdlen(8) for (i = 1; i < count; i++) { a[i] = a[i-1] + 1; b[i] = *c + 1; bar(i); } 

المزيد عن دلالات توجيه OpenMP SIMD


يوفر توجيه OpenMP SIMD للمستخدمين طريقة لإملاء برنامج التحويل البرمجي لتوجيه حلقة. يُسمح للمترجم بتجاهل الشرعية الظاهرة لمثل هذا الاتجاه عن طريق قبول وعد المستخدمين بالصحة. تقع على عاتق المستخدمين مسؤولية عندما يحدث سلوك غير متوقع مع vectorization. من خلال التعليق التوضيحي على حلقة بتوجيه OpenMP SIMD ، ينوي المستخدمون تنفيذ تكرارات متعددة للحلقات في وقت واحد. هذا يمنح المترجم الكثير من الحرية لإنشاء رمز الجهاز الذي يستفيد من موارد SIMD أو المتجهات على المعالج الهدف. في حين أن المترجم غير مسؤول عن استكشاف صحة وأرباح مثل هذه التوازي المحدد من قبل المستخدم ، فإنه يجب أن يضمن السلوك المتسلسل لتكرار حلقة واحدة.


على سبيل المثال ، يتم شرح الحلقة التالية بتوجيه OpenMP SIMD. لا يوجد توازي تام بين التكرارات الحلقية نظرًا لوجود تبعية متخلفة من [i] إلى [i-1]. ولكن نظرًا لتوجيهات SIMD ، لا يزال يُسمح للمترجم بتجميع التكرارات المتتالية للبيان الأول في تعليمة متجه واحد وتشغيلها على التوازي.


 #pragma omp simd for (i = 1; i < count; i++) { a[i] = a[i-1] + 1; b[i] = *c + 1; bar(i); } 

لذلك ، يعد الشكل المتجه المحول التالي للحلقة قانونيًا لأن المحول البرمجي يحتفظ بالسلوك المتسلسل لكل تكرار حلقة الأصلي. بمعنى آخر ، يتم تنفيذ [i] بعد [-1] ، ب [i] بعد [i] وتحدث الدعوة إلى الحظر أخيرًا.


 #pragma omp simd for (i = 1; i < count; i+=4) { a[i:i+3] = a[i-1:i+2] + 1; b[i:i+3] = *c + 1; bar(i); bar(i+1); bar(i+2); bar(i+3); } 

من غير القانوني نقل مرجع الذاكرة * c من الحلقة إذا كان قد يكون اسمًا مستعارًا باستخدام [i] أو b [i] . من غير القانوني أيضًا إعادة ترتيب العبارات داخل تكرار أصلي واحد في حالة كسر التبعية المتسلسلة. كمثال ، الحلقة المحولة التالية غير قانونية.


 c = b; t = *c; #pragma omp simd for (i = 1; i < count; i+=4) { a[i:i+3] = a[i-1:i+2] + 1; bar(i); // illegal to reorder if bar[i] depends on b[i] b[i:i+3] = t + 1; // illegal to move *c out of the loop bar(i+1); bar(i+2); bar(i+3); } 

الخطط المستقبلية والتغذية الراجعة


نحن نشجعك على تجربة هذه الميزة الجديدة. كما هو الحال دائمًا ، نرحب بتعليقاتك. إذا رأيت حلقة SIMD لبرنامج OpenMP تتوقع أن تكون متجهة ، ولكن لا توجد أو أن الكود الذي تم إنشاؤه ليس هو الأمثل ، يرجى إعلامنا. يمكن الوصول إلينا عبر التعليقات أدناه ، أو عبر البريد الإلكتروني ( visualcpp@microsoft.com ) ، أو twitter (visualc) ، أو عبر مجتمع Developer .


للمضي قدمًا ، نود أن نسمع حاجتك إلى وظائف OpenMP المفقودة في Visual Studio. نظرًا لوجود العديد من التطورات الرئيسية في OpenMP منذ الإصدار 2.0 ، أصبح لدى OpenMP الآن ميزات هائلة لتخفيف جهدك في إنشاء برامج عالية الأداء. على سبيل المثال ، تتوفر برمجة التزامن القائمة على المهام بدءًا من OpenMP 3.0. الحوسبة غير المتجانسة (مسرعات CPU +) مدعومة في OpenMP 4.0. تتوفر أيضًا معاملات SIMD المتقدمة ودعم موازاة حلقة DOACROSS في أحدث معيار OpenMP الآن. يرجى مراجعة المراجعات القياسية الكاملة ومجموعات الميزات من الموقع الرسمي OpenMP: https://www.openmp.org . نطلب بإخلاص أفكارك بشأن ميزات OpenMP المحددة التي تود رؤيتها. نحن مهتمون أيضًا بمعرفة كيفية استخدامك لبرنامج OpenMP لتسريع التعليمات البرمجية الخاصة بك. تعد تعليقاتك مهمة للغاية لأنها ستساعد في توجيه اتجاه دعم OpenMP في Visual Studio.


الصورة الرمزية
هونغ تاو يو

Source: https://habr.com/ru/post/ar446688/


All Articles