ما هو فرع التنبؤ؟

في أي برنامج كمبيوتر تقريبًا ، توجد أجزاء من الكود تتفرع إلى مسارات منفصلة. على سبيل المثال ، عبارة if-then-else لها نتيجتان محتملتان. لا تقدم هذه العبارات أي مشكلة للمعالجات المتسلسلة ، حيث تعالج وحدة المعالجة المركزية كل أمر بالترتيب. تمثل الفروع مشكلة كبيرة للمعالجات المتصلة بالأنابيب ، حيث يتم تنفيذ تعليمات متعددة في وقت واحد.

السيناريو

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

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

لماذا هذه مشكلة؟

لا يهم كيف يتم صياغة هذه المشكلة في معالج متسلسل بالكامل. إنها ببساطة ليست مشكلة. يُعرف الفرع الذي سيتم أخذه قبل معالجة الجزء الأول من التعليمات التالية.

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

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

كيف يتم معالجة هذه المشكلة حقًا

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

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

كود المطابقة

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

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

تنبؤات الفرع الديناميكي

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

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

أنماط التتبع

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

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

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

قد يحدد متنبئ الفرع الذي يستخدم جدول محفوظات النمط أنماطًا متكررة عند أخذ فروع معينة. مثل توقع أن حلقة ما لم يتم أخذها إلا ثلاث مرات قبل مغادرتها.

استنتاج

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

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