ترجمة منشور Titus Winters في مجموعة العمل 21 (WG21) - لجنة توحيد اللغة C ++. يناقش المؤلف مشكلة مهمة: دعم التوافق الثنائي المتخلف أو ABI (واجهة التطبيق الثنائية).
خلال السنوات الماضية في WG21 ، شجعت بنشاط أن التقدم أكثر أهمية من التوافق مع الإصدارات السابقة. لكنني نفسي لم أعد أؤمن بهذا ، خاصة فيما يتعلق بالحفاظ على التوافق الثنائي (ABI). في الإصدارات الثلاثة الأخيرة (C ++ 14 و C ++ 17 و C ++ 20) ، كان ABI مستقراً كما كنا قادرين على ذلك. حتى إذا قررت WG21 كسر التوافق العكسي لـ ABI في الإصدار C ++ 23 ، فإننا نقدم التوافق الثنائي على العديد من المنصات لأكثر من 10 سنوات. في رأيي ، يهيمن قانون Hyrum على التعديلات واسعة النطاق لأنظمة البرمجيات. الآن لا يمكنك معرفة عدد المستخدمين الذين يفترضون استقرار المكتبة القياسية لـ ABI (بغض النظر عن مدى الحكمة أو الصراحة أو الضمنية) بحزم "في القشرة الفرعية" ، ربما نصف مطوري C ++ في العالم.
أحتفظ بقائمة بما يمكن لـ WG21 إصلاحه في اللغة إذا قررنا "كسر" ABI. ولا يمكنني القول بثقة أن التكلفة الإجمالية لإعادة صياغة العمل ، والتي ستستلزم تنفيذ هذه القائمة فقط ، يمكن مقارنتها بتكلفة انتهاك ABI عبر النظام البيئي. لقد رأينا العديد من التحسينات الصغيرة في تناسق واجهة برمجة التطبيقات ، وجودة رمز المكتبة القياسية ، وما إلى ذلك ، ولكن بدون شك ، لا يوجد تغيير "اختراق" واحد يبرر هذه التكلفة بالنسبة للمطور العادي. ربما نحصل على تطبيقات أفضل للمعيار ، ونمنح فرصة لحل المشكلات الخاصة بالتطبيقات التي لا تتوافق مع المواصفات القياسية اليوم. ولكن ليس هناك تحسن واحد على قائمتي يستحق التكلفة بوضوح.
الأهم من ذلك ، بسبب قيود ABI ، لا يمكننا التخلص من خسائر الأداء الكبيرة. لا يمكننا التخلص من التكلفة الكبيرة لتمرير unique_ptr من حيث القيمة [سيتم نشر حديث تشاندلر حول CppCon 2019 في وقت لاحق] ، لا يمكننا تغيير std :: hash أو موضع الفصل في الذاكرة من أجل unordered_map دون إجبار الجميع على إعادة ترجمة كل شيء في كل مكان. تمت دراسة أداء التجزئات على نطاق واسع على مر السنين ، ومع الأخذ في الاعتبار تحسين عمليات البحث في الجدول والتجزئة الصحيحة ، نحن على ثقة من أنه يمكننا توفير تطبيق unordered_map / std :: hash الذي يتوافق مع واجهة برمجة التطبيقات ويوفر زيادة في الأداء بنسبة 200-300٪. لكن قيود ABI لا تسمح بذلك. تشير الدراسات الإضافية حول تحسين وضبط SSO لسلسلة std :: string إلى زيادة غير تافهة في الأداء (1٪ في العلامات الصغيرة والقياس) - لا تتأثر واجهة برمجة التطبيقات ، لكن قيود ABI لا تسمح بذلك.
تصل الخسارة الإجمالية للإنتاجية المحظورة حصريًا من قبل ABI إلى عدة نقاط مئوية - ربما تصل إلى 5-10٪. هذا ليس شيئًا لا يمكن للنظام البيئي ككل الاستغناء عنه ، ولكن قد لا يكون مقبولًا لدى بعض المؤسسات (من بينها Google). هذا ، بالطبع ، خسارة كبيرة في الأداء مقارنة بما هو مقبول في C ++: تذكر أن هذه لغة تدعي أنها لا تترك مجالًا لمنافس أكثر إنتاجية. لا يبدو معظم المستخدمين مهتمين بتدهور الأداء: فهناك تطبيقات أخرى لجدول التجزئة لهؤلاء المعنيين بالأداء المطلق. ويظهر عدم الكفاءة العامة المرتبطة بتمرير قيمة فريدة ومشاكل أخرى في لغة ABI إلى الواجهة في عدد صغير جدًا من المهام. يمكن للمؤسسات التي تحتاج إلى أقصى إنتاجية أن تسير بطريقتها الخاصة (وتفعل ذلك) ، وذلك باستخدام المكتبات غير القياسية وأدوات التكوين غير القياسية. هذا أمر طبيعي ويجب فهمه بوضوح.
سيؤثر أي تغيير في ABI على عدد أكبر نسبيًا من المستخدمين. أظن أن نسبة كبيرة من هؤلاء المستخدمين لا تشك في مدى قوة اعتمادهم على ABI. في النظام البيئي لخوادم Google ، يتم جمع كل شيء تقريبًا من المصدر ، وهناك عدد قليل من التبعيات الخارجية وهناك فرصة أفضل من المتوسط لإجراء إعادة هيكلة واسعة النطاق. ولكن حتى بالنسبة لنا ، فإن التغييرات الحديثة في ABI على المكتبة القياسية كلفت 5-10 سنوات هندسية.
يمكن تقدير التكلفة الإجمالية لكسر التوافق مع الإصدارات السابقة لـ ABI لنظام C ++ بالكامل بشكل متحفظ في " مهندس الألفية ": إن تنسيق إعادة البناء لكل مزود من المكونات الإضافية ، لذلك. أو dll في العالم سوف يتطلب موارد بشرية هائلة. بالإضافة إلى فصل النظام الإيكولوجي بسبب وحدات C ++ 20 ، يمكن أن يؤدي تغيير ABI في تطوير وتنفيذ الجدول الزمني لـ C ++ 23 إلى فصل ثابت للنظام الإيكولوجي.
هناك العديد من الأسئلة التي لا يمكن الإجابة عليها في هذه المناقشة. إلى متى يمكننا الاستمرار في النقطة التي يصبح فيها تغيير ABI من المفيد فقط ضرورة حاسمة؟ إذا اخترنا صراحة دعم استقرار ABI ، فكم ستكون تكلفة التغيير متى ومتى تنشأ حاجة ماسة؟ إذا كانت مشكلات الأمان مثل Specter و Meltdown تتطلب تغييرًا في اتفاقية الاتصال ، فكم ستكون تكلفة C ++ لكسر هذا الخط؟ ما نسبة المطورين الذين يستخدمون C ++ لأننا نطالب بوضع الأداء فوق كل شيء آخر؟ الأسوأ من ذلك: كم من الوقت يمكن أن تدعي C ++ أنها أسرع لغة وليس لديها مثل هذه التحسينات؟
إذا لم نتمكن من إدراك أو عدم رغبتك في تغيير ABI ، فيجب أن يتم التعبير عن هذا القرار بصوت عالٍ. يجب أن نقول بوضوح أن هذه هي اللغة التي تضع استقرار ABI أعلى من المئة في المئة الأخيرة من الإنتاجية. أنا على استعداد للقول بأن هذا هو الحال في الممارسة العملية على مدى السنوات القليلة الماضية. نحتاج إلى السماح للمستخدمين بمعرفة ما يمكن توقعه منا ، وإعلامهم أنه من المتوقع أن تقوم المكتبات مثل Boost أو Folly أو Absail بالاختيار الصحيح إذا كان الأداء مطلوبًا. ولكن هذا لا يساعد شيئًا في مثل هذه القيود المتعلقة بـ ABI في اللغة نفسها كتكلفة إرسال unique_ptr. تحتفظ المكتبة القياسية بالأهمية في نموذج التطوير هذا: المكتبة القياسية هي ما نستخدمه للتوافق والاستقرار. قد يتطلب هذا تغييرًا في التركيز واتجاه التطوير: قد نرغب في تصميم لمزيد من المرونة في الظروف المتغيرة وليس للأداء "النظيف".
إذا جادلنا بأن الإنتاجية أهم من استقرار ABI ، فيجب علينا أن نقرر على الفور متى سنحطم "التوافق" بالضبط ونبذل قصارى جهدنا حتى يقبل النظام البيئي هذه التغييرات. ونعلن بوضوح وبصوت عالٍ أننا نسير على هذا النحو. عليك أن تفهم أنه كلما مر الوقت بين هذه التغييرات ، كلما أصبحت أكثر تكلفة - لأنه بمرور الوقت سيكون هناك اعتماد أكثر فأكثر غير معتمد على ABI. أوضح "المنفذون" لدينا أن تغييرات C ++ 11 المتوافقة مع التوافق كانت مؤلمة ومكلفة. الرغبة في تجنب تكرار مثل هذه التكاليف أمر طبيعي ، ولكن عليك أن تختار: إما أننا لا نكررها ، لأننا لا نغير ABI ، أو نخفض التكاليف.
في جوهرها ، هناك ثلاثة احتمالات لـ WG21:
- تحديد أي إصدار سيتم تغيير ABI لا يهم في C ++ 23 أو C ++ 26. تحذير الناس وتطوير أدوات التشخيص على الفور للمساعدة في تحديد الأماكن التي سوف تنكسر. يركز على ممارسات وأدوات أكثر اتساقًا لدعم تغييرات ABI المستقبلية. ليس من مصلحة أحد المنفذين تعريض مستخدميه لعواقب تغيير ABI ، إذا لم تقم تطبيقات أخرى بذلك ، فإن تغيير ABI يجب أن يكون نشاطًا منسقًا لصالح المستخدمين في المستقبل. من الناحية المثالية ، تحتاج إلى كسر كل شيء - لتوضيح أن التعليمات البرمجية المترجمة في وضع C ++ 23 غير متوافقة مع التعليمات البرمجية المترجمة في الأوضاع السابقة. إذا تمكن شخص ما من الاستغناء عن إعادة البناء ، وسيواجه الآخرون أخطاء في التخطيط أو في وقت التشغيل - سيزيد ذلك من سوء الفهم وخيبة الأمل.
- قرر أننا نسعى جاهدين لتحقيق استقرار ABI من خلال إضفاء الطابع الرسمي على الممارسة اليوم. كان هذا هو الحال منذ سنوات عديدة عندما كان للمنفذين العاديين حق الاعتراض على كسر تغييرات ABI - لقد وضعنا بالفعل توافق ABI المتخلف فوق نقاء التصميم والأداء. إذا أدركنا ذلك وأبلغنا المستخدمين بوضوح ، فسيكون النظام البيئي أفضل. ستزداد قيمة المكتبات الإضافية لأولئك الذين يحتاجون إلى الضغط على آخر قطرات من الأداء ، لكنهم لا يحتاجون إلى الاستقرار الذي يوفره المعيار. قد تتحدى اللغات الأخرى الموجهة نحو الأداء مركزنا في المستقبل.
- عدم القدرة على اختيار اتجاه وحفظ الوضع الراهن. هذا هو السيناريو الأسوأ بالنسبة لي: نحن نواصل الاهتمام الضمني بالتوافق مع الإصدارات السابقة لـ ABI. نقول "الأداء" ونصوت "التوافق الثنائي". مثل هذا التنافر يضر بالنظام الإيكولوجي ويعني عدم وجود اتفاق على أولويات اللغة. آمل مخلصًا أن نصل إلى توافق الآراء الضروري من خلال جهود المنفذين والمديرين التنفيذيين.
أعتقد أن الخيار رقم 1 مناسب بشكل أفضل للمستخدمين الذين يحتاجون إلى الحد الأقصى من الأداء ، لكن التكلفة الباهظة للنظام الإيكولوجي ويمكن أن تؤدي إلى تجزئة اللغة في المستقبل. الخيار رقم 2 هو خيار ممل ومسؤول وجدير: من المحزن أن نعترف بأننا رسمنا أنفسنا في زاوية الغرفة ونحاول تقليل الخسائر المرتبطة بذلك. يعني اختيار الخيار رقم 3 عدم الإدارة ، وأدعو إلى تجنب ذلك: أي خيار صريح أفضل من التنافر الحالي وعدم القدرة على التوصل إلى اتفاق بشأن اختيار الأهداف الطويلة الأجل.
أفهم أننا وصلنا إلى موقفنا الحالي من خلال العديد من الأعمال الصغيرة التي تبدو وكأنها غير معقولة. على مدار السنوات العشر الماضية ، لم يتم إجراء أي تغيير يمكن أن يبرر حدوث انتهاك للتوافق الثنائي ، ولكن السياسة الضمنية المتمثلة في الحفاظ على التوافق مع الإصدارات السابقة أصبحت مدمرة للنظام الإيكولوجي. ومع ذلك ، من خلال اعتماد مثل هذه السياسة بشكل صريح ، سنفتح إمكانية أخرى لـ C ++ لترك المرحلة تدريجياً: لا يمكنك أن تكون لغة موجهة نحو النظام موجهة نحو الإنتاجية ، وترك مساحة كبيرة للغة أكثر إنتاجية. من الناحية النظرية ، يمكن لكل بائع أن يقرر "كسر" ABI في أي إصدار مستقبلي ، لكن الاتجاه العام للفكر يبدو مختلفًا. أنا متأكد من أن المناقشة والإجماع بين منفذي المعيار و WG21 مطلوبين: ما الأولويات التي يجب عليّ اختيارها؟