
على مدى العقد الماضي منذ ظهور لغة C ، تم إنشاء العديد من لغات البرمجة المثيرة للاهتمام. لا يزال البعض منهم يستخدم ، والبعض الآخر قد أثر على الجيل القادم من اللغات ، وتلاشت شعبية الجيل الثالث بهدوء. في هذه الأثناء ، كانت اللغة القديمة المثيرة للجدل والبدائية ، والتي صنعت في أسوأ تقاليد جيلها من اللغات C (وورثتها) أكثر حيوية من جميع الكائنات الحية.
النقد C هو النوع الكلاسيكي epistolary لصناعتنا. يبدو أعلى من الصوت ، ثم أكثر هدوءًا ، ولكن في الآونة الأخيرة كان مذهلاً حرفيًا. مثال على ذلك هو ترجمة لمقال ديفيد سيسويل "C ليست لغة منخفضة المستوى" ، التي نشرت على مدونتنا منذ بعض الوقت. يمكنك قول أشياء مختلفة عن لغة C ، فهناك الكثير من الأخطاء غير السارة في تصميم اللغة ، لكن رفض لغة "C" في "المستوى المنخفض" كثير جدًا!
حتى لا أتسامح مع مثل هذا الظلم ، أخذت الشجاعة وحاولت أن تقرر ما هي لغة البرمجة منخفضة المستوى وما هي الممارسة التي أرادوا منها ، وبعد ذلك تخطّيت حجج النقاد. هذه هي الطريقة التي ظهر بها هذا المقال.
محتوى
حجج النقد C
فيما يلي بعض حجج نقاد C ، بما في ذلك حجج مقال David Ciswell:
- تشبه آلة تجريد لغة C إلى حد كبير بنية PDP-11 التي عفا عليها الزمن ، والتي توقفت منذ فترة طويلة عن التوافق مع جهاز المعالجات الحديثة الشائعة.
- عدم التطابق بين آلة تجريدية وجهاز الآلات الحقيقية يعقد عملية تطوير تحسين برامج الترجمة اللغوية.
- يؤدي عدم اكتمال مستوى اللغة وتعقيده إلى تباين في التطبيقات القياسية.
- لا تسمح هيمنة اللغات المشابهة لـ C باستكشاف بنيات المعالج البديلة.
دعنا أولاً نحدد متطلبات اللغة ذات المستوى المنخفض ، وبعدها نعود إلى الحجج المقدمة.
لغة برمجة منخفضة المستوى
لا يوجد تعريف مقبول عالميًا للغة منخفضة المستوى. ولكن قبل مناقشة القضايا المثيرة للجدل ، من المستحسن أن يكون لديك على الأقل بعض المتطلبات الأولية لموضوع النزاع.
لا أحد يجادل بأن لغة التجميع هي في أدنى مستوى. لكنه فريد في كل منصة ، لذلك لا يمكن أن تكون الشفرة في مثل هذه اللغة محمولة. حتى في النظام الأساسي المتوافق مع الإصدارات السابقة ، قد تحتاج إلى استخدام بعض الإرشادات الجديدة.
من هنا يتبع الشرط الأول للغة منخفضة المستوى: يجب أن تحتفظ بميزات مشتركة للأنظمة الأساسية الشائعة . ببساطة ، يجب أن يكون المترجم المحمول. تعمل إمكانية نقل المحول البرمجي على تبسيط عملية تطوير برامج الترجمة اللغوية للأنظمة الأساسية الجديدة ، كما أن مجموعة الأنظمة الأساسية المختلفة التي يدعمها برنامج التحويل البرمجي تلغي الحاجة للمطورين لإعادة كتابة برامج التطبيقات لكل جهاز جديد.
يتعارض المطلب الأول مع رغبات مطوري البرامج الخاصة: لغات البرمجة ، وبرامج التشغيل ، وأنظمة التشغيل وقواعد البيانات عالية الأداء. يريد المبرمجون الذين يكتبون هذه البرامج أن يكونوا قادرين على التحسين يدويًا والعمل مباشرة مع الذاكرة وما إلى ذلك. باختصار ، يجب أن تسمح اللغة ذات المستوى المنخفض بالعمل مع تفاصيل تنفيذ النظام الأساسي .
يعد إيجاد توازن بين هذين المطلبين - تحديد الجوانب الشائعة للمنصات والوصول إلى أكبر عدد ممكن من التفاصيل - سببًا أساسيًا لصعوبة تطوير لغة منخفضة المستوى.
لاحظ أن التجريدات عالية المستوى ليست مهمة جدًا لمثل هذه اللغة - من المهم جدًا أن تكون بمثابة عقد بين النظام الأساسي والمترجم والمطور. وإذا كان هناك عقد ، فهناك حاجة إلى لغة مستقلة عن معيار التنفيذ الخاص .
يتم التعبير عن مطلبنا الأول - الميزات الشائعة في الأنظمة الأساسية المستهدفة - في جهاز لغة مجردة ، لذلك سنبدأ المناقشة مع C.
الأمر لا يقتصر على PDP-11
النظام الأساسي الذي ظهرت به لغة C هو PDP-11. يعتمد على بنية von Neumann التقليدية ، حيث يتم تنفيذ البرامج بالتتابع بواسطة المعالج المركزي ، والذاكرة عبارة عن شريط مسطح ، حيث يتم تخزين كل من البيانات والبرامج. يتم تطبيق هذه البنية بسهولة في الأجهزة ، ومع مرور الوقت ، بدأت جميع أجهزة الكمبيوتر للأغراض العامة في استخدامها.
تهدف التحسينات الحديثة في هندسة von Neumann إلى التخلص من عنق الزجاجة الرئيسي - التأخير في تبادل البيانات بين المعالج والذاكرة ( عنق الزجاجة الإنجليزية von Neuman ). أدى الاختلاف في الذاكرة وأداء وحدة المعالجة المركزية إلى ظهور أنظمة تخزين مؤقتة للمعالجات (أحادية المستوى ومتعددة المستويات لاحقًا).
ولكن حتى المخابئ هذه الأيام ليست كافية. أصبحت المعالجات الحديثة superscalar. يتم التعويض جزئيًا عن التأخير في تلقي التعليمات من بيانات الذاكرة عن طريق التنفيذ الاستثنائي ( التوازي على مستوى التعليمات ) للتعليمات ، إلى جانب أداة التنبؤ بالفرع .
تحاكي الآلة التجريدية المتسلسلة C (والعديد من اللغات الأخرى) العمل ليس بشكل خاص في PDP-11 ، ولكن لأي أجهزة كمبيوتر مرتبة وفقًا لمبدأ هندسة von Neumann. وهو يتضمن تصميمات مبنية حول معالجات ذات نواة واحدة: سطح المكتب والخادم x86 ، ARM المحمول ، والتي تأتي من موقع Sun / Oracle SPARC و IBM POWER.
مع مرور الوقت ، بدأ دمج العديد من مراكز المعالجة في معالج واحد ، ونتيجة لذلك أصبح من الضروري الحفاظ على تماسك ذاكرات التخزين المؤقت لكل بروتوكولات تفاعلية جوهرية مطلوبة. وهكذا تم تحجيم العمارة فون نيومان إلى عدة نوى.
كانت النسخة الأصلية من الجهاز abstract C متسلسلة ، لا تعكس وجود مؤشرات ترابط تنفيذ البرنامج التي تتفاعل من خلال الذاكرة. وساهم مظهر طراز الذاكرة في المعيار في زيادة إمكانيات الجهاز التجريدي بالتوازي.
وبالتالي ، فإن التأكيد على أن آلة C المجردة منذ فترة طويلة لا تتفق مع بنية المعالجات الحديثة لا تعني الكثير من اللغات المحددة ، ولكن أجهزة الكمبيوتر التي تستخدم بنية فون نيومان ، بما في ذلك في التنفيذ الموازي.
لكن كممارس ، أود أن أشير إلى ما يلي: يمكننا أن نفترض أن نهج فونيمان قديم ، يمكننا أن نفترض أنه مناسب ، لكن هذا لا يلغي حقيقة أن تصميمات المباني العامة للأغراض العامة تستخدم مشتقات النهج التقليدي.
تجسيد موحد ومحمول للهندسة المعمارية فون نيومان - آلة مجردة C - يتم تنفيذها بسهولة على جميع المنصات الرئيسية ، وبالتالي تتمتع بشعبية كمجمع المحمولة بجدارة.
تحسين المجمعين واللغة ذات المستوى المنخفض
يتمثل مطلبنا الثاني للغة منخفضة المستوى في الوصول إلى تفاصيل التنفيذ ذات المستوى المنخفض لكل من المنصات الشائعة. في حالة C ، هذا هو العمل المباشر مع الذاكرة والكائنات الموجودة فيه كصفيف من وحدات البايت ، والقدرة على العمل مباشرة مع عناوين البايت وحساب المؤشر المتقدم.
يشير نقاد C إلى أن معيار اللغة يوفر الكثير من الضمانات فيما يتعلق ، على سبيل المثال ، بموقع الحقول الفردية في الهياكل والجمعيات. جنبا إلى جنب مع المؤشرات والآليات البدائية للحلقات هذا يعقد عمل محسن.
في الواقع ، سيسمح النهج الأكثر تعقيدًا للمترجم على حل مشكلات محاذاة البيانات في الذاكرة أو الترتيب الأمثل للحقول في الهياكل بشكل مستقل ؛ توفر الدورات ذات المستوى الأعلى الحرية التي تحتاجها عند التمرين.
يكون موضع مطوري C في هذه الحالة كما يلي: يجب أن تسمح لها لغة منخفضة المستوى بالعمل بمستوى منخفض بدرجة كافية حتى يتمكن المبرمج من حل مشكلات التحسين بشكل مستقل. ضمن C ، من الممكن العمل كمترجم ، واختيار ، على سبيل المثال ، تعليمات SIMD ووضع البيانات بشكل صحيح في الذاكرة.
بمعنى آخر ، يتعارض متطلبنا الخاص بالوصول إلى تفاصيل التنفيذ الخاصة بكل منصة مع رغبات مطوري تحسين برامج التحويل البرمجي بالتحديد بسبب وجود أدوات منخفضة المستوى.
ومن المثير للاهتمام ، في مقالته المعنونة "C ليست لغة منخفضة المستوى" ، يجادل Lifewell بالمفارقة أن C منخفضة المستوى للغاية ، مما يشير إلى عدم وجود أدوات عالية المستوى فيها. لكن الممارسين يحتاجون إلى أدوات منخفضة المستوى على وجه التحديد ، وإلا فإن اللغة لا يمكن استخدامها لتطوير أنظمة التشغيل وغيرها من البرامج ذات المستوى المنخفض ، أي أنها لن تلبي متطلباتنا الثانية.
بصرف النظر عن وصف مشاكل التحسين C ، أود أن أشير إلى أنه في الوقت الحالي لا يُستثمر جهد في تحسين مترجمين من اللغات عالية المستوى (نفس C # و Java) مقارنةً بـ GCC أو Clang. تحتوي اللغات الوظيفية أيضًا على مترجمين فعالين كفاية: MLTon ، OCaml ، وغيرها. ولكن لا يزال بإمكان مطوري نفس OCaml التفاخر بالأداء في أحسن الأحوال بنصف سرعة الرمز C ...
معيار كسلعة مطلقة
في مقالته ، يستشهد Chiznell بنتائج الدراسة الاستقصائية التي أجريت في عام 2015: ارتكب العديد من المبرمجين أخطاء في حل مشاكل فهم معايير C.
أفترض أن أحد القراء كان يتعامل مع المعيار C. لدي نسخة ورقية من C99 ، 900 صفحة من الإعلانات التجارية. هذه ليست مواصفات مخطط لاكوني مع حجم أقل من 100 صفحة وليس ML ML القياسية 300 من اللقطات. متعة العمل لا أحد يحصل على معيار C: لا مطوري برامج التحويل البرمجي ، ولا مطوري المستندات ، أو المبرمجين.
ولكن يجب أن نفهم أن معيار C قد تم تطويره بعد الحقيقة ، بعد ظهور العديد من اللهجات المتوافقة مع "الأماكن بالكاد تقريبًا". لقد قام مؤلفو ANSI C بعمل رائع يلخصون التطبيقات الحالية ويغطيون "عكازات" لا تعد ولا تحصى من عدم التناسق في تصميم اللغة.
قد يبدو غريباً أن يتعهد شخص ما بتنفيذ مثل هذا المستند. ولكن تم تنفيذ C من قبل العديد من المجمعين. لن أعيد سرد حكايات الآخرين حول حديقة حيوانات UNIX في أواخر الثمانينيات ، خاصة وأنني في ذلك الوقت لم أعتبرها واثقة للغاية وحتى خمس سنوات فقط. لكن من الواضح أن كل شخص في الصناعة كان بحاجة فعليًا إلى مستوى قياسي.
الشيء العظيم هو أنه موجود ويتم تنفيذه من قبل ثلاثة على الأقل المجمعين كبيرة والعديد من المجمعين أصغر ، والتي تدعم معا مئات المنصات. لا يمكن لأي من اللغات المنافسة C ، التي تدعي تاج ملك اللغات المنخفضة المستوى ، أن تفتخر بهذا التنوع والتنوع.
في الواقع ، فإن معيار C الحالي ليس سيئا للغاية. مبرمج أكثر أو أقل خبرة قادر على تطوير برنامج التحويل البرمجي C غير الأمثل في فترة زمنية معقولة ، وهو ما يؤكده وجود العديد من تطبيقات شبه الهواة (نفس TCC ، LCC و 8cc).
إن وجود معيار مقبول بشكل عام يعني أن اللغة C تلبي آخر متطلباتنا للغة منخفضة المستوى: هذه اللغة مبنية على مواصفات وليس على تنفيذ محدد.
بنيات بديلة - الحوسبة الخاصة
ولكن Lifewell يستشهد بحجة أخرى ، والعودة إلى الجهاز من المعالجات الحديثة للأغراض العامة التي تنفذ خيارات الهندسة المعمارية فون نيومان. يدعي أنه من المنطقي تغيير كيفية عمل المعالج المركزي. مرة أخرى ، لا يقتصر هذا النقد على C ، ولكن للنموذج الأساسي للبرمجة الضرورية.
في الواقع ، هناك العديد من البدائل للنهج التقليدي مع التنفيذ المتسلسل للبرامج: نماذج SIMD في نمط GPU ، ونماذج بأسلوب آلة Erlang المجردة ، وغيرها. لكن كل من هذه الطرق لها قابلية تطبيق محدودة عند استخدامها في معالج مركزي.
وحدات معالجة الرسومات ، على سبيل المثال ، تتضاعف بشكل ملحوظ المصفوفات في الألعاب والتعلم الآلي ، ولكن من الصعب استخدامها لتتبع الأشعة. بمعنى آخر ، هذا النموذج مناسب للمسرعات المتخصصة ، لكنه لا يعمل معالجات للأغراض العامة.
يعمل Erlang بشكل رائع في مجموعة ، لكن يصعب عمل جدول فرز سريع أو جدول تجزئة فعال. يتم استخدام نموذج الجهات الفاعلة المستقلة بشكل أفضل على مستوى أعلى ، في مجموعة كبيرة ، حيث لا تزال كل عقدة هي نفس الجهاز عالي الأداء مع معالج تقليدي.
وفي الوقت نفسه ، تضمنت المعالجات الحديثة المتوافقة مع x86 منذ فترة طويلة مجموعات من تعليمات مكافحة ناقلات مماثلة ل GPU في الغرض ومبادئ التشغيل ، ولكن الحفاظ على دائرة المعالج العام في أسلوب فون نيومان ككل. ليس لدي أدنى شك في أنه سيتم تضمين أي أساليب عامة إلى حد ما في الحوسبة في المعالجات الشعبية.
هناك مثل هذا الرأي الموثوق : يكمن المستقبل في مسرعات متخصصة قابلة للبرمجة. تحت مثل هذه القطع الاستثنائية من الحديد ، من المنطقي حقًا تطوير لغات ذات دلالات خاصة. لكن جهاز كمبيوتر متعدد الأغراض كان ولا يزال مشابهًا لجهاز PDP-11 الذي تعتبر اللغات الملائمة له مثل C مناسبة تمامًا.
سيعيش
هناك تناقض أساسي في مقالة تشيزنيل. يكتب أنه لضمان سرعة برامج C ، تحاكي المعالجات آلة C المجردة (و PDP-11 المنسية منذ زمن طويل) ، وبعد ذلك تشير إلى القيود المفروضة على مثل هذه الآلة. لكنني لا أفهم لماذا هذا يعني أن "C ليست لغة منخفضة المستوى".
بشكل عام ، لا يتعلق الأمر بعيوب لغة C كلغة ، بل يتعلق بالنقد للهندسة الشائعة لأسلوب فون نيومان ونموذج البرمجة الذي يتبعهما. لكن حتى الآن لا يبدو أن الصناعة مستعدة للتخلي عن البنية المألوفة (على الأقل ليس في معالجات للأغراض العامة).
على الرغم من توفر العديد من المعالجات المتخصصة مثل GPUs و TPUs ، فإن بنية von Neumann تتحكم حاليًا وتحتاج الصناعة إلى لغة تسمح لها بالعمل بأقل مستوى ممكن في إطار الهيكل الأكثر شعبية. بسيطة إلى حد ما ، موصلة إلى عشرات المنصات ولغة البرمجة الموحدة هي C (وعائلتها المباشرة).
على الرغم من ذلك ، فإن لدى C قصورًا كافيًا: مكتبة من الوظائف القديمة ، ومعيار معقد وغير متناسق ، وأخطاء في التصميم الإجمالي. ولكن ، على ما يبدو ، ما زال مبدعو اللغة يفعلون شيئًا صحيحًا.
بطريقة أو بأخرى ، ما زلنا بحاجة إلى لغة منخفضة المستوى ، وقد صُمم خصيصًا لأجهزة الكمبيوتر Fonneimann الشائعة. ودع C يكون قديمًا ، لكن من الواضح أن أي خليفة له سيظل مضطرًا للبناء على نفس المبادئ.