اعتبارات الأداء للتوافق (C++)

يوفر هذا الموضوع إرشادات لتقليل تأثير انتقالات التوافق المُدار/غير المُدار أو أداء وقت التشغيل.

يدعم ++Visual C نفس آليات إمكانية التشغيل التفاعلي التى تدعمها لغات .NET الأخرى مثل Visual Basic و C# (P/Invoke) ، ولكن أيضاً توفر دعم التوافق الخاص بـ Visual C++ (interop C++). بالنسبة للتطبيقات التى يكون الأداء فيها عنصرا محوريا، فإنه من المهم فهم التأثير على الأداء لكل أسلوب توافق.

بغض النظر عن تقنية التوافق المستخدمة , تطلب تسلسلات انتقال خاصة , تسمى thunks فى كل مرة تستدعى فيها الدالة المدارة دالة غير مدارة والعكس بالعكس. يتم إدراج thunks هذه تلقائياً عن طريق برنامج التحويل البرمجي لـ ++Visual C ولكن المهم أن تتذكر أنه بشكل تراكمى ، هذه الانتقالات يمكن أن تكون مكلفة بالنسبة للأداء.

تقليل الانتقالات

أحد طرق تجنب أو تقليل تكلفة "thunks التوافق" هو إعادة بناء التعليمات البرمجية الخاصة بالواجهات المتضمنة لتقليل الانتقالات بين المُدار/غير المُدار. يمكن تحسين الاداء بشكل مثير عن طريق استهداف واجهات مُحَدِّثة (chatty) ،و هي تلك التي تتضمن استدعاءات متكررة عبر الحدود المُدارة/ الغير مُدارة. الدالة المدارة التى تستدعي دالة غير مدارة في حلقة مشدودة، على سبيل المثال، هى مُرَشح جيد لإعادة بناء التعليمات البرمجية. إذا تم نقل الحلقة نفسها إلى الجانب الغير المُدار أو إذا تم إنشاء مدار بديل عن استدعاء غير مدار (ربما بوضع البيانات فى قائمة انتظار على الجانب المدار ثم تنظيمها و إرسالها إلى API الغير المدار مرة واحدة بعد الحلقة) ، يمكن تقليل عدد الانتقالات بشكل ملحوظ.

أو P/Invoke.C++ Interop

بالنسبة للغات .NET مثل Visual Basic و C# ، الأسلوب الموصوف للتوافق مع المكونات الأصلية هو P/Invoke. لأن P/Invoke معتمد من قبل .NET Framework و أيضاً من قبل ++Visual C ، ولكن ++Visual C توفر دعم التوافق الخاص بها الذي يشار إليه بـ " C++ Interop" أو توافق C++ . توافق C++ يُفضل عن P/Invoke لأن P/Invoke ليس آمانا من جهة النوع. نتيجة لذلك ، يتم الإعلان عن أخطاء بشكل أساسي و قت التشغيل ولكن C++ Interop أيضاً له ميزات أداء عن P/Invoke.

تتطلب كلا التقنيات العديد من الأشياء يتم تنفيذها كلما استدعت الدالة المدارة دالة غير مدارة :

  • يتم تنظيم و إرسال وسيطات استدعاء الدالة من CLR إلى أنواع أصلية.

  • يتم تنفيذ تعليمة برمجية للتحويل من المدار إلى الغير مدار.

  • الدالة الغير مدارة يتم استدعاؤها (باستخدام الإصدارات الأصلية من الوسيطات).

  • يتم تنفيذ تعليمة برمجية للتحويل من المدار إلى الغير مدار.

  • نوع الإرجاع و أي وسائط "خارج" أو "خارج,داخل" يتم تنظيمها و إرسالها من الأنواع الأصلية إلى CLR .

تعليمة برمجية للتحويل بين المُدارة/غير المدارة تكون ضرورية للتوافق لتعمل مطلقاً، و لكن تنظيم و إرسال البيانات المطلوب يعتمد على أنواع البيانات المتضمنة ، و توقيع الدالات و كيفية استخدام البيانات.

تنظيم و إرسال البيانات الذى تم عن طريق ++Interop C هو أبسط نموذج ممكن: يتم نسخ المعلمات ببساطة عبر الحدود المُدارة/غير المُدارة بأسلوب أحادي المعامل; لا يتم تنفيذ أى تحويل إطلاقا. بالنسبة لـ P/Invoke، هذا صحيح فقط إذا كانت كل المعلمات بسيطة، أو من أنواع مشتركة. وبخلاف ذلك، يقوم P/Invoke بتنفيذ خطوات قوية جدًا لتحويل كل معلمة مدارة إلى النوع الأصلي المناسب، و العكس بالعكس إذا تم وضع علامة على الوسائط كـ "خارج" أو "خارج,داخل".

بمعنى آخر، C++ Interop يستخدم أسرع أسلوب ممكن لتنظيم و إرسال البيانات بينما يستخدم P/Invoke الأسلوب الأكثر فعالية. هذا يعني أن C++ Interop (بأسلوب نموذجى ل++C) يوفر الأداء الأمثل بشكل افتراضي، و يكون المبرمج مسؤولاً عن عنونة الحالات حيث يكون هذا السلوك غير آمن أو مناسب.

ولذلك C++ Interop يتطلب أن توفير تنظيم و إرسال البيانات بشكل صريح و لكن الميزة هى أن المبرمج حر ليقرر ما هو المناسب، مع كون طبيعة البيانات ، و كيفية استخدامها معطاة. علاوة على ذلك، بالرغم من أنه يمكن تعديل سلوك تنظيم البيانات P/Invoke إلى مخصصة نسبيا ، إلا أن C++ Interop تسمح بتخصيص تنظيم و إرسال البيانات على أساس استدعاء باستدعاء. هذا غير ممكن مع P/Invoke.

لمزيد من المعلومات حول C++ Interop, انظراستخدام PInvoke) C++ Interop الضمني ).

راجع أيضًا:

المبادئ

تجميعات مختلطة (أصلية و مدارة)