C ++ روسيا بيتر 2019 تقارير الاستعراض

في برنامج ماجستير ITMO و JetBrains المشترك ، نطلب من الطلاب الذين يتم إرسالهم إلى المؤتمر كتابة تقرير مع مراجعة التقارير.
ننشر أحد هذه التقارير حول مؤتمر C ++ Russia Piter 2019. المؤلف هو طالب السنة الثانية أرتيوم خوروشيف.



في أوائل نوفمبر ، حضرت مؤتمر cpp-russia-piter ، أدناه سأتحدث عن التقارير التي أتذكرها.

رومان روسييف: استثناءات C ++ من خلال منظور تحسينات برنامج التحويل البرمجي


تقرير مثير للاهتمام تحدث فيه المتحدث عن مثال LLVM عن استثناءات التكلفة الصفرية في C ++ الحديثة.

يقدم LLVM IR البرنامج كرسومات التحكم في التدفق. في العقد من الرسم البياني هي كتل من التعليمات التي يجب اتباعها. في نهاية كل كتلة ، يوجد فاصل ينقل التحكم إلى الكتلة التالية. يمكن أن يكون المُنهي عبارة عن انتقال مشروط إلى كتلة أخرى ، أو تعليمة إرجاع ، أو تعليمة استدعاء خاصة ، والتي لها دلالات في استدعاء الوظيفة ، وإذا نجحت ، تقوم بنقل تدفق التحكم إلى كتلة واحدة ، وفي حالة وجود استثناء ، تشير إلى الكتلة التي تريد معالجتها. تحتوي الإرشادات الموجودة داخل كتلة ما على خاصية أننا إذا وصلنا إلى كتلة ، فسوف ننفذ جميع التعليمات ، أو لن نقع في هذه الكتلة على الإطلاق. هناك تحسينات يمكن أن تعمل فقط ضمن كتلة واحدة. في حالة القطع الصغيرة ، سيكون لها سياق أصغر ، ونتيجة لذلك من الأسوأ إجراء تحسينات.
تحدث المتحدث عن كيفية قيام المحول البرمجي الحديث بتحويل بيانات الاستدعاء إلى بيانات الاتصال ، والتي لم تعد نهائية ، وبالتالي ، يعطي المحول البرمجي مساحة أكبر للتحسينات. ولكن ، حتى لا تعتمد على برنامج التحويل البرمجي ، يمكنك كتابة وظيفة noexcept بنفسك (إذا كان هذا صحيحًا) للتأكد من أن برنامج التحويل البرمجي سينفذ جميع التحسينات.

(شرائح التقرير)

مكسيم Khizhinsky: السكن من الدرجة الراحة للجهات الفاعلة والمعالجات


حدد المتحدث هدفًا للتخلص من عدد من المشكلات المرتبطة بالبرمجة الموازية:

  • البيانات المشتركة
  • تبديل السياق ،
  • مزامنة،
  • إنشاء متكرر للتدفق على الطيران لتلبية الاحتياجات على المدى القصير.

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

(شرائح التقرير)

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


الاسم يتحدث عن نفسه. أخبر المتحدث كيف قاموا بزيادة أداء النظام بشكل كبير باستخدام أداة تخصيص الألواح . يعمل مخصص البلاطات على عدة كيانات:

  • الألواح عبارة عن قطعة متجاورة من الذاكرة (عادةً ما تكون بحجم ثابت) يتم تقسيمها إلى أقسام من نفس الحجم. تستخدم هذه المناطق لتخزين الكائنات من نفس الحجم ،
  • ذاكرة التخزين المؤقت - قائمة الألواح مع نفس الانقسام ،
  • مخصص بلاطة - مجموعة من ذاكرات التخزين المؤقت.

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

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

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

(شرائح التقرير)

انطون Polukhin: جيم + تاكسي الخدع


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

// Foo.h struct Foo { Foo(); private: struct Foo_impl; //forward declaration std::unique_ptr<Foo_impl> impl; }; // Foo.cpp //implementation struct Foo::Foo_impl { }; 

نريد التخلص من التخصيص الديناميكي ، لذلك سنقوم بإعداد مكان مقدمًا مباشرةً في كائن Foo:
 // Foo.h struct Foo { Foo(); private: struct Foo_impl; //forward declaration std::aligned_storage_t<sizeof(Foo_impl), alignof(Foo_impl)> impl; }; // Foo.cpp //implementation struct Foo::Foo_impl { } 

لن تنجح هذه الطريقة ، لأنه ليس لدينا معلومات كاملة عن النوع Foo_impl في Foo.h وسيتم تلقي خطأ في الترجمة. الحل الوحيد المتبقي هو تخمين حجم التخزين مسبقًا.

 // Foo.h struct Foo { Foo(); private: struct Foo_impl; //forward declaration constexpr std::size_t kImplSize = 32; constexpr std::size_t kImplAlign = 8; std::aligned_storage_t<kImplSize, kImplAlign> impl; }; // Foo.cpp //implementation struct Foo::Foo_impl { } 

لكنك تحتاج إلى إضافة التحقق من أن الحجم لا يزال صحيحًا. يعد ذلك ضروريًا ، لأن محاولة وضع الكائن في مخزن مؤقت غير مناسب هو UB.

 // Foo.h struct Foo { Foo(); ~Foo(); private: constexpr std::size_t kImplSize = 32; constexpr std::size_t kImplAlign = 8; struct Foo_impl; //forward declaration std::aligned_storage_t<kImplSize, kImplAlign> impl; }; // Foo.cpp //implementation struct Foo::Foo_impl { } struct Foo::~Foo() { static_assert(kImplSize==sizeof(Foo_impl),"Size and sizeof(T) mismatch"); static_assert(kImplAlign==alignof(kImplAlign),"Alignment and alignof(T) mismatch"); // call destructor of Foo_impl } 

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

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

(شرائح التقرير)

إريك نيبلر: تجريد موحد للتزامن في C ++


تقرير مثير للاهتمام يناقش مشاكل التجريدات غير المتزامنة في المعيار اللغوي الحالي: لماذا يكون المستقبل والوعد بطيئين ، وما إذا كنا نستطيع تصميم المكتبة بطريقة تتجنب هذه النفقات العامة. يبدو أن مطوري Facebook لديهم حل لائق https://github.com/facebookexperimental/libunifex

(شرائح التقرير)

دميتري كوزيفنيكوف وأندريه دافيدوف: تقريران عن الوحدات


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

(شرائح التقارير: 1 ، 2 )

استنتاج


كان المؤتمر السابق مسروراً بأمثلة شيقة لاستخدام ميزات معروفة للغة. كان هناك عدد كبير من التقارير حول الرقائق من المعيار التالي - C ++ 20. هذا ، بالطبع ، مفيد للغاية لجميع مطوري C ++.

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


All Articles