الغوص في الأنظمة › 5. ما عرفه von Neumann: بنية الحاسوب 6 / 18 السابق التالي

5. ما عرفه فون نيومان: معمارية الحاسوب

قد يشير مصطلح معمارية الحاسوب (computer architecture) إلى كامل مستوى عتاد الحاسوب. غير أنه كثيراً ما يُستخدم للإشارة إلى تصميم وتنفيذ الجزء الخاص بالمعالج الرقمي في عتاد الحاسوب، ونركّز في هذا الفصل على معمارية معالج الحاسوب.

وحدة المعالجة المركزية (CPU، أو المعالج) هي جزء الحاسوب الذي ينفّذ تعليمات البرنامج على بيانات البرنامج. وتُخزَّن تعليمات البرنامج وبياناته في ذاكرة الوصول العشوائي (RAM) في الحاسوب. وينفّذ معالج رقمي معيّن معمارية مجموعة تعليمات محددة (ISA) تحدد مجموعة التعليمات وترميزها الثنائي ومجموعة سجلات المعالج وآثار تنفيذ التعليمات في حالة المعالج. وهناك معماريات ISA مختلفة كثيرة، منها SPARC وIA32 وMIPS وARM وARC وPowerPC وx86 (وتشمل الأخيرة IA32 وx86-64). وتعرّف المعمارية الدقيقة (microarchitecture) دوائر تنفيذ معمارية ISA محددة. ويمكن أن تختلف تنفيذات المعمارية الدقيقة للمعمارية ISA نفسها ما دامت تنفّذ تعريف ISA. فمثلاً، تنتج Intel وAMD تنفيذات معالجات مختلفة لمعمارية IA32.

تعرّف بعض معماريات ISA حاسوب مجموعة التعليمات المختزلة (RISC)، وتعرّف أخرى حاسوب مجموعة التعليمات المعقّدة (CISC). فمعماريات RISC لها مجموعة صغيرة من التعليمات الأساسية التي تُنفَّذ كل منها بسرعة؛ إذ تُنفَّذ كل تعليمة في نحو دورة ساعة معالج واحدة، ويدمج المصرّفون تسلسلات من عدة تعليمات RISC أساسية لتنفيذ وظائف عالية المستوى. وفي المقابل، توفّر تعليمات معمارية CISC وظائف أعلى مستوى من تعليمات RISC. كما تعرّف معماريات CISC مجموعة أكبر من التعليمات من RISC، وتدعم أنماط عنونة أكثر تعقيداً (أي طرقاً للتعبير عن مواقع ذاكرة بيانات البرنامج)، وتدعم تعليمات متغيرة الطول. وقد تنفّذ تعليمة CISC واحدة سلسلة من الوظائف منخفضة المستوى وقد تستغرق عدة دورات ساعة معالج. وتتطلب الوظيفة نفسها تعليمات متعددة على معمارية RISC.

تاريخ RISC مقابل CISC

في أوائل الثمانينيات، طوّر باحثون في جامعتي بيركلي وستانفورد RISC من خلال مشروع Berkeley RISC ومشروع Stanford MIPS. وحصل ديفيد باترسون من بيركلي وجون هينيسي من ستانفورد على جائزة تورينغ عام 20171 (أعلى جائزة في الحوسبة) عن عملهما في تطوير معماريات RISC.

عند تطويرها، كانت معمارية RISC خروجاً جذرياً عن الرأي السائد بأن معماريات ISA تحتاج إلى التعقيد المتزايد لتحقيق أداء عالٍ. «اختلف نهج RISC عن حواسيب مجموعات التعليمات المعقّدة (CISC) السائدة آنذاك في أنه تطلب مجموعة صغيرة من التعليمات البسيطة والعامة (الوظائف التي يجب أن يؤديها الحاسوب)، ما يتطلب ترانزستورات أقل من مجموعات التعليمات المعقّدة ويقلّل مقدار العمل الذي يجب أن يؤديه الحاسوب.»2

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

وعند مقارنة RISC بـ CISC، تحتوي برامج RISC على عدد أكبر من التعليمات الكلية المطلوب تنفيذها، لكن تُنفَّذ كل تعليمة بكفاءة أكبر بكثير من معظم تعليمات CISC، وتتيح معماريات RISC تصاميم معمارية دقيقة أبسط من CISC. وتحتوي برامج CISC على تعليمات أقل، وتصمَّم المعماريات الدقيقة لـ CISC لتنفيذ تعليمات أكثر تعقيداً بكفاءة، لكنها تتطلب تصاميم معمارية دقيقة أكثر تعقيداً ومعدلات ساعة أسرع. وبشكل عام، ينتج عن معالجات RISC تصميم أكفأ وأداء أفضل. ومع زيادة أحجام ذاكرة الحاسوب بمرور الوقت، صار حجم الملف التنفيذي أقل أهمية لأداء البرنامج. غير أن CISC ظلت معمارية ISA المهيمنة، وذلك إلى حد كبير لأن الصناعة تنفّذها وتدعمها.

واليوم، تبقى CISC معمارية ISA المهيمنة لحواسيب المكتب وكثير من حواسيب فئة الخوادم. فمثلاً، معماريات x86 من Intel قائمة على CISC. أما معماريات RISC فتكثر رؤيتها في الخوادم الراقية (مثل SPARC) وفي الأجهزة المحمولة (مثل ARM) بسبب متطلبات طاقتها المنخفضة. وقد يجمع تنفيذ معمارية دقيقة معينة لمعمارية ISA من نوع RISC أو CISC بين تصميمي RISC وCISC في الخفاء. فمثلاً، تستخدم معظم معالجات CISC شيفرة دقيقة (microcode) لترميز بعض تعليمات CISC بمجموعة تعليمات أقرب إلى RISC ينفّذها المعالج الأساسي، وتحتوي بعض مجموعات تعليمات RISC الحديثة على بضع تعليمات أو أنماط عنونة أكثر تعقيداً من مجموعات تعليمات MIPS وBerkeley RISC الأولى.

تلتزم جميع المعالجات الحديثة، بصرف النظر عن معمارية ISA، بنموذج معمارية فون نيومان. ويتيح التصميم عام الغرض لمعمارية فون نيومان تنفيذ أي نوع من البرامج. وهي تستخدم نموذج البرنامج المخزَّن، أي أن تعليمات البرنامج تقيم في ذاكرة الحاسوب مع بيانات البرنامج، وكلاهما مدخلان للمعالج.

يقدّم هذا الفصل معمارية فون نيومان والأصول والمكوّنات التي تقوم عليها معمارية الحاسوب الحديثة. نبني معالجاً رقمياً مثالياً (CPU) على نموذج معمارية فون نيومان، ونصمّم وحدة معالجة من دوائر رقمية مبنية من لبنات البوابات المنطقية، ونوضح كيف تنفّذ وحدة المعالجة تعليمات البرنامج.

المراجع

  1. جوائز ACM A. M. Turing. https://amturing.acm.org/
  2. «روّاد معمارية الحاسوب الحديثة يحصلون على جائزة ACM A.M. Turing»، إشعار مركز إعلام ACM، مارس 2018. https://www.acm.org/media-center/2018/march/turing-award-2017

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

من القرن الثامن عشر حتى أوائل القرن العشرين، عمل الرياضيون كأوائل الحواسيب البشرية لحسابات تتعلق بتطبيقات العلوم والهندسة1. وقد أشارت كلمة «computer» في الأصل إلى «الشخص الذي يحسب». وكثيراً ما تولّت النساء الرياضيات دور الحاسوب. بل إن استخدام النساء كحواسيب بشرية كان منتشراً إلى حدّ أن تعقيد الحساب كان يُقاس بـ«كيلو-فتاة» (kilo-girls)، أي مقدار العمل الذي يمكن لألف حاسوب بشري إنجازه في ساعة واحدة2. وقد اعتُبرت النساء على نطاق واسع أفضل من الرجال في إجراء الحسابات الرياضية، لأنه كانت غالبيتهن أكثر منهجية. ولم يكن مسموحاً للنساء بشغل منصب مهندس. وبالتالي، حُصرن في عمل أكثر «دنوّاً»، مثل إجراء حسابات معقّدة.

صُمِّم أول حاسوب رقمي عام الغرض، وهو المحرك التحليلي (Analytical Engine)، على يد الرياضي البريطاني تشارلز باباج الذي يُنسب إليه بعضهم لقب أبي الحاسوب. وكان المحرك التحليلي امتداداً لاختراعه الأصلي، المحرك التفاضلي، وهو آلة حاسبة ميكانيكية قادرة على حساب الدوال كثيرات الحدود. وكانت آدا لوفلايز، التي ربما ينبغي أن تُعرف بأم الحوسبة، أول شخص يطوّر برنامجاً حاسوبياً وأول من نشر خوارزمية يمكن حسابها باستخدام المحرك التحليلي لتشارلز باباج. ومن ضمن ملاحظاتها إدراكها الطبيعة العامة للمحرك التحليلي: «[فـ]المحرك التحليلي لا يدّعي بأي حال أنه يبتكر شيئاً. بل يفعل كل ما نعرف كيف نأمره بأدائه.3» غير أن المحرك التحليلي، خلافاً للحواسيب الحديثة، كان جهازاً ميكانيكياً ولم يُبنَ إلا جزئياً. ولم يكن معظم مصممي ما صار السلف المباشر للحاسوب الحديث على علم بعمل باباج ولوفلايز عندما طوّروا آلاتهم.

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

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

5.1.1. آلة تورينغ

في عام 1937، اقترح الرياضي البريطاني آلان تورينغ7 «آلة الحوسبة المنطقية»، وهي حاسوب نظري. واستخدم تورينغ هذه الآلة لإثبات عدم وجود حل لمسألة القرار (وبالألمانية Entscheidungsproblem)، التي طرحها الرياضيان ديفيد هيلبرت وفيلهلم أكرمان عام 1928. ومسألة القرار خوارزمية تأخذ عبارة كمدخل وتحدد ما إذا كانت العبارة صحيحة عالمياً. وقد أثبت تورينغ عدم وجود مثل هذه الخوارزمية بإظهار أن مسألة التوقف (هل تتوقف الآلة X على المدخل y؟) غير قابلة للحسم في آلة تورينغ. وكجزء من هذا الإثبات، وصف تورينغ آلة عامة قادرة على أداء مهام أي آلة حوسبة أخرى. وكان ألونزو تشيرش، مشرف أطروحة تورينغ في جامعة برينستون، أول من أشار إلى آلة الحوسبة المنطقية باسم آلة تورينغ، وإلى صورتها العامة باسم آلة تورينغ العامة.

وبعد ذلك عاد تورينغ إلى إنجلترا وخدم بلده كجزء من وحدة فك الشيفرات في بلتشلي بارك خلال الحرب العالمية الثانية. وكان له دور أساسي في تصميم وبناء بومبي (Bombe)، وهو جهاز كهروميكانيكي ساعد في فك الشيفرة التي تنتجها آلة إنيغما، التي كانت ألمانيا النازية تستخدمها عادةً لحماية الاتصالات الحساسة خلال الحرب العالمية الثانية.

وبعد الحرب، صمّم تورينغ محرك الحوسبة الآلي (ACE). وكان ACE حاسوباً ببرنامج مخزَّن، أي أن تعليمات البرنامج وبياناته معاً تُحمَّل في ذاكرة الحاسوب ويشغّلها الحاسوب عام الغرض. وورقته، المنشورة عام 1946، هي ربما أكثر الأوصاف تفصيلاً لحاسوب كهذا8.

5.1.2. أوائل الحواسيب الإلكترونية

سرّعت الحرب العالمية الثانية كثيراً من تطوير الحواسيب الأولى. غير أنه بسبب الطبيعة السرية للعمليات العسكرية في الحرب العالمية الثانية، لم يُعترف علناً بكثير من تفاصيل الابتكارات التي نتجت عن النشاط المحموم خلال الحرب إلا بعد سنوات. ومن الأمثلة الجيدة على ذلك كولوسوس، وهي آلة صمّمها المهندس البريطاني تومي فلاورز للمساعدة في فك شيفرة لورنتس التي كانت ألمانيا النازية تستخدمها لترميز الاتصالات الاستخباراتية عالية المستوى. وقد ساعد بعض عمل آلان تورينغ في تصميمها. وبُنيت عام 1943، ويمكن القول إن كولوسوس أول حاسوب قابل للبرمجة ورقمي وإلكتروني كامل. غير أنه كان حاسوباً خاص الغرض، مصمّماً خصيصاً لفك الشيفرات. وعملت النساء في الخدمة البحرية الملكية النسائية (WRNS، المعروفات بـ«الزرزور») كمشغّلات لكولوسوس. ورغم أن التقرير العام عن توني14 أشار إلى أن عدة من الزرزور أظهرن قدرة في العمل التشفيري، فلم يُمنح أي منهن منصب مشفّرة، بل وُكّلت إليهن مهام تشغيل كولوسوس أكثر دنوّاً5,15.

وعلى الجانب الآخر من الأطلسي، كان العلماء والمهندسون الأمريكيون يعملون بجد على إنشاء حواسيب خاصة بهم. وقد صمّم أستاذ هارفارد هوارد أيكن (وكان أيضاً قائداً بحرياً في احتياطي البحرية الأمريكية) المارك I، وهو حاسوب كهروميكانيكي عام الغرض قابل للبرمجة. وبُني عام 1944 وساعد في تصميم القنبلة الذرية. وبنى أيكن حاسوبه وهو غير مدرك إلى حد كبير لعمل تورينغ، وكان مدفوعاً بهدف إحياء المحرك التحليلي لتشارلز باباج6. ومن الخصائص الرئيسية للمارك I أنه كان آلياً بالكامل وقادراً على العمل أياماً دون تدخل بشري6. وقد أصبح ذلك خصيصة أساسية في تصميم الحواسيب مستقبلاً.

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

وبينما جُنّد الرجال في القوات المسلحة خلال الحرب العالمية الثانية، جُندت النساء للمساعدة في المجهود الحربي كحواسيب بشرية. ومع وصول أول الحواسيب الإلكترونية، صارت النساء أول المبرمجات، لأن البرمجة كانت تُعدّ عملاً كتابياً. ولا عجب أن كثيراً من الابتكارات المبكرة في البرمجة، مثل أول مصرّف وفكرة تقسيم البرامج إلى وحدات والتنقيح ولغة التجميع، يُنسب إلى مخترعات نساء. فمثلاً، طوّرت غريس هوبر أول مصرّف (A-0) وأول لغة برمجة عالية المستوى (FLOW-MATIC)، وقد أثّرت الأخيرة تأثيراً كبيراً في تصميم COBOL، أول لغة برمجة مستقلة عن الآلة. وكانت هوبر أيضاً مبرمجة للمارك I وكتبت الكتاب الذي وصف تشغيله.

كانت مبرمجات ENIAC ست نساء: جين جينينغز بارتيك، وبيتي سنايدر هولبرتون، وكاي مكنولتي موشلي، وفرانسيس بيلاس سبنس، ومارلين ويسكوف ميلتزر، وروث ليشترمان تيتلبوم. وخلافاً للزرزور، مُنحت نساء ENIAC قدراً كبيراً من الاستقلالية في مهمتهن؛ إذ أُعطين مخططات توصيل ENIAC فقط، وقيل لهن أن يكتشفن كيف يعمل وكيف يُبرمَج. وإضافةً إلى ابتكارهن في حل كيفية برمجة (وتنقيح) أحد أوائل الحواسيب الإلكترونية العامة في العالم، طوّرت مبرمجات ENIAC أيضاً فكرة المخططات الانسيابية الخوارزمية، وطوّرن مفاهيم برمجية مهمة مثل الإجراءات الفرعية والتداخل. ومثل غريس هوبر، سيكون لجين جينينغز بارتيك وبيتي سنايدر هولبرتون مسيرتان طويلتان في الحوسبة، وهما من روّاد الحوسبة الأوائل. ولسوء الحظ، لا يُعرف المدى الكامل لإسهامات النساء في الحوسبة المبكرة. وبعدم قدرتهن على التقدم، تركت كثير من النساء المجال بعد الحرب العالمية الثانية. ولمعرفة المزيد عن المبرمجات الأوائل، نشجع القرّاء على الاطلاع على إعادة ترميز الجندر11 لجانيت أباتي، وروزيات بالغة السرية، وهو فيلم وثائقي لـ PBS12 من إخراج ليآن إريكسون، و*«الحواسيب»* لكاثي كليمان13.

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

5.1.3. إذن ما الذي عرفه فون نيومان؟

من مناقشتنا لأصل معمارية الحاسوب الحديثة، يتضح أنه كانت في الثلاثينيات والأربعينيات عدة ابتكارات أدت إلى نهضة الحاسوب كما نعرفه اليوم. وفي عام 1945، نشر جون فون نيومان ورقة بعنوان «المسودة الأولى لتقرير عن EDVAC»9، تصف معمارية تستند إليها الحواسيب الحديثة. وكان EDVAC خليفة ENIAC. وقد اختلف عنه في أنه كان حاسوباً ثنائياً لا عشرياً، وكان حاسوباً ببرنامج مخزَّن. واليوم، يُعرف هذا الوصف للتصميم المعماري لـ EDVAC بـمعمارية فون نيومان.

تصف معمارية فون نيومان حاسوباً عام الغرض، أي حاسوباً مصمّماً لتشغيل أي برنامج. وهي تستخدم أيضاً نموذج البرنامج المخزَّن، أي أن تعليمات البرنامج وبياناته تُحمَّل معاً على الحاسوب ليعمل. ولا يوجد في نموذج فون نيومان تمييز بين التعليمات والبيانات؛ فكلاهما يُحمَّل في الذاكرة الداخلية للحاسوب، وتُجلب تعليمات البرنامج من الذاكرة وتنفّذها وحدات الحاسوب الوظيفية التي تنفّذ تعليمات البرنامج على بيانات البرنامج.

تتشابك إسهامات جون فون نيومان مع عدة قصص سابقة في الحوسبة. فقد كان رياضياً هنغارياً، وأستاذاً في معهد الدراسات المتقدمة وجامعة برينستون معاً، وعمل مرشداً مبكراً لآلان تورينغ. ولاحقاً أصبح عالماً باحثاً في مشروع مانهاتن، ما قاده إلى هوارد أيكن والمارك I؛ ثم عمل مستشاراً في مشروع ENIAC، وتراسل بانتظام مع إيكرت وموشلي. وقد جاءت ورقته الشهيرة التي تصف EDVAC من عمله على الحاسوب الإلكتروني المتغير المنفصل الآلي (EDVAC) الذي اقترحه إيكرت وموشلي على الجيش الأمريكي، وبُني في جامعة بنسلفانيا. وقد تضمّن EDVAC عدة ابتكارات في التصميم المعماري تشكّل أساس كل الحواسيب الحديثة تقريباً: فقد كان عام الغرض، واستخدم نظام الأعداد الثنائي، وكان له ذاكرة داخلية، وكان كهربائياً بالكامل. ولأن فون نيومان كان المؤلف الوحيد للورقة9 إلى حد كبير، فإن التصميم المعماري الذي تصفه الورقة يُنسب أساساً إلى فون نيومان وصار يُعرف بمعمارية فون نيومان. ويجدر الذكر أن تورينغ وصف بتفصيل كبير تصميم آلة مشابهة في عام 1946. غير أنه بما أن ورقة فون نيومان نُشرت قبل ورقة تورينغ، فقد نال فون نيومان الفضل الأكبر في هذه الابتكارات.

وبصرف النظر عن من «اخترع فعلاً» معمارية فون نيومان، لا ينبغي التقليل من إسهامات فون نيومان نفسه. فقد كان رياضياً وعالماً لامعاً. وتمتد إسهاماته في الرياضيات من نظرية المجموعات إلى ميكانيكا الكم ونظرية الألعاب. وفي الحوسبة، يُعدّ أيضاً مخترع خوارزمية الدمج والترتيب (merge sort). وقد رأى والتر إيزاكسون في كتابه المبتكرون أن من أعظم نقاط قوة فون نيومان قدرته على التعاون على نطاق واسع وعلى رؤية أهمية المفاهيم الجديدة حدسياً6. وقد عمل كثير من مصممي الحاسوب الأوائل بمعزل عن بعضهم. ويرى إيزاكسون أن فون نيومان، بمشاهدته بطء حاسوب المارك I، استطاع أن يدرك حدسياً قيمة حاسوب إلكتروني حقيقي والحاجة إلى تخزين البرامج في الذاكرة وتعديلها. ويمكن القول لذلك إن فون نيومان، أكثر حتى من إيكرت وموشلي، استوعب قوة الحاسوب الإلكتروني ببرنامج مخزَّن وقدّرها تقديراً كاملاً6.

5.1.4. المراجع

  1. ديفيد آلان غرير، «When Computers Were Human»، مطبعة جامعة برينستون، 2005.
  2. ميغان غاربر، «Computing Power Used to be Measured in 'Kilo-Girls'». The Atlantic، 16 أكتوبر 2013. https://www.theatlantic.com/technology/archive/2013/10/computing-power-used-to-be-measured-in-kilo-girls/280633/
  3. بيتي ألكسندرا تول، «Ada, The Enchantress of Numbers». Strawberry Press، 1998.
  4. جورج ديسون، Turing’s Cathedral: the origins of the digital universe. Pantheon. 2012.
  5. جاك كوبلاند، «Colossus: The Secrets of Bletchley Park’s Code-breaking Computers».
  6. والتر إيزاكسون. «The Innovators: How a group of inventors, hackers, genius and geeks created the digital revolution». Simon and Schuster. 2014.
  7. آلان م. تورينغ. «On computable numbers, with an application to the Entscheidungsproblem». Proceedings of the London mathematical society 2(1). ص 230—265. 1937.
  8. برايان كاربنتر وروبرت دوران. «The other Turing Machine». The Computer Journal 20(3) ص 269—279. 1977.
  9. جون فون نيومان. «First Draft of a Report on the EDVAC (1945)». أُعيد نشره في IEEE Annals of the history of computing 4. ص 27—75. 1993.
  10. آرثر بيركس، هيرمان غولدستين، جون فون نيومان. «Preliminary discussion of the logical design of an electronic computing instrument (1946)». أعيد نشره بواسطة The Origins of Digital Computers (Springer)، ص 399—413. 1982.
  11. جانيت أباتي. «Recoding gender: Women’s changing participation in computing». MIT Press. 2012.
  12. ليآن إريكسون. «Top Secret Rosies: The Female Computers of World War II». Public Broadcasting System. 2010.
  13. كاثي كليمان، «The Computers». http://eniacprogrammers.org/
  14. «Breaking Teleprinter Ciphers at Bletchley Park: An edition of I.J. Good, D. Michie and G. Timms: General Report on Tunny with Emphasis on Statistical Methods (1945)». المحررون: Reeds وDiffie وFields. Wiley، 2015.
  15. جانيت أباتي، «Recoding Gender»، MIT Press، 2012.

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

تتألف معمارية فون نيومان (المصوَّرة في الشكل 1) من خمسة مكوّنات رئيسية:

  1. تنفّذ وحدة المعالجة تعليمات البرنامج.
  2. تدير وحدة التحكم تنفيذ تعليمات البرنامج في وحدة المعالجة. وتشكّل وحدتا المعالجة والتحكم معاً المعالج.
  3. تخزّن وحدة الذاكرة بيانات البرنامج وتعليماته.
  4. تُحمّل وحدة (وحدات) الإدخال بيانات البرنامج وتعليماته على الحاسوب وتبدأ تنفيذ البرنامج.
  5. تخزّن وحدة (وحدات) الإخراج نتائج البرنامج أو تستقبلها.

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

تُعرض الوحدات الخمس لمعمارية فون نيومان كصناديق، وتربط بينها النواقل الموضَّحة كخطوط أسفل الصناديق يتصل بها كل صندوق. الشكل 1. تتألف معمارية فون نيومان من وحدات المعالجة والتحكم والذاكرة والإدخال والإخراج. وتشكّل وحدتا التحكم والمعالجة المعالج، الذي يحتوي وحدة الحساب والمنطق (ALU) وسجلات المعالج العامة وبعض السجلات الخاصة (IR وPC). وتربط الوحدات نواقل تُستخدم لنقل البيانات والاتصال بين الوحدات.

5.2.1. المعالج

تنفّذ وحدتا التحكم والمعالجة معاً المعالج، وهو جزء الحاسوب الذي ينفّذ تعليمات البرنامج على بيانات البرنامج.

5.2.2. وحدة المعالجة

تتألف وحدة المعالجة في آلة فون نيومان من جزأين. الأول وحدة الحساب والمنطق (ALU) التي تنفّذ عمليات رياضية مثل الجمع والطرح والمنطقي «أو»، على سبيل المثال لا الحصر. وعادةً ما تنفّذ وحدات ALU الحديثة مجموعة كبيرة من العمليات الحسابية. والجزء الثاني من وحدة المعالجة مجموعة من السجلات. والسجل (register) وحدة تخزين صغيرة وسريعة تُستخدم لحمل بيانات البرنامج والتعليمات التي تنفّذها وحدة الحساب والمنطق. والأمر الجوهري أنه لا يوجد تمييز بين التعليمات والبيانات في معمارية فون نيومان. فالتعليمات هي بيانات بكل المقاييس. ولذلك يستطيع كل سجل حمل كلمة بيانات واحدة.

5.2.3. وحدة التحكم

تدير وحدة التحكم تنفيذ تعليمات البرنامج بتحميلها من الذاكرة وتغذية معاملات التعليمات وعملياتها عبر وحدة المعالجة. وتتضمن وحدة التحكم أيضاً بعض التخزين لتتبع حالة التنفيذ وتحديد إجرائها التالي: يحتفظ عدّاد البرنامج (PC) بعنوان ذاكرة التعليمة التالية المطلوب تنفيذها، ويخزّن سجل التعليمات (IR) التعليمة المحمَّلة من الذاكرة الجاري تنفيذها حالياً.

5.2.4. وحدة الذاكرة

الذاكرة الداخلية ابتكار رئيسي في معمارية فون نيومان. فهي توفّر تخزين بيانات البرنامج قريباً من وحدة المعالجة، ما يقلّل كثيراً مقدار الوقت اللازم لإجراء الحسابات. وتخزّن وحدة الذاكرة بيانات البرنامج وتعليماته معاً — وتخزين تعليمات البرنامج جزء رئيسي من نموذج البرنامج المخزَّن في معمارية فون نيومان.

يختلف حجم الذاكرة من نظام لآخر. غير أن معمارية ISA للنظام تحدّ نطاق العناوين التي يمكنه التعبير عنها. وفي الأنظمة الحديثة، أصغر وحدة ذاكرة قابلة للعنونة بايت واحد (8 بتّات)، وبالتالي يقابل كل عنوان موقع ذاكرة فريداً لتخزين بايت واحد. ونتيجةً لذلك، تدعم معماريات 32 بتّة عادةً حجم فضاء عناوين أقصى قدره 232، وهو ما يقابل 4 غيغابايت (GiB) من الذاكرة القابلة للعنونة.

يشير مصطلح الذاكرة أحياناً إلى تسلسل هرمي كامل من التخزين في النظام. وقد يشمل سجلات في وحدة المعالجة إضافة إلى أجهزة تخزين ثانوية مثل محركات الأقراص الصلبة (HDD) أو محركات الأقراص الصلبة الإلكترونية (SSD). ونناقش التسلسل الهرمي للذاكرة بالتفصيل في فصل التخزين والتسلسل الهرمي للذاكرة. وسنستخدم الآن مصطلح «الذاكرة» بالتبادل مع ذاكرة الوصول العشوائي الداخلية (RAM) — وهي الذاكرة التي يمكن لوحدة المعالجة المركزية الوصول إليها. وتخزين RAM وصول عشوائي لأن جميع مواقع تخزين RAM (العناوين) يمكن الوصول إليها مباشرة. ومن المفيد التفكير في RAM كمصفوفة خطية من العناوين، حيث يقابل كل عنوان بايتاً واحداً من الذاكرة.

أحجام الكلمات عبر التاريخ

حجم الكلمة، المحدد في معمارية ISA، هو عدد بتّات حجم البيانات القياسي الذي يعالجه المعالج كوحدة واحدة. وقد تذبذب حجم الكلمة القياسي على مر السنين. فبالنسبة إلى EDVAC، اقترح حجم كلمة من 30 بتّة. وفي الخمسينيات، كانت أحجام الكلمات من 36 بتّة شائعة. ومع ابتكار IBM 360 في الستينيات، صارت أحجام الكلمات معيارية أكثر أو أقل، وبدأت تتوسع من 16 بتّة إلى 32 بتّة إلى 64 بتّة اليوم. وإذا فحصت معمارية Intel بمزيد من التفصيل، فقد تلاحظ بقايا بعض هذه القرارات القديمة، إذ أُضيفت معماريات 32 و64 بتّة كامتدادات لمعمارية 16 بتّة الأصلية.

5.2.5. وحدتا الإدخال والإخراج (I/O)

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

تتألف وحدة الإدخال من مجموعة الأجهزة التي تتيح للمستخدم أو البرنامج جلب البيانات من العالم الخارجي إلى الحاسوب. وأكثر أشكال أجهزة الإدخال شيوعاً اليوم هي لوحة المفاتيح والفأرة. والكاميرات والميكروفونات أمثلة أخرى.

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

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

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

5.2.6. آلة فون نيومان أثناء العمل: تنفيذ برنامج

تعمل الوحدات الخمس المكوّنة لمعمارية فون نيومان معاً لتنفيذ دورة جلب-فك-تنفيذ-تخزين (fetch-decode-execute-store) من الإجراءات التي تنفّذ معاً تعليمات البرنامج. وتبدأ هذه الدورة بتعليمة البرنامج الأولى، وتُكرَّر حتى يخرج البرنامج:

  1. تجلب وحدة التحكم التعليمة التالية من الذاكرة. ولوحدة التحكم سجل خاص، هو عدّاد البرنامج (PC)، يحتوي عنوان التعليمة التالية المطلوب جلبها. وتضع ذلك العنوان على ناقل العناوين وتضع أمر قراءة على ناقل التحكم إلى وحدة الذاكرة. ثم تقرأ وحدة الذاكرة البايتات المخزّنة عند العنوان المحدد وترسلها إلى وحدة التحكم على ناقل البيانات. ويخزّن سجل التعليمات (IR) بايتات التعليمة المستلمة من وحدة الذاكرة. كما تزيد وحدة التحكم قيمة PC لتخزين عنوان التعليمة التالية الجديدة المطلوب جلبها.
  2. تفكّ وحدة التحكم التعليمة المخزّنة في IR. فتفكّ بتّات التعليمة التي ترمّز العملية المطلوب تنفيذها والبتّات التي ترمّز أماكن وجود المعاملات. وتُفكّ بتّات التعليمة استناداً إلى تعريف معمارية ISA لترميز تعليماتها. كما تجلب وحدة التحكم قيم معاملات البيانات من مواقعها (من سجلات المعالج أو الذاكرة أو مضمّنة في بتّات التعليمة) كمدخل إلى وحدة المعالجة.
  3. تنفّذ وحدة المعالجة التعليمة. وتنفّذ وحدة الحساب والمنطق عملية التعليمة على معاملات بيانات التعليمة.
  4. تخزّن وحدة التحكم النتيجة في الذاكرة. وتُخزَّن نتيجة تنفيذ وحدة المعالجة للتعليمة في الذاكرة. وتكتب وحدة التحكم النتيجة في الذاكرة بوضع قيمة النتيجة على ناقل البيانات، ووضع عنوان موقع التخزين على ناقل العناوين، ووضع أمر كتابة على ناقل التحكم. وعند استقبال ذلك، تكتب وحدة الذاكرة القيمة في الذاكرة عند العنوان المحدد.

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

يعرض الشكل 2 والشكل 3 المراحل الأربع لتنفيذ تعليمة من معمارية فون نيومان لتعليمة جمع مثال مُخزَّن معاملاها في سجلات المعالج. في مرحلة الجلب، تقرأ وحدة التحكم التعليمة عند عنوان الذاكرة المخزّن في PC ‏(1234). وترسل العنوان على ناقل العناوين وأمر READ على ناقل التحكم. وتستقبل وحدة الذاكرة الطلب، وتقرأ القيمة عند العنوان 1234، وترسلها إلى وحدة التحكم على ناقل البيانات. وتضع وحدة التحكم بايتات التعليمة في سجل IR وتحدّث PC بعنوان التعليمة التالية (1238 في هذا المثال). وفي مرحلة الفك، تغذّي وحدة التحكم وحدة الحساب والمنطق في وحدة المعالجة ببتّات التعليمة التي تحدد العملية المطلوب تنفيذها، وتستخدم بتّات التعليمة التي تحدد السجلات التي تخزّن المعاملات لقراءة قيم المعاملات من سجلات وحدة المعالجة إلى وحدة الحساب والمنطق (وقيم المعاملات 3 و4 في هذا المثال). وفي مرحلة التنفيذ، ينفّذ جزء وحدة الحساب والمنطق في وحدة المعالجة العملية على المعاملات لإنتاج النتيجة (3 + 4 = 7). وأخيراً، في مرحلة التخزين، تكتب وحدة التحكم النتيجة (7) من وحدة المعالجة إلى وحدة الذاكرة. ويُرسَل عنوان الذاكرة (5678) على ناقل العناوين، ويُرسَل أمر WRITE على ناقل التحكم، وتُرسَل قيمة البيانات المطلوب تخزينها (7) على ناقل البيانات. وتستقبل وحدة الذاكرة هذا الطلب وتخزّن 7 عند عنوان الذاكرة 5678. وفي هذا المثال، نفترض أن عنوان الذاكرة المطلوب تخزين النتيجة فيه مضمّن في بتّات التعليمة.

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

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

الترانزستورات

تُنشأ البوابات المنطقية من ترانزستورات محفورة في مادة شبه موصلة (مثل رقائق السيليكون). وتعمل الترانزستورات كمفاتيح تتحكم في التدفق الكهربائي عبر الرقاقة. ويمكن للترانزستور تبديل حالته بين التشغيل أو الإيقاف (بين خرج جهد عالٍ أو منخفض). وتعتمد حالة خرجه على حالته الحالية زائد حالة مدخله (جهد عالٍ أو منخفض). وتُرمَّز القيم الثنائية بهذين الجهدين العالي (1) والمنخفض (0)، وتُنفَّذ البوابات المنطقية بترتيبات من بضعة ترانزستورات تنفّذ إجراءات تبديل على المدخلات لإنتاج خرج البوابة المنطقية. وعدد الترانزستورات التي يمكن أن تتسع في دائرة متكاملة (رقاقة) مقياس تقريبي لقوتها؛ فمع ترانزستورات أكثر لكل رقاقة، توجد لبنات أكثر لتنفيذ وظائف أو تخزين أكثر.

5.3.1. البوابات المنطقية الأساسية

على أدنى مستوى، تُبنى كل الدوائر بربط البوابات المنطقية معاً. وتنفّذ البوابات المنطقية عمليات بوليانية على معاملات بوليانية (0 أو 1). وتشكّل AND وOR وNOT مجموعة كاملة من البوابات المنطقية يمكن بناء أي دائرة منها. وللبوابة المنطقية قيمة إدخال ثنائية واحدة (NOT) أو قيمتا إدخال ثنائيتان (AND وOR) وتُنتج قيمة خرج ثنائية هي العملية المنطقية البتّية على مدخلها. فمثلاً، قيمة إدخال مقدارها 0 لبوابة NOT تُخرج 1 ‏(1 هو NOT(0)). ويعرض جدول الحقيقة (truth table) لعملية منطقية قيمة العملية لكل تبديل من تبديلات المدخلات. ويعرض الجدول 1 جداول الحقيقة لبوابات AND وOR وNOT المنطقية.

A B A AND B A OR B NOT A
0 0 0 0 1
0 1 0 1 1
1 0 0 1 0
1 1 1 1 0

يوضح الشكل 1 كيف يمثّل معماريو الحواسيب هذه البوابات في رسومات الدوائر.

بوابات AND وOR وNOT المنطقية. الشكل 1. بوابات AND وOR وNOT المنطقية لمدخلات من بتّة واحدة تُنتج خرجاً من بتّة واحدة.

النسخة متعددة البتّات من بوابة منطقية (لمدخل وخرج من M بتّة) دائرة بسيطة جداً تُبنى باستخدام M بوابة منطقية من بتّة واحدة. وتدخل كل بتّة من بتّات قيمة الإدخال الـM إلى بوابة مختلفة من بتّة واحدة تنتج بتّة الخرج المقابلة في النتيجة الـM. فمثلاً، يعرض الشكل 2 دائرة AND من 4 بتّات مبنية من أربع بوابات AND من بتّة واحدة.

بوابة AND من 4 بتّات مبنية من بوابات AND من بتّة واحدة. الشكل 2. دائرة AND من 4 بتّات مبنية من أربع بوابات AND من بتّة واحدة.

هذا النوع من الدوائر البسيطة جداً، الذي يوسّع فقط عرض بتّات الإدخال والإخراج لبوابة منطقية، يُشار إليه غالباً ببوابة M بتّة لقيمة محددة من M تحدد عرض بتّات الإدخال والإخراج (عدد البتّات).

5.3.2. بوابات منطقية أخرى

رغم أن مجموعة البوابات المنطقية المكوّنة من AND وOR وNOT كافية لتنفيذ أي دائرة، توجد بوابات منطقية أساسية أخرى تُستخدم غالباً لبناء الدوائر الرقمية. وتشمل هذه البوابات الإضافية NAND (نفي A AND B) وNOR (نفي A OR B) وXOR (أو الحصري). وتظهر جداول حقيقتها في الجدول 2.

A B A NAND B A NOR B A XOR B
0 0 1 1 0
0 1 1 0 1
1 0 1 0 1
1 1 0 0 0

تظهر بوابات NAND وNOR وXOR في رسومات الدوائر كما في الشكل 3.

بوابات XOR وNAND وNOR المنطقية. الشكل 3. بوابات NAND وNOR وXOR المنطقية.

تمثّل الدائرة الموجودة في نهاية بوابتي NAND وNOR النفي أو NOT. فمثلاً، تبدو بوابة NOR كبوابة OR بدائرة في نهايتها، تمثيلاً لكون NOR نفي OR.

المجموعات الجزئية الدنيا من البوابات المنطقية

ليست NAND وNOR وXOR ضرورية لبناء الدوائر، لكنها بوابات إضافية تُضاف إلى المجموعة {AND، OR، NOT} وتُستخدم عادةً في تصميم الدوائر. ويمكن تنفيذ أي من هذه البوابات من ترانزستورات (لبنة البوابات المنطقية)، أو من تراكيب بوابات أخرى.

ومن المجموعة الأكبر {AND، OR، NOT، NAND، NOR، XOR}، توجد عدة مجموعات جزئية دنيا من البوابات المنطقية تكفي وحدها لبناء أي دائرة. فمثلاً، المجموعة الجزئية {AND، NOT} مجموعة دنيا: ‏(A OR B) مكافئ لـ NOT(NOT(A) AND NOT(B)). وبدلاً من استخدام مجموعة دنيا من البوابات، نستخدم المجموعة {AND، OR، NOT} لأنها الأسهل فهماً.

ولأن NAND وNOR وXOR غير ضرورية، يمكن تنفيذ وظائفها بدمج بوابات AND وOR وNOT في دوائر تنفّذ وظائف NAND وNOR وXOR. فمثلاً، يمكن بناء NOR باستخدام NOT مدمجة مع بوابة OR، (A NOR B) ≡ NOT(A OR B))، كما في الشكل 4.

بوابة NOR مبنية من بوابتي OR وNOT: يُدخَل خرج بوابة OR في بوابة NOT الشكل 4. يمكن تنفيذ بوابة NOR باستخدام بوابة OR وبوابة NOT. يُغذّى المدخلان A وB أولاً عبر بوابة OR، ويُدخل خرج بوابة OR إلى بوابة NOT (فـ NOR هو NOT لـ OR).

تُبنى رقائق الدوائر المتكاملة اليوم بتقنية CMOS التي تستخدم NAND كلبنة أساسية للدوائر على الرقاقة. وتشكّل بوابة NAND وحدها مجموعة جزئية دنيا أخرى من بوابات منطقية كاملة.

تنفّذ الدوائر الرقمية الوظائف الجوهرية للمعمارية. فهي تنفّذ معمارية مجموعة التعليمات (ISA) في العتاد، وتنفّذ أيضاً وظائف التخزين والتحكم في جميع أنحاء النظام. ويتضمن تصميم الدوائر الرقمية تطبيق مستويات متعددة من التجريد: فالدوائر التي تنفّذ وظائف معقّدة تُبنى من دوائر أصغر تنفّذ وظائف جزئية، وهذه تُبنى من دوائر أبسط، وهكذا وصولاً إلى لبنات البوابات المنطقية الأساسية لجميع الدوائر الرقمية. ويوضح الشكل 1 دائرة مجرّدة من تنفيذها. وتُمثَّل الدائرة كـصندوق أسود (black box) موسوم بوظيفتها أو اسمها ولا يُعرض منه إلا مدخلاته ومخرجاته، مع إخفاء تفاصيل تنفيذه الداخلي.

مثال على دائرة الشكل 1. تُنفَّذ الدائرة بربط دوائر فرعية وبوابات منطقية معاً. وتُجرَّد وظيفتها من تفاصيل تنفيذها ويمكن استخدامها كبنية لإنشاء دوائر أخرى.

توجد ثلاث فئات رئيسية من لبنات بناء الدوائر: دوائر الحساب/المنطق، ودوائر التحكم، ودوائر التخزين. فالدائرة المتكاملة للمعالج مثلاً تحتوي الأنواع الثلاثة من الدوائر الفرعية: تستخدم مجموعة سجلاته دوائر تخزين؛ وتستخدم وظيفته الجوهرية لتنفيذ وظائف الحساب والمنطق دوائر حساب ومنطق؛ وتُستخدم دوائر التحكم في جميع أنحاء المعالج لإدارة تنفيذ التعليمات والتحكم في تحميل القيم وتخزينها في سجلاته.

نناقش في هذا القسم هذه الأنواع الثلاثة من الدوائر، ونعرض كيفية تصميم دائرة أساسية من البوابات المنطقية، ثم كيفية بناء دوائر أكبر من الدوائر الأساسية والبوابات المنطقية.

تنفّذ دوائر الحساب والمنطق تعليمات الحساب والمنطق في معمارية ISA، وهي التي تشكّل معاً وحدة الحساب والمنطق (ALU) في المعالج. كما تنفّذ دوائر الحساب والمنطق أجزاء من وظائف أخرى في المعالج. فمثلاً، تُستخدم دوائر الحساب لزيادة عدّاد البرنامج (PC) كجزء من الخطوة الأولى من تنفيذ التعليمة، وتُستخدم لحساب عناوين الذاكرة بدمج بتّات معاملات التعليمة وقيم السجلات.

كثيراً ما يبدأ تصميم الدوائر بتنفيذ نسخة من بتّة واحدة لدائرة بسيطة من البوابات المنطقية. ثم تُستخدم هذه الدائرة من بتّة واحدة كبنية لتنفيذ نسخ من M بتّة من الدائرة. وخطوات تصميم دائرة من بتّة واحدة من البوابات المنطقية الأساسية هي:

  1. صمّم جدول الحقيقة للدائرة: حدّد عدد المدخلات والمخرجات، وأضف مدخلاً في الجدول لكل تبديل من تبديلات بتّات الإدخال يحدد قيمة بتّات الخرج.
  2. باستخدام جدول الحقيقة، اكتب تعبيراً عن وقت تكون فيه كل بتّة خرج للدائرة 1 بدلالة قيم مدخلاتها مدمجةً بـ AND وOR وNOT.
  3. ترجم التعبير إلى تسلسل من البوابات المنطقية، حيث تحصل كل بوابة على مدخلاتها إما من مدخل للدائرة أو من خرج بوابة منطقية سابقة.

نتبع هذه الخطوات لتنفيذ دائرة التساوي من بتّة واحدة: يخرج التساوي البتّي (A == B) القيمة 1 عندما تتساوى قيمتا A وB ويخرج 0 خلاف ذلك.

أولاً، صمّم جدول الحقيقة للدائرة:

A B خرج A == B
0 0 1
0 1 0
1 0 0
1 1 1

بعد ذلك، اكتب تعبيرات عن وقت تكون فيه A == B هي 1 بدلالة A وB مدمجتين بـ AND وOR وNOT. أولاً، تأمّل كل صف خرجه 1 على حدة، بدءاً بالصف الأول في جدول الحقيقة:

A B A == B
0 0 1
بالنسبة إلى قيم الإدخال في هذا الصف، أنشئ اقتراناً (conjunction) من تعبيرات مدخلاته يُقيَّم إلى 1. والاقتران يدمج تعبيرات فرعية تُقيَّم إلى 0 أو 1 بـ AND، ويكون هو نفسه 1 فقط عندما يُقيَّم كلا تعبيريه الفرعيين إلى 1. ابدأ بالتعبير عن وقت تقييم كل إدخال إلى 1:
NOT(A)    # is 1 when A is 0
NOT(B)    # is 1 when B is 0

بعد ذلك، أنشئ اقترانهما (ادمجهما بـ AND) للحصول على تعبير عن وقت تقييم هذا الصف من جدول الحقيقة إلى 1:

NOT(A) AND NOT(B)    # is 1 when A and B are both 0

نفعل الشيء نفسه للصف الأخير في جدول الحقيقة، الذي خرجه أيضاً 1:

A B A == B
1 1 1
A AND B   # is 1 when A and B are both 1

وأخيراً، أنشئ فصلاً (disjunction) (أي OR) من كل اقتران يقابل صفاً في جدول الحقيقة يُقيَّم إلى 1:

(NOT(A) AND NOT(B)) OR (A AND B)  # is 1 when A and B are both 0 or both 1

عند هذه النقطة لدينا تعبير عن A == B يمكن ترجمته إلى دائرة. وفي هذه الخطوة، يستخدم مصممو الدوائر تقنيات لتبسيط التعبير لإنشاء تعبير مكافئ أدنى (أي يقابل أقل عدد من المعاملات و/أو أقصر مسار للبوابات عبر الدائرة). ويجب على المصممين توخي الحذر الشديد عند تصغير تصميم دائرة لضمان تكافؤ التعبير المترجَم. وهناك طرق رسمية لتصغير الدوائر خارج نطاق تغطيتنا، لكننا سنستخدم بعض الاستدلالات أثناء تطوير الدوائر.

في مثالنا، نترجم التعبير السابق مباشرةً إلى دائرة. وقد يُغوينا استبدال (NOT(A) AND NOT(B)) بـ (A NAND B)، لكن لاحظ أن هذين التعبيرين ليسا متكافئين: فهما لا يُقيَّمان التقييم نفسه لجميع تبديلات A وB. فمثلاً، عندما يكون A هو 1 وB هو 0، يكون (A == B) هو 0 و(A NAND B) هو 1.

لترجمة التعبير إلى دائرة، ابدأ من التعبير الأعمق واعمل نحو الخارج (سيكون الأعمق أول البوابات، وستكون مخارجها مدخلات لبوابات لاحقة). وتقابل المجموعة الأولى من البوابات أي نفي لقيم الإدخال (بوابات NOT للمدخلين A وB). بعد ذلك، لكل اقتران، أنشئ أجزاء الدائرة التي تغذّي قيم الإدخال إلى بوابة AND. ثم تُغذّى مخارج بوابات AND إلى بوابة OR (أو بوابات) تمثّل الفصل. وتُعرض الدائرة الناتجة في الشكل 1.

دائرة تساوي من بتّة واحدة الشكل 1. دائرة التساوي من بتّة واحدة (A == B) المبنية من بوابات AND وOR وNOT المنطقية.

للتحقق من صحة هذه الدائرة، حاكِ جميع تبديلات قيم الإدخال A وB الممكنة عبر الدائرة وتحقق من مطابقة خرج الدائرة للصف المقابل في جدول الحقيقة لـ (A == B). فمثلاً، إذا كان A هو 0 وB هو 0، تنفي بوابتا NOT قيمتهما قبل تغذيتهما عبر بوابة AND العليا، فيكون دخل بوابة AND هذه (1، 1)، ما ينتج خرجاً مقداره 1، وهو قيمة الإدخال العليا لبوابة OR. وتُغذّى قيمتا A وB ‏(0، 0) مباشرةً عبر بوابة AND السفلى، ما ينتج خرجاً مقداره 0 من بوابة AND السفلى، وهو الإدخال الأسفل لبوابة OR. وهكذا تستقبل بوابة OR قيمتي الإدخال (1، 0) وتُخرج القيمة 1. لذا، عندما يكون A وB كلاهما 0، تُخرج الدائرة 1 بشكل صحيح. ويوضح الشكل 2 هذا المثال.

قيم مثال عبر دائرة تساوي من بتّة واحدة الشكل 2. مثال يوضح كيف تحسب دائرة التساوي من بتّة واحدة (A == B). بدءاً بقيمتي إدخال 0 لـ A و0 لـ B، تنتشر القيم عبر البوابات المكوّنة للدائرة لحساب قيمة الخرج الصحيحة 1 لـ A == B.

إن النظر إلى تنفيذ دائرة التساوي من بتّة واحدة كوحدة يتيح تجريدها من تنفيذها، وبالتالي يمكن استخدامها بسهولة أكبر كبنية لدوائر أخرى. ونمثّل هذا التجريد لدائرة التساوي من بتّة واحدة (المعروض في الشكل 3) كصندوق مدخلاه موسومان بـA وB وخرجه الوحيد موسوم بـA == B. والبوابات الداخلية التي تنفّذ دائرة التساوي من بتّة واحدة مخفية في هذا العرض المجرّد للدائرة.

دائرة التساوي من بتّة واحدة الشكل 3. تجريد دائرة التساوي من بتّة واحدة. يمكن استخدام هذه الدائرة كبنية في دوائر أخرى.

يمكن بناء نسخ من بتّة واحدة لدوائر NAND وNOR وXOR بطريقة مشابهة، باستخدام بوابات AND وOR وNOT فقط، بدءاً من جداول حقيقتها (الجدول 2) وتطبيق الخطوات نفسها المتبعة مع دائرة التساوي من بتّة واحدة.

A B A NAND B A NOR B A XOR B
0 0 1 1 0
0 1 1 0 1
1 0 1 0 1
1 1 0 0 0

تُبنى النسخ متعددة البتّات من هذه الدوائر من نسخ متعددة من بتّة واحدة منها بطريقة مشابهة لكيفية بناء بوابة AND من 4 بتّات من أربع بوابات AND من بتّة واحدة.

دوائر الحساب

تُبنى دوائر الحساب بالطريقة نفسها التي استخدمناها لبناء الدوائر المنطقية. فمثلاً، لبناء دائرة جمع من بتّة واحدة، ابدأ بجدول الحقيقة للجمع من بتّة واحدة، الذي له قيمتا إدخال A وB وقيمتا خرج: إحداهما لمجموع A وB، والأخرى للتجاوز أو الحمل الخارج (CARRY OUT). ويعرض الجدول 3 جدول الحقيقة الناتج لجمع بتّة واحدة.

A B SUM CARRY OUT
0 0 0 0
0 1 1 0
1 0 1 0
1 1 0 1

في الخطوة التالية، لكل خرج، أي المجموع SUM والحمل الخارج CARRY OUT، أنشئ تعبيرات منطقية عن وقت تكون فيه قيمة الخرج 1. وتُعبَّر هذه التعبيرات كفصول من اقترانات لكل صف من قيم الإدخال:

SUM: (NOT(A) AND B) OR (A AND NOT(B))     # 1 when exactly one of A or B is 1
CARRY OUT:  A AND B                       # 1 when both A and B are 1

لا يمكن تبسيط تعبير الحمل الخارج CARRY OUT. غير أن تعبير المجموع SUM أعقد ويمكن تبسيطه، ما يؤدي إلى تصميم دائرة أبسط. وأول ما يجب ملاحظته أن خرج المجموع يمكن التعبير عنه أيضاً بـ (A XOR B). وإذا كان لدينا بوابة أو دائرة XOR، فإن التعبير عن المجموع بـ (A XOR B) ينتج تصميم دائرة جمع أبسط. وإلا فسيُستخدم التعبير بـ AND وOR وNOT ويُنفَّذ ببوابات AND وOR وNOT.

لنفترض أن لدينا بوابة XOR يمكن استخدامها لتنفيذ دائرة الجمع من بتّة واحدة. وتُعرض الدائرة الناتجة في الشكل 4.

دائرة جمع من بتّة واحدة الشكل 4. لدائرة الجمع من بتّة واحدة مدخلان A وB ومخرجان: المجموع SUM والحمل الخارج CARRY OUT.

يمكن استخدام دائرة الجمع من بتّة واحدة كبنية لدوائر أكثر تعقيداً. فمثلاً، قد نريد إنشاء دوائر جمع من N بتّة لإجراء الجمع على قيم بأحجام مختلفة (مثل دوائر جمع من بايت واحد أو بايتين أو 4 بايتات). غير أن إنشاء دائرة جمع من N بتّة من N دائرة جمع من بتّة واحدة يتطلب عناية أكبر من إنشاء دوائر منطقية من N بتّة من N دائرة منطقية من بتّة واحدة.

عند إجراء جمع (أو طرح) متعدد البتّات، تُجمع البتّات الفردية بالترتيب من البتّة الأقل أهمية إلى الأكثر أهمية. ومع تقدّم هذا الجمع البتّي، إذا نتج عن جمع البتّتين رقم i حمل خارج قيمته 1، فيُضاف 1 إضافي مع البتّتين رقم (i+1). وبعبارة أخرى، الحمل الخارج من دائرة جمع البتّة رقم i قيمة إدخال لدائرة جمع البتّة رقم (i+1).

وبالتالي، لتنفيذ دائرة جمع متعددة البتّات، نحتاج دائرة جمع جديدة من بتّة واحدة لها ثلاثة مدخلات: A وB والحمل الداخل CARRY IN. وللقيام بذلك، اتبع الخطوات أعلاه لإنشاء دائرة جمع من بتّة واحدة، بثلاثة مدخلات (A، B، CARRY IN) ومخرجين (SUM وCARRY OUT)، بدءاً بجدول الحقيقة لجميع تبديلات مدخلاتها الثلاثة. ونترك تصميم هذه الدائرة تمريناً للقارئ، لكننا نعرض تجريدها كدائرة جمع من بتّة واحدة في الشكل 5.

دائرة جمع من بتّة واحدة مع حمل وارد الشكل 5. دائرة الجمع من بتّة واحدة بثلاثة مدخلات (A وB وCARRY IN) ومخرجين (SUM وCARRY OUT).

وباستخدام هذه النسخة من دائرة الجمع من بتّة واحدة كبنية، يمكننا بناء دائرة جمع من N بتّة بتغذية بتّات المعاملات المتناظرة عبر دوائر جمع فردية من بتّة واحدة، وتغذية قيمة الحمل الخارج CARRY OUT من دائرة جمع البتّة رقم i في قيمة الحمل الداخل CARRY IN لدائرة جمع البتّة رقم (i+1). وتستقبل دائرة جمع البتّتين رقم 0 قيمة 0 لحملها الداخل من جزء آخر من دوائر المعالج يفكّ تعليمة ADD.

هذا النوع من دوائر الجمع من N بتّة، المبنية من N دائرة جمع من بتّة واحدة، يُسمى جامع الحمل المتموّج (ripple carry adder)، المعروض في الشكل 6. وتتموّج نتيجة المجموع أو تنتشر عبر الدائرة من البتّات منخفضة الرتبة إلى عالية الرتبة. ولن تُحسب بتّة 1 من قيمتي المجموع والحمل الخارج حساباً صحيحاً إلا بعد حساب بتّة 0 منهما. والسبب أن الحمل الداخل للبتّة رقم 1 يستمد قيمته من الحمل الخارج للبتّة رقم 0، وهكذا بالنسبة للبتّات الأعلى رتبة التالية في النتيجة.

دائرة الجمع المتموّجة. يُصبح خرج CARRY OUT من دائرة الجمع الخاصة بالبتّة i هو المدخل CARRY IN لدائرة الجمع الخاصة بالبتّة i+1. الشكل 6. دائرة جامع حمل متموّج من 4 بتّات أُنشئت من أربع دوائر جمع من بتّة واحدة.

تُبنى دوائر وظائف حسابية ومنطقية أخرى بطرق مشابهة بدمج الدوائر والبوابات المنطقية. فمثلاً، يمكن بناء دائرة طرح تحسب (A - B) من دوائر جمع وسلب تحسب الطرح كـ (A + (-B)).

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

ومضمِّم الإشارة (multiplexer, MUX) مثال على دائرة تحكم تختار واحدة من عدة قيم. وقد يستخدم المعالج دائرة مضمِّم لاختيار سجل المعالج الذي يُقرأ منه قيمة معامل تعليمة.

ولمضمِّم الإشارة ذي N طريق مجموعة من N قيمة إدخال وقيمة خرج واحدة مختارة من إحدى مدخلاته. وقيمة إدخال إضافية هي التحديد (Select, S) ترمّز أي من مدخلاته الـN يُختار لخرجه.

أبسط مضمِّم ثنائي الطريقين يختار بين مدخلين A وB من بتّة واحدة. ومدخل التحديد لمضمِّم ثنائي الطريقين بتّة واحدة: إذا كان مدخل S هو 1 فسيختار A للخرج؛ وإذا كان 0 فسيختار B للخرج. ويُعرض جدول الحقيقة لمضمِّم ثنائي الطريقين من بتّة واحدة أدناه. وقيمة بتّة التحديد (S) تختار إما قيمة A أو B كقيمة خرج المضمِّم.

A B S الخرج
0 0 0 0 (قيمة B)
0 1 0 1 (قيمة B)
1 0 0 0 (قيمة B)
1 1 0 1 (قيمة B)
0 0 1 0 (قيمة A)
0 1 1 0 (قيمة A)
1 0 1 1 (قيمة A)
1 1 1 1 (قيمة A)

يعرض الشكل 1 دائرة المضمِّم ثنائي الطريقين لمدخل من بتّة واحدة.

مضمِّم من بتّة واحدة الشكل 1. دائرة مضمِّم ثنائي الطريقين من بتّة واحدة. تُستخدم قيمة إدخال الإشارة (S) لاختيار أي من مدخليه (A أو B) سيكون قيمة خرج الدائرة: عندما يكون S هو 1 يُختار A؛ وعندما يكون S هو 0 يُختار B.

يعرض الشكل 2 كيف يختار المضمِّم خرج A بقيمة إدخال S مقدارها 1. فمثلاً، لنفترض أن قيم الإدخال هي 1 لـ A و0 لـ B و1 لـ S. وتُنفى S قبل إرسالها إلى بوابة AND العليا مع B ‏(0 AND B)، ما ينتج قيمة خرج 0 من بوابة AND العليا. وتُغذّى S إلى بوابة AND السفلى مع A، ما ينتج (1 AND A) الذي يُقيَّم إلى قيمة A الخارجة من بوابة AND السفلى. وتُغذّى قيمة A ‏(1 في مثالنا) و0 من بوابة AND العليا كمدخل إلى بوابة OR، ما ينتج (0 OR A) كخرج. وبعبارة أخرى، عندما يكون S هو 1، يختار المضمِّم قيمة A كخرجه (وقيمة A هي 1 في مثالنا). ولا تؤثر قيمة B في الخرج النهائي للمضمِّم، لأن 0 سيكون دائماً خرج بوابة AND العليا عندما يكون S هو 1.

عندما تكون S هي 1، يختار المضمِّم A كخرج له الشكل 2. دائرة مضمِّم ثنائي الطريقين من بتّة واحدة تختار (تُخرج) A عندما يكون S هو 1.

يعرض الشكل 3 المسار عبر المضمِّم عندما تختار قيمة إدخال S‏ = 0 خرج B. وإذا اعتبرنا المدخلين نفسيهما لـ A وB كما في المثال أعلاه، لكن غيّرنا S إلى 0، فسيكون نفي 0 هو الدخل إلى بوابة AND العليا، ما ينتج (1 AND B)، أي قيمة B، كخرج من بوابة AND العليا. ودخل بوابة AND السفلى هو (0 AND A)، ما ينتج 0 من بوابة AND السفلى. وبذلك تكون قيم الإدخال إلى بوابة OR هي (B OR 0)، وهو ما يُقيَّم إلى قيمة B كخرج للمضمِّم (وقيمة B هي 0 في مثالنا).

عندما تكون S هي 0، يختار المضمِّم B كخرج له الشكل 3. دائرة مضمِّم ثنائي الطريقين من بتّة واحدة تختار (تُخرج) B عندما يكون S هو 0.

ودائرة المضمِّم ثنائي الطريقين من بتّة واحدة بنية لبناء دوائر مضمِّم ثنائية الطريقين من N بتّة. فمثلاً، يعرض الشكل 4 مضمِّماً ثنائي الطريقين من 4 بتّات مبنيّاً من أربع دوائر مضمِّم ثنائية الطريقين من بتّة واحدة.

مضمِّم ثنائي من 4 بتّات الشكل 4. دائرة مضمِّم ثنائي الطريقين من 4 بتّات مبنية من أربع دوائر مضمِّم ثنائية الطريقين من بتّة واحدة. وتختار بتّة إشارة واحدة S إما A أو B كخرج.

ويختار مضمِّم N طريق واحداً من N مدخل كخرج. وهو يتطلب دائرة مضمِّم مختلفة قليلاً عن مضمِّم ثنائي الطريقين، ويحتاج log2(N) بتّة لمدخل التحديد. والبتّات التحديدية الإضافية ضرورية لأنه بـ log2(N) بتّة يمكن ترميز N قيمة متميزة، واحدة لاختيار كل من المدخلات الـN. ويدخل كل تبديل متميز لبتّات التحديد log2(N) مع إحدى قيم الإدخال الـN إلى بوابة AND، ما ينتج اختيار قيمة إدخال واحدة بالضبط كخرج للمضمِّم. ويعرض الشكل 5 مثالاً على دائرة مضمِّم من بتّة واحدة بأربعة اتجاهات.

مضمِّم من N اتجاه الشكل 5. لدائرة مضمِّم أربعة اتجاهات أربعة مدخلات وبتّتا تحديد ‏(log(4)) ترمّزان أي المدخلات الأربعة ينبغي أن يُخرجه المضمِّم.

تستخدم دائرة المضمِّم رباعية الاتجاهات أربع بوابات AND بثلاثة مدخلات وبوابة OR واحدة بأربعة مدخلات. ويمكن بناء نسخ متعددة المدخلات من البوابات بتسلسل عدة بوابات AND ‏(وOR) ثنائية المدخلات. فمثلاً، تُبنى بوابة AND بثلاثة مدخلات من بوابتَي AND ثنائيتَي المدخلات، حيث تأخذ بوابة AND الأولى قيمتَي إدخال وتأخذ الثانية قيمة الإدخال الثالثة وخرج بوابة AND الأولى: ‏(x AND y AND z) مكافئ لـ ((x AND y) AND z).

لمعرفة كيف تعمل دائرة المضمِّم رباعية الاتجاهات، تأمّل قيمة إدخال S مقدارها 2 ‏(0b10 ثنائياً)، كما في الشكل 6. تحصل بوابة AND العليا على الدخل (NOT(S0) AND NOT(S1) AND A)، أو (1 AND 0 AND A)، ما ينتج 0 كخرج من بوابة AND العليا. وتحصل بوابة AND الثانية على قيم الإدخال (0 AND 0 AND B)، ما ينتج 0 كخرج. وتحصل بوابة AND الثالثة على قيم الإدخال (1 AND 1 AND C)، ما ينتج قيمة C كخرج. وتحصل بوابة AND الأخيرة على (0 AND 1 AND D)، ما ينتج 0 كخرج. ولدى بوابة OR مدخلات (0 OR 0 OR C OR 0)، ما ينتج قيمة C كخرج للمضمِّم (فقيمة S مقدارها 2 تختار C).

تختار دائرة المضمِّم الرباعية C كخرج عندما تكون S هي 2 ‏(0b10) الشكل 6. دائرة مضمِّم رباعية الاتجاهات تختار C كخرج عندما يكون إدخال التحديد S هو 2 ‏(0b10).

ومفكّكات التضميم والمفكّكات فئتان أخريان من دوائر التحكم. ومفكّك التضميم (demultiplexer, DMUX) معكوس المضمِّم. فبينما يختار المضمِّم واحداً من N مدخل، يختار مفكّك التضميم واحداً من N مخرج. ويأخذ DMUX قيمة إدخال واحدة وإدخال تحديد، وله N مخرج. وبناءً على قيمة S، يرسل قيمة الإدخال إلى مخرج واحد بالضبط من مخارجه الـN (فتوجَّه قيمة الإدخال إلى أحد خطوط الخرج الـN). وكثيراً ما تُستخدم دائرة DMUX لاختيار إحدى N دائرة لتمرير قيمة. أما دائرة المفكّك (decoder) فتأخذ إدخالاً مرمّزاً وتُمكّن أحد عدة مخارج بناءً على قيمة الإدخال. فمثلاً، دائرة مفكّك لها قيمة إدخال من N بتّة تستخدم القيمة لتمكين (ضبط على 1) خط خرج واحد بالضبط من خطوط خرجها البالغ عددها 2N (الخط المقابل لترميز القيمة ذات N بتّة). ويعرض الشكل 7 مثالاً على دائرة DMUX ثنائية الطريقين من بتّة واحدة، تختار قيمة إدخال تحديدها (s) أي مخرج من مخرجيها يحصل على قيمة الإدخال A. كما يعرض مثالاً على دائرة مفكّك من بتّتين، تحدد بتّات إدخالها أي المخارج الأربعة يُضبط على 1. ويُعرض جدولا الحقيقة للدائرتين أيضاً.

مفكّك ثنائي من بتّة واحدة ومفكّك من بتّتين الشكل 7. مفكّك تضميم ثنائي الطريقين من بتّة واحدة، ومفكّك من بتّتين، مع جدولي حقيقتهما.

تُستخدم دوائر التخزين لبناء ذاكرة الحاسوب لتخزين القيم الثنائية. ويُسمى نوع ذاكرة الحاسوب المبنية من دوائر التخزين ذاكرة الوصول العشوائي الساكنة (SRAM). وتُستخدم لبناء تخزين سجلات المعالج والذاكرة المؤقتة على الرقاقة. وتستخدم الأنظمة عادةً ذاكرة الوصول العشوائي الديناميكية (DRAM) لتخزين الذاكرة الرئيسية (RAM). ويتطلب التصميم القائم على المكثفات في DRAM تجديدها دورياً بالقيمة التي تخزّنها، ومن هنا جاء وصف «الديناميكية». أما SRAM فتخزين قائم على الدوائر لا يحتاج إلى تجديد قيمه، ولهذا تُسمى ذاكرة وصول عشوائي ساكنة. والذاكرة القائمة على الدوائر أسرع لكنها أغلى من الذاكرة القائمة على المكثفات. ونتيجةً لذلك، تميل SRAM إلى الاستخدام للتخزين في أعلى التسلسل الهرمي للذاكرة (سجلات المعالج والذاكرة المؤقتة على الرقاقة)، وDRAM لتخزين الذاكرة الرئيسية (RAM). ونركّز في هذا الفصل على الذاكرة القائمة على الدوائر مثل SRAM.

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

مزلاج RS

المزلاج (latch) دائرة رقمية تخزّن (أو تتذكر) قيمة من بتّة واحدة. ومن الأمثلة مزلاج إعادة الضبط والضبط (reset-set latch أو RS latch). وله مدخلان S وR ومخرج واحد Q، وهو أيضاً القيمة المخزّنة في المزلاج. وقد يُخرج مزلاج RS إضافةً إلى ذلك NOT(Q)، أي نفي القيمة المخزّنة. ويعرض الشكل 1 دائرة مزلاج RS لتخزين بتّة واحدة.

مزلاج RS لتخزين بتّة واحدة الشكل 1. تخزّن دائرة مزلاج RS قيمة من بتّة واحدة.

أول ما يجب ملاحظته في مزلاج RS حلقة التغذية الراجعة من مخارجه إلى مدخلاته: فخرج بوابة NAND العليا (Q) دخل (a) لبوابة NAND السفلى، وخرج بوابة NAND السفلى (~Q) دخل (b) لبوابة NAND العليا. وعندما يكون المدخلان S وR كلاهما 1، يخزّن مزلاج RS القيمة Q. وبعبارة أخرى، عندما يكون S وR كلاهما 1، تكون قيمة خرج مزلاج RS هي Q مستقرة. ولمشاهدة هذا السلوك، تأمّل الشكل 2؛ فهو يعرض مزلاج RS يخزّن القيمة 1 ‏(Q هي 1). وعندما يكون R وS كلاهما 1، تكون قيمة الإدخال المرتد (a) إلى بوابة NAND السفلى هي قيمة Q وهي 1، لذا يكون خرج بوابة NAND السفلى 0 ‏(1 NAND 1 = 0). وقيمة الإدخال المرتد (b) إلى بوابة NAND العليا هي خرج بوابة NAND السفلى وهي 0. أما الدخل الآخر إلى بوابة NAND العليا فهو 1، أي قيمة S. ويكون خرج البوابة العليا 1 ‏(1 NAND 0 = 1). وهكذا، عندما يكون S وR كلاهما 1، تخزّن هذه الدائرة قيمة Q باستمرار (1 في هذا المثال).

مزلاج RS يخزّن القيمة 1 الشكل 2. مزلاج RS يخزّن قيمة من بتّة واحدة. يكون R وS كلاهما 1 عندما يخزّن المزلاج قيمة. والقيمة المخزّنة هي الخرج Q.

لتغيير القيمة المخزّنة في مزلاج RS، تُضبط قيمة واحد فقط من R أو S على 0. وعندما يخزّن المزلاج القيمة الجديدة، يُعاد ضبط R وS إلى 1. وتضمن دوائر التحكم حول مزلاج RS ألا يكون R وS معاً 0 في وقت واحد أبداً: فسيكون واحد منهما على الأكثر بقيمة 0، وتعني القيمة 0 لأحد R أو S أن قيمة تُكتب في مزلاج RS. ولتخزين القيمة 0 في مزلاج RS، يُضبط المدخل R على 0 (وتبقى قيمة S عند 1). ولتخزين القيمة 1 في مزلاج RS، يُضبط المدخل S على 0 (وتبقى قيمة R عند 1). فمثلاً، افترض أن مزلاج RS يخزّن حالياً 1. لكتابة 0 في المزلاج، تُضبط قيمة R على 0. وهذا يعني أن القيمتين 0 و1 تدخلان بوابة NAND السفلى التي تحسب نتيجة (0 NAND 1)، أي 1. وقيمة الخرج هذه 1 تُدخل أيضاً كمدخل b إلى بوابة NAND العليا (المعروض في الشكل 3 B). وبدخول جديد b قيمته 1 ومدخل S قيمته 1، تحسب بوابة NAND العليا قيمة خرج جديدة 0 لـ Q، وتُغذّى أيضاً كمدخل a إلى بوابة NAND السفلى (المعروض في الشكل 3 C). وبدخول a قيمته 0 وb قيمته 1، يخزّن المزلاج الآن 0. وعندما يُعاد ضبط R في النهاية إلى 1، يستمر مزلاج RS في تخزين القيمة 0 (المعروض في الشكل 3 D).

اضبط R على 0 للكتابة 0 في مزلاج RS الشكل 3. لكتابة 0 في مزلاج RS، اضبط R على 0 لحظياً.

مزلاج D المسوَّر

يضيف مزلاج D المسوَّر (gated D latch) دوائر إلى مزلاج RS لضمان ألا يستقبل أبداً إدخالاً بقيمة 0 لكل من R وS في وقت واحد. ويعرض الشكل 4 بناء مزلاج D المسوَّر.

يدمج مزلاج D المسوَّر مزلاج RS بدوائر تحكم كتابة مضافة الشكل 4. يخزّن مزلاج D المسوَّر قيمة من بتّة واحدة. وتتحكم مجموعته الأولى من بوابات NAND في الكتابات إلى مزلاج RS وتضمن ألا تكون قيمتا R وS معاً 0 في وقت واحد أبداً.

مدخل البيانات (D) إلى مزلاج D المسوَّر هو القيمة المطلوب تخزينها في الدائرة (0 أو 1). ويتحكم مدخل تمكين الكتابة (WE) في كتابة قيمة في مزلاج RS. وعندما يكون WE هو 0، يكون خرج بوابتَي NAND كلتيهما 1، فتكون قيمتا الإدخال S وR إلى مزلاج RS هي 1 (فيخزّن مزلاج RS قيمة). ولا يكتب مزلاج D المسوَّر قيمة D في مزلاج RS إلا عندما يكون WE هو 1. ولأن قيمة مدخل البيانات (D) تُنفى قبل إرسالها إلى بوابة NAND السفلى، يكون دخل واحدة فقط من بوابتَي NAND العليا أو السفلى هو 1. وهذا يعني أنه عندما تكون بتّة WE هي 1، يكون واحد فقط من R أو S هو 0. فمثلاً، عندما يكون D هو 1 وWE هو 1، تحسب بوابة NAND العليا (1 NAND 1) وتحسب بوابة NAND السفلى (0 NAND 1). ونتيجةً لذلك، يكون الدخل إلى S من بوابة NAND العليا 0 والدخل إلى R من بوابة NAND السفلى 1، ما يؤدي إلى كتابة القيمة 1 في مزلاج RS. وعندما يكون مدخل WE هو 0، تُخرج بوابتا NAND كلتاهما 1، فتبقى R وS عند 1. وبعبارة أخرى، عندما يكون WE هو 0، لا أثر لقيمة D في القيمة المخزّنة في مزلاج RS؛ ولا تُكتب قيمة D في المزلاج إلا عندما يكون WE هو 1. ولكتابة قيمة أخرى في مزلاج D المسوَّر، اضبط D على القيمة المطلوب تخزينها وWE على 1.

سجل المعالج

تُبنى دوائر التخزين متعددة البتّات بربط عدة دوائر تخزين من بتّة واحدة معاً. فمثلاً، دمج 32 مزلاج D من بتّة واحدة معاً ينتج دائرة تخزين من 32 بتّة يمكن استخدامها كسجل معالج من 32 بتّة، كما في الشكل 5. ولدائرة السجل قيمتا إدخال: قيمة بيانات من 32 بتّة وإشارة تمكين كتابة من بتّة واحدة. وداخلياً، يأخذ كل مزلاج D من بتّة واحدة بتّة واحدة من مدخل Data in ذي الـ32 بتّة في السجل كدخله D، ويأخذ كل مزلاج D من بتّة واحدة مدخل WE في السجل كمدخله WE. وخرج السجل هو القيمة ذات الـ32 بتّة المخزّنة عبر 32 مزلاج D من بتّة واحدة المكوّنة لدائرة السجل.

سجل معالج من 32 بتّة مبني من 32 مزلاج D مسوَّر من بتّة واحدة الشكل 5. يُبنى سجل المعالج من عدة مزلاجات D مسوَّرة (32 منها لسجل من 32 بتّة). وعندما يكون مدخل WE هو 1، تُكتب قيمة Data في السجل. وخرج Data هو القيمة المخزّنة.

تنفّذ وحدة المعالجة المركزية (CPU) وحدتي المعالجة والتحكم في معمارية فون نيومان، أي الجزءين الذين يديران تنفيذ تعليمات البرنامج على بيانات البرنامج (انظر الشكل 1).

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

وتُبنى وحدة المعالجة المركزية من لبنات دوائر الحساب/المنطق والتخزين والتحكم الأساسية. ومكوّناتها الوظيفية الرئيسية هي وحدة الحساب والمنطق (ALU) التي تنفّذ عمليات الحساب والمنطق؛ ومجموعة من السجلات العامة لتخزين بيانات البرنامج؛ وبعض دوائر التحكم وسجلات الأغراض الخاصة المستخدمة في تنفيذ التعليمات؛ وساعة تدير دوائر وحدة المعالجة المركزية لتنفيذ تعليمات البرنامج.

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

5.5.1. وحدة الحساب والمنطق

وحدة الحساب والمنطق دائرة معقّدة تنفّذ جميع عمليات الحساب والمنطق على الأعداد الصحيحة المؤشّرة وغير المؤشّرة. وتنفّذ وحدة فاصلة عائمة منفصلة عمليات حسابية على قيم الفاصلة العائمة. وتأخذ وحدة الحساب والمنطق قيم معاملات صحيحة وقيمة رمز التشغيل (opcode) تحدد العملية المطلوب تنفيذها (مثلاً الجمع). وتُخرج وحدة الحساب والمنطق القيمة الناتجة عن تنفيذ العملية المحددة على مدخلات المعاملات وقيم رموز الحالة (condition codes) التي ترمّز معلومات عن نتيجة العملية. وتحدد رموز الحالة الشائعة ما إذا كانت نتيجة وحدة الحساب والمنطق سالبة أو صفراً أو إذا وُجدت بتّة حمل خارج من العملية. فمثلاً، بالعبارة التالية في C

x = 6 + 8;

تبدأ وحدة المعالجة المركزية تنفيذ الجمع بتغذية قيم المعاملات (6 و8) والبتّات التي ترمّز عملية ADD إلى دائرة وحدة الحساب والمنطق. وتحسب وحدة الحساب والمنطق النتيجة وتُخرجها مع رموز حالة تشير إلى أن النتيجة غير سالبة وغير صفرية ولا تسبب حمل خارج. ويُرمَّز كل رمز حالة في بتّة واحدة. وتشير قيمة البتّة 1 إلى تحقق الشرط، وتشير القيمة 0 إلى عدم تحققه لنتيجة وحدة الحساب والمنطق. وفي مثالنا، يحدد نمط البتّات 000 مجموعة الشروط الثلاثة المرتبطة بتنفيذ 6+8: النتيجة ليست سالبة (0)، وليست صفراً (0)، وقيمة الحمل الخارج صفر (0).

وتُستخدم رموز الحالة، التي تضبطها وحدة الحساب والمنطق كجزء من تنفيذها عمليةً ما، أحياناً في تعليمات لاحقة تختار إجراءً بناءً على شرط معيّن. فمثلاً، يمكن لتعليمة ADD حساب الجزء (x + 8) من عبارة if التالية:

if( (x + 8) != 0 ) {
    x++;
}

يضبط تنفيذ وحدة الحساب والمنطق لتعليمة ADD رموز الحالة بناءً على نتيجة جمع (x + 8). وتختبر تعليمة قفز شرطية تُنفَّذ بعد تعليمة ADD بتّات رمز الحالة التي ضبطتها تعليمة ADD، فإما تقفز (تتجاوز تنفيذ التعليمات في جسم if) أو لا، بناءً على قيمتها. فمثلاً، إذا ضبطت تعليمة ADD رمز حالة الصفر على 0، فلن تقفز تعليمة القفز الشرطي متجاوزةً التعليمات المرتبطة بجسم if (فقيمة 0 لرمز حالة الصفر تعني أن نتيجة ADD لم تكن صفراً). وإذا كان رمز حالة الصفر هو 1، فستقفز متجاوزةً تعليمات جسم if. ولتنفيذ قفزة متجاوزة لمجموعة تعليمات، تكتب وحدة المعالجة المركزية عنوان ذاكرة التعليمة الأولى التي تلي تعليمات جسم if في عدّاد البرنامج (PC)، الذي يحتوي عنوان التعليمة التالية المطلوب تنفيذها.

تجمع دائرة وحدة الحساب والمنطق عدة دوائر حساب ومنطق (لتنفيذ مجموعة عملياتها) مع دائرة مضمِّم لاختيار خرج وحدة الحساب والمنطق. وبدلاً من محاولة تنشيط الدائرة الحسابية المرتبطة بالعملية المحددة فقط، ترسل وحدة حساب ومنطق بسيطة قيم مدخلات معاملاتها إلى جميع دوائرها الحسابية والمنطقية الداخلية. وتدخل مخارج جميع دوائر وحدة الحساب والمنطق الداخلية الحسابية والمنطقية إلى دائرة المضمِّم فيها، التي تختار خرج وحدة الحساب والمنطق. ويُستخدم مدخل رمز التشغيل إلى وحدة الحساب والمنطق كمدخل إشارة إلى المضمِّم لاختيار العملية الحسابية/المنطقية المطلوب اختيارها كخرج لوحدة الحساب والمنطق. ويستند خرج رمز الحالة إلى خرج المضمِّم مدمجاً بدوائر تختبر قيمة الخرج لتحديد كل بتّة رمز حالة.

يعرض الشكل 2 مثالاً على دائرة وحدة حساب ومنطق تنفّذ أربع عمليات مختلفة (ADD وOR وAND وEQUALS) على معاملين من 32 بتّة. كما تنتج خرج رمز حالة واحداً يشير إلى ما إذا كانت نتيجة العملية صفراً. لاحظ أن وحدة الحساب والمنطق توجّه رمز التشغيل إلى مضمِّم يختار أي نتائجها الحسابية الأربع تُخرجها.

وحدة حساب ومنطق بأربع عمليات ورمز حالة واحد للصفر الشكل 2. وحدة حساب ومنطق رباعية الوظائف تنفّذ ADD وOR وAND وEQUALS على معاملين من 32 بتّة. ولها بتّة خرج واحدة لرمز الحالة تحدد ما إذا كانت النتيجة 0.

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

  | OPCODE BITS | OPERAND A SOURCE | OPERAND B SOURCE | RESULT DESTINATION |

وبحسب معمارية المعالج، قد ترمّز بتّات مصدر المعامل سجلاً في المعالج أو عنوان الذاكرة التي تخزّن قيمة المعامل أو قيم معاملات حرفية. فمثلاً، في تعليمة لتنفيذ 6 + 8، يمكن ترميز القيمتين الحرفيتين 6 و8 مباشرةً في بتّات محدِّد المعامل في التعليمة.

وبالنسبة إلى وحدة الحساب والمنطق لدينا، يتطلب رمز التشغيل بتّتين لأن الوحدة تدعم أربع عمليات، ويمكن لبتّتين ترميز أربع قيم متميزة (00 و01 و10 و11)، واحدة لكل عملية. وبشكل عام، تحتاج وحدة حساب ومنطق تنفّذ N عملية متميزة إلى log2(N) بتّة لرمز التشغيل لتحديد نتيجة العملية المطلوب إخراجها من الوحدة.

يعرض الشكل 3 مثالاً على كيفية استخدام بتّات رمز التشغيل والمعامل في تعليمة ADD كمدخل إلى وحدة الحساب والمنطق لدينا.

بتّات التعليمة ورمز التشغيل تُرسَل كثلاث قيم مدخل إلى وحدة الحساب والمنطق الشكل 3. تستخدم وحدة الحساب والمنطق بتّات رمز التشغيل من التعليمة لاختيار العملية المطلوب إخراجها. وفي هذا المثال، تُغذّى بتّات مختلفة من تعليمة ADD إلى مدخلي المعامل ورمز التشغيل في وحدة الحساب والمنطق لتنفيذ جمع 6 و8.

5.5.2. ملف السجلات

في أعلى التسلسل الهرمي للذاكرة، تخزّن مجموعة السجلات العامة في المعالج قيماً مؤقتة. وتوفّر المعالجات عدداً صغيراً جداً من السجلات، عادةً 8-32 (فمثلاً، توفّر معمارية IA32 ثمانية، وMIPS ستة عشر، وARM ثلاثة عشر). وكثيراً ما تحصل التعليمات على قيم معاملاتها من السجلات العامة أو تخزّن نتائجها فيها. فمثلاً، قد تُرمَّز تعليمة ADD كـ*«أضف القيمة من السجل 1 إلى القيمة من السجل 2 وخزّن النتيجة في السجل 3»*.

تُنظَّم مجموعة السجلات العامة في المعالج في دائرة ملف السجلات (register file). ويتألف ملف السجلات من مجموعة دوائر سجلات لتخزين قيم البيانات وبعض دوائر التحكم للتحكم في القراءات والكتابات في سجلاته. وللدائرة عادةً خط إدخال بيانات واحد للقيمة المطلوب كتابتها في أحد سجلاته، وخطا إخراج بيانات لقراءة قيمتين من سجلاته في وقت واحد.

يعرض الشكل 4 مثالاً على دائرة ملف سجلات بأربعة سجلات. وتتحكم في قيمتَي خرجها (Data out0 وData out1) دائرتا مضمِّم. ويُغذّى كل من مدخلَي اختيار القراءة (Sr0 وSr1) إلى أحد المضمِّمين لاختيار قيمة السجل للخرج المقابل. ويُرسَل مدخل البيانات إلى ملف السجلات (خط Data in) إلى كل دائرة سجل، ويُمرَّر مدخل تمكين الكتابة (WE) عبر دائرة مفكّك تضميم (DMUX) أولاً قبل إرساله إلى كل دائرة سجل. وتأخذ دائرة DMUX قيمة إدخال واحدة وتختار أي المخارج الـN ترسل القيمة إليه، وترسل 0 إلى المخارج الـN-1 المتبقية. ويُرسَل مدخل اختيار الكتابة (Sw) إلى ملف السجلات إلى دائرة DMUX لاختيار سجل الوجهة لقيمة WE. وعندما تكون قيمة مدخل WE في ملف السجلات 0، لا تُكتب قيمة في أي سجل لأن بتّة WE لكل سجل تحصل أيضاً على 0 (وبذلك لا أثر لـData in في القيم المخزّنة في السجلات). وعندما تكون بتّة WE هي 1، يُخرج DMUX قيمة بتّة WE مقدارها 1 إلى السجل المحدد بإدخال اختيار الكتابة (Sw) فقط، ما يؤدي إلى كتابة قيمة Data in في السجل المحدد فقط.

ملف السجلات الشكل 4. ملف السجلات: مجموعة سجلات المعالج العامة المستخدمة لتخزين قيم معاملات التعليمات ونتائجها.

سجلات الأغراض الخاصة

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

5.5.3. المعالج

بدائرتَي وحدة الحساب والمنطق وملف السجلات، يمكننا بناء الأجزاء الرئيسية لوحدة المعالجة المركزية كما في الشكل 5. ولأن معاملات التعليمات تأتي غالباً من قيم مخزّنة في السجلات العامة، ترسل مخارج ملف السجلات بيانات إلى مدخلات وحدة الحساب والمنطق. وبالمثل، ولأن نتائج التعليمات تُخزَّن غالباً في السجلات، يُرسَل خرج نتيجة وحدة الحساب والمنطق كمدخل إلى ملف السجلات. ولدى وحدة المعالجة المركزية دوائر إضافية لنقل البيانات بين وحدة الحساب والمنطق وملف السجلات ومكوّنات أخرى (مثل الذاكرة الرئيسية).

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

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

يُنفَّذ تنفيذ التعليمات على عدة مراحل. وتنفّذ المعماريات المختلفة أعداداً مختلفة من المراحل، لكن معظمها ينفّذ مرحلتي الجلب والفك ومرحلتي التنفيذ والكتابة الخلفية لتنفيذ التعليمات في أربع مراحل منفصلة أو أكثر. ونركّز في مناقشتنا لتنفيذ التعليمات على هذه المراحل الأربع، ونستخدم تعليمة ADD كمثالنا. ويُرمَّز مثال تعليمة ADD كما في الشكل 1.

صيغة التعليمة المستخدمة كمثال الشكل 1. صيغة تعليمة مثال لعملية بثلاثة سجلات. تُرمَّز التعليمة ثنائياً بمجموعات فرعية من بتّاتها تقابل ترميزات أجزاء مختلفة من التعليمة: العملية (رمز التشغيل)، والسجلان المصدران (المعاملان)، وسجل الوجهة لتخزين نتيجة العملية. ويعرض المثال ترميز تعليمة ADD بهذه الصيغة.

لتنفيذ تعليمة، تجلب وحدة المعالجة المركزية أولاً التعليمة التالية من الذاكرة إلى سجل أغراض خاصة، هو سجل التعليمات (IR). ويُخزَّن عنوان ذاكرة التعليمة المطلوب جلبها في سجل أغراض خاصة آخر، هو عدّاد البرنامج (PC). ويتتبع PC عنوان ذاكرة التعليمة التالية المطلوب جلبها وتُزاد قيمته كجزء من تنفيذ مرحلة الجلب، فيخزّن قيمة عنوان ذاكرة التعليمة التالية مباشرة. فمثلاً، إذا كانت جميع التعليمات بطول 32 بتّة، فتُزاد قيمة PC بمقدار 4 (لكل بايت، أي 8 بتّات، عنوان فريد) لتخزين عنوان ذاكرة التعليمة التي تلي التعليمة الجاري جلبها مباشرة. وتزيد دوائر حسابية منفصلة عن وحدة الحساب والمنطق قيمة PC. وقد تتغير قيمة PC أيضاً أثناء مرحلة الكتابة الخلفية. فمثلاً، تقفز بعض التعليمات إلى عناوين محددة، مثل تلك المرتبطة بتنفيذ الحلقات if-else أو استدعاءات الدوال. ويعرض الشكل 2 مرحلة الجلب من التنفيذ.

مرحلة الجلب في تنفيذ التعليمات من المعالج الشكل 2. مرحلة الجلب من تنفيذ التعليمات: تُقرأ التعليمة عند قيمة عنوان الذاكرة المخزّنة في سجل PC من الذاكرة وتُخزَّن في IR. وتُزاد قيمة PC أيضاً في نهاية هذه المرحلة (إذا كانت التعليمات 4 بايتات، فالعنوان التالي 1238؛ ويختلف حجم التعليمة الفعلي بحسب المعمارية ونوع التعليمة).

بعد جلب التعليمة، تفكّ وحدة المعالجة المركزية بتّات التعليمة المخزّنة في سجل IR إلى أربعة أجزاء: ترمّز البتّات عالية الرتبة في التعليمة رمز التشغيل الذي يحدد العملية المطلوب تنفيذها (مثل ADD وSUB وOR وغيرها)، وتُقسَّم البتّات المتبقية إلى ثلاث مجموعات فرعية تحدد مصدرَي المعاملين ووجهة النتيجة. وفي مثالنا، نستخدم سجلات لكلا المصدرين ووجهة النتيجة. ويُرسَل رمز التشغيل على أسلاك تدخل إلى وحدة الحساب والمنطق، وتُرسَل بتّات المصدر على أسلاك تدخل إلى ملف السجلات. وتُرسَل بتّات المصدر إلى مدخلَي اختيار القراءة (Sr0 وSr1) اللذين يحددان قيم السجلات المطلوب قراءتها من ملف السجلات. وتُعرض مرحلة الفك في الشكل 3.

مرحلة الفك في تنفيذ التعليمات من المعالج الشكل 3. مرحلة الفك من تنفيذ التعليمات: افصل بتّات التعليمة في IR إلى مكوّنات وأرسلها كمدخل إلى وحدة الحساب والمنطق وملف السجلات. تُرسَل بتّات رمز التشغيل في IR إلى مدخل اختيار وحدة الحساب والمنطق لاختيار العملية المطلوب تنفيذها. وتُرسَل مجموعتا بتّات المعامل في IR إلى مدخلي اختيار ملف السجلات لاختيار السجلات المطلوب قراءة قيم المعاملات منها. وتُرسَل بتّات الوجهة في IR إلى ملف السجلات في مرحلة الكتابة الخلفية. وهي تحدد السجل المطلوب كتابة نتيجة وحدة الحساب والمنطق فيه.

بعد أن تحدد مرحلة الفك العملية المطلوب تنفيذها ومصدرَي المعاملين، تنفّذ وحدة الحساب والمنطق العملية في المرحلة التالية، وهي مرحلة التنفيذ. وتأتي مدخلات البيانات إلى وحدة الحساب والمنطق من مخرجَي ملف السجلات، ويأتي مدخل اختيارها من بتّات رمز التشغيل في التعليمة. وتنتشر هذه المدخلات عبر وحدة الحساب والمنطق لإنتاج نتيجة تدمج قيم المعاملات مع العملية. وفي مثالنا، تُخرج وحدة الحساب والمنطق نتيجة جمع القيمة المخزّنة في Reg1 إلى القيمة المخزّنة في Reg3، وتُخرج قيم رموز الحالة المرتبطة بقيمة النتيجة. وتُعرض مرحلة التنفيذ في الشكل 4.

مرحلة التنفيذ الشكل 4. مرحلة التنفيذ من تنفيذ التعليمات: تنفّذ وحدة الحساب والمنطق العملية المحددة (من بتّات رمز التشغيل في التعليمة) على قيم مدخلاتها (من مخارج ملف السجلات).

وفي مرحلة الكتابة الخلفية، تُخزَّن نتيجة وحدة الحساب والمنطق في سجل الوجهة. ويستقبل ملف السجلات خرج نتيجة وحدة الحساب والمنطق على مدخله Data in، وسجل الوجهة (من بتّات التعليمة في IR) على مدخله write-select ‏(Sw)، والقيمة 1 على مدخله WE. فمثلاً، إذا كان سجل الوجهة هو Reg0، تُرسَل البتّات التي ترمّز Reg0 في IR كمدخل Sw إلى ملف السجلات لاختيار سجل الوجهة. ويُرسَل خرج وحدة الحساب والمنطق كمدخل Data in إلى ملف السجلات، وتُضبط بتّة WE على 1 لتمكين كتابة نتيجة وحدة الحساب والمنطق في Reg0. وتُعرض مرحلة الكتابة الخلفية في الشكل 5.

مرحلة الكتابة الخلفية الشكل 5. مرحلة الكتابة الخلفية من تنفيذ التعليمات: تُكتب نتيجة مرحلة التنفيذ (خرج وحدة الحساب والمنطق) في سجل الوجهة في ملف السجلات. وخرج وحدة الحساب والمنطق هو مدخل Data in في ملف السجلات، وتذهب بتّات وجهة التعليمة إلى مدخل اختيار الكتابة (Sw) في ملف السجلات، وتُضبط بتّة WE على 1 لتمكين كتابة قيمة Data in في سجل الوجهة المحدد.

5.6.1. التنفيذ بقيادة الساعة

تدير الساعة تنفيذ وحدة المعالجة المركزية للتعليمات، فتطلق بداية كل مرحلة. وبعبارة أخرى، تستخدم وحدة المعالجة المركزية الساعة لتحديد متى تصبح مدخلات الدوائر المرتبطة بكل مرحلة جاهزة لاستخدام الدائرة لها، وتتحكم في متى تمثّل مخارج الدوائر نتائج صالحة من مرحلة ما ويمكن استخدامها كمدخلات لدوائر أخرى تنفّذ المرحلة التالية. تقيس ساعة المعالج زمناً متقطعاً لا زمناً متصلاً. وبعبارة أخرى، يوجد زمن 0 يليه زمن 1 يليه زمن 2 وهكذا لكل نبضة ساعة تالية. ويقيس زمن دورة الساعة في المعالج المدة بين كل نبضتي ساعة. وسرعة الساعة في المعالج (أو معدل الساعة) هي 1/(clock cycle time). وتُقاس عادةً بالميغاهرتز (MHz) أو الغيغاهرتز (GHz). فمعدل ساعة 1 ميغاهرتز يعني مليون نبضة ساعة في الثانية، و1 غيغاهرتز يعني مليار نبضة ساعة في الثانية. ومعدل الساعة مقياس لسرعة تشغيل المعالج، وتقدير للعدد الأقصى من التعليمات في الثانية التي يستطيع المعالج تنفيذها. فمثلاً، على معالجات قياسية بسيطة كمعالجنا المثال، قد يبلغ معالج بسرعة 2 غيغاهرتز أقصى معدل تنفيذ تعليمات قدره مليارا تعليمة في الثانية (أو تعليمتان كل نانوثانية).

ورغم أن زيادة معدل الساعة على آلة واحدة ستحسّن أداءها، فإن معدل الساعة وحده ليس مقياساً ذا معنى لمقارنة أداء معالجات مختلفة. فمثلاً، تتطلب بعض المعماريات (مثل RISC) مراحل أقل لتنفيذ التعليمات من غيرها (مثل CISC). وفي المعماريات ذات مراحل التنفيذ الأقل، قد تعطي ساعة أبطأ العدد نفسه من التعليمات المكتملة في الثانية كما في معمارية أخرى بمعدل ساعة أسرع لكن بمراحل تنفيذ أكثر. غير أن مضاعفة سرعة الساعة في معالج دقيق محدد ستضاعف تقريباً سرعة تنفيذه للتعليمات.

معدلات الساعة وأداء المعالج

تاريخياً، كانت زيادة معدل الساعة (إلى جانب تصميم معماريات دقيقة أكثر تعقيداً وقوة يمكن لساعة أسرع أن تديرها) طريقة فعالة جداً لمعماريي الحواسيب لتحسين أداء المعالجات. فمثلاً، في عام 1974، كان معالج Intel 8080 يعمل بتردد 2 ميغاهرتز (معدل ساعة مليوني دورة في الثانية). وكان معدل ساعة معالج Intel Pentium Pro، المقدَّم عام 1995، هو 150 ميغاهرتز (150 مليون دورة في الثانية)، ومعدل ساعة معالج Intel Pentium 4، المقدَّم عام 2000، هو 1.3 غيغاهرتز (1.3 مليار دورة في الثانية). وقد بلغت معدلات الساعة ذروتها في منتصف العقد الأول من القرن وحتى أواخره مع معالجات مثل IBM z10 الذي كان معدل ساعته 4.4 غيغاهرتز.

غير أن معدلات ساعة المعالجات بلغت اليوم حدّها الأقصى بسبب مشاكل تتعلق بالتعامل مع تبديد حرارة الساعات الأسرع. ويُعرف هذا الحد بـجدار الطاقة (power wall). وقد أدى جدار الطاقة إلى تطوير معالجات متعددة الأنوية بدءاً من منتصف العقد الأول من القرن. والمعالجات متعددة الأنوية لها عدة أنوية معالجة «بسيطة» لكل رقاقة، وكل نواة تديرها ساعة لم يزد معدلها عن النواة من الجيل السابق. وتصميم المعالجات متعددة الأنوية طريقة لتحسين أداء المعالج دون الحاجة إلى زيادة معدل ساعة المعالج.

دائرة الساعة

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

تولّد دائرة الساعة نمطاً منتظماً من 1 و0 الشكل 6. النمط المنتظم من 1 و0 لخرج دائرة ساعة. وتشكّل كل متتالية من 1 و0 دورة ساعة.

ودورة الساعة (أو النبضة) متتالية فرعية من 1 و0 في نمط دائرة الساعة. ويُسمى الانتقال من 1 إلى 0 أو من 0 إلى 1 حافة الساعة (clock edge). وتُطلق حواف الساعة تغييرات الحالة في دوائر المعالج، فتدار تنفيذ التعليمات. وتشير حافة الساعة الصاعدة (الانتقال من 0 إلى 1 في بداية دورة ساعة جديدة) إلى حالة تكون فيها قيم الإدخال جاهزة لمرحلة من مراحل تنفيذ التعليمات. فمثلاً، تشير حافة الصعود إلى أن قيم الإدخال إلى دائرة وحدة الحساب والمنطق جاهزة. وبينما تكون قيمة الساعة 1، تنتشر هذه المدخلات عبر الدائرة حتى يصبح خرج الدائرة جاهزاً. ويُسمى ذلك تأخير الانتشار (propagation delay) عبر الدائرة. فمثلاً، بينما تكون إشارة الساعة 1، تنتشر قيم الإدخال إلى وحدة الحساب والمنطق عبر دوائر عملياتها ثم عبر المضمِّم لإنتاج الخرج الصحيح من وحدة الحساب والمنطق للعملية التي تدمج قيم الإدخال. وعند حافة الهبوط (الانتقال من 1 إلى 0)، تكون مخارج المرحلة مستقرة وجاهزة للانتشار إلى الموقع التالي (المعروض بـ«الخرج جاهز» في الشكل 7). فمثلاً، يكون خرج وحدة الحساب والمنطق جاهزاً عند حافة الهبوط. وطوال مدة قيمة الساعة 0، ينتشر خرج وحدة الحساب والمنطق إلى مدخلات ملف السجلات. وفي دورة الساعة التالية، تشير حافة الصعود إلى أن قيمة إدخال ملف السجلات جاهزة للكتابة في سجل (المعروض بـ«إدخال جديد» في الشكل 7).

دورة ساعة الشكل 7. تُطلق حافة الصعود لدورة ساعة جديدة تغييرات في مدخلات الدوائر التي تتحكم فيها. وتُطلق حافة الهبوط عندما تصبح المخارج صالحة من الدوائر التي تتحكم فيها.

طول دورة الساعة (أو معدل الساعة) محدود بأطول تأخير انتشار عبر أي مرحلة من مراحل تنفيذ التعليمات. وعادةً ما تكون مرحلة التنفيذ والانتشار عبر وحدة الحساب والمنطق أطول المراحل. وبالتالي، يجب ألا يكون نصف زمن دورة الساعة أسرع من الزمن الذي تستغرقه قيم إدخال وحدة الحساب والمنطق لتنتشر عبر أبطأ دائرة عملية إلى مخارج الوحدة (وبعبارة أخرى، تعكس المخارج نتائج العملية على المدخلات). فمثلاً، في وحدة الحساب والمنطق رباعية العمليات لدينا (OR وADD وAND وEQUALS)، تتمتع دائرة جامع الحمل المتموّج بأطول تأخير انتشار وتحدد الحد الأدنى لطول دورة الساعة.

ولأن إكمال مرحلة واحدة من تنفيذ تعليمات المعالج يستغرق دورة ساعة واحدة، فإن معالجاً بتسلسل تنفيذ من أربع مراحل (الجلب والفك والتنفيذ والكتابة الخلفية؛ انظر الشكل 8) يكمل تعليمة واحدة على الأكثر كل أربع دورات ساعة.

أربع دورات ساعة لإكمال تعليمة واحدة الشكل 8. تنفيذ التعليمات من أربع مراحل يستغرق أربع دورات ساعة لإكماله.

فمثلاً، إذا كان معدل الساعة 1 غيغاهرتز، فتستغرق التعليمة الواحدة 4 نانوثانية لإكمالها (تستغرق كل مرحلة من المراحل الأربع 1 نانوثانية). وبمعدل ساعة 2 غيغاهرتز، تستغرق التعليمة الواحدة 2 نانوثانية فقط.

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

5.6.2. تجميع كل ذلك: المعالج في حاسوب كامل

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

يعرض الشكل 9 مثالاً على معالج في سياق حاسوب حديث كامل، تُنفّذ مكوّناته معاً معمارية فون نيومان.

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

5.6.3. الحواشي

  1. من الاقتراحات «Computer Architecture: A Quantitative Approach» لجون هينيسي وديفيد باترسون.

يستغرق معالجنا الرباعي المراحل أربع دورات لتنفيذ تعليمة واحدة: تُستخدم الدورة الأولى لجلب التعليمة من الذاكرة؛ والثانية لفك التعليمة وقراءة المعاملات من ملف السجلات؛ والثالثة لتنفيذ وحدة الحساب والمنطق العملية؛ والرابعة لكتابة نتيجة وحدة الحساب والمنطق عائدةً إلى سجل في ملف السجلات. ولتنفيذ تسلسل من N تعليمة يستغرق الأمر 4N دورة ساعة، حيث يُنفَّذ كل منها واحداً في كل مرة، بالترتيب، بواسطة المعالج.

12 دورة لإكمال 3 تعليمات الشكل 1. تنفيذ ثلاث تعليمات يستغرق 12 دورة إجمالاً.

يعرض الشكل 1 ثلاث تعليمات تستغرق إجمالاً 12 دورة للتنفيذ، بأربع دورات لكل تعليمة، ما ينتج CPI مقداره 4 (وCPI هو متوسط عدد الدورات اللازمة لتنفيذ تعليمة). غير أنه يمكن تحسين دوائر التحكم في المعالج لتحقيق قيمة CPI أفضل (أقل).

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

تخطيط خطوط الأنابيب في المعالج (pipelining) هو فكرة بدء تنفيذ التعليمة التالية قبل أن تكمل التعليمة الحالية تنفيذها بالكامل. وينفّذ تخطيط خطوط الأنابيب التعليمات بالترتيب، لكنه يتيح لتنفيذ تسلسل من التعليمات أن يتداخل. فمثلاً، في الدورة الأولى تدخل التعليمة الأولى مرحلة الجلب. وفي الدورة الثانية، تنتقل التعليمة الأولى إلى مرحلة الفك، وتدخل التعليمة الثانية في الوقت نفسه مرحلة الجلب. وفي الدورة الثالثة، تنتقل التعليمة الأولى إلى مرحلة التنفيذ، والثانية إلى مرحلة الفك، وتُجلب التعليمة الثالثة من الذاكرة. وفي الدورة الرابعة، تنتقل التعليمة الأولى إلى مرحلة الكتابة الخلفية وتكتمل، وتنتقل الثانية إلى مرحلة التنفيذ، والثالثة إلى مرحلة الفك، وتدخل الرابعة مرحلة الجلب. وعند هذه النقطة يمتلئ خط أنابيب التعليمات في المعالج — فكل مرحلة من مراحل المعالج تنفّذ تعليمات البرنامج فعلياً، وكل تعليمة لاحقة تتأخر مرحلة واحدة عن سابقتها. وعندما يمتلئ خط الأنابيب، يكمل المعالج تنفيذ تعليمة واحدة كل دورة ساعة!

التنفيذ بخط أنابيب للتعليمات الشكل 2. تخطيط خطوط الأنابيب: تداخل تنفيذ التعليمات لتحقيق تعليمة مكتملة واحدة في كل دورة. وتشير الدائرة إلى أن المعالج بلغ الحالة المستقرة بإكمال تعليمة واحدة في كل دورة.

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

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

وتُستخدم فكرة تخطيط خطوط الأنابيب في سياقات أخرى في علم الحاسوب أيضاً لتسريع التنفيذ، وتنطبق الفكرة على كثير من التطبيقات غير الحاسوبية كذلك. فمثلاً، تأمّل مهمة غسل عدة حمولات ملابس بغسالة واحدة. فإذا كان إكمال حمولة غسيل واحدة يتألف من أربع خطوات (الغسل والتجفيف والطي والترتيب)، فيمكن بعد غسل الحمولة الأولى وضع الحمولة الثانية في الغسالة بينما تكون الأولى في المجففة، بتداخل غسل حمولات الغسيل الفردية لتسريع الوقت الكلي لغسل أربع حمولات. وخطوط تجميع المصانع مثال آخر على تخطيط خطوط الأنابيب.

استخدمنا في مناقشتنا لكيفية تنفيذ المعالج لتعليمات البرنامج وتخطيط خطوط أنابيبه خط أنابيب بسيطاً من أربع مراحل وتعليمة ADD مثالاً. ولتنفيذ التعليمات التي تُحمّل وتخزّن قيماً بين الذاكرة والسجلات، يُستخدم خط أنابيب من خمس مراحل. ويتضمن خط الأنابيب الخماسي مرحلة ذاكرة للوصول إلى الذاكرة: الجلب-الفك-التنفيذ-الذاكرة-الكتابة الخلفية. وقد يكون لمعالجات مختلفة مراحل خط أنابيب أقل أو أكثر من خط الأنابيب الخماسي النموذجي. فمثلاً، كانت معمارية ARM الأولى بثلاث مراحل (الجلب والفك والتنفيذ، حيث كانت مرحلة التنفيذ تنفّذ وظيفتي تنفيذ وحدة الحساب والمنطق والكتابة الخلفية لملف السجلات). أما معماريات ARM الأحدث فلها أكثر من خمس مراحل في خطوط أنابيبها. وكانت معماريات Intel Pentium الأولى بخط أنابيب من خمس مراحل، لكن المعماريات اللاحقة كان لها مراحل أعلى بكثير. فمثلاً، لدى Intel Core i7 خط أنابيب من 14 مرحلة.

تذكّر أن تخطيط خطوط الأنابيب يحسّن أداء المعالج بتداخل تنفيذ تعليمات متعددة. وقد وصفنا في مناقشتنا السابقة عن تخطيط خطوط الأنابيب خط أنابيب بسيطاً من أربع مراحل بالمراحل الأساسية: الجلب (F) والفك (D) والتنفيذ (E) والكتابة الخلفية (W). وفي مناقشتنا التالية، ننظر أيضاً في مرحلة خامسة هي الذاكرة (M) التي تمثّل وصولاً إلى ذاكرة البيانات. وبالتالي يتألف خط الأنابيب الخماسي لدينا من المراحل التالية:

  • الجلب (F): قراءة تعليمة من الذاكرة (يشير إليها عدّاد البرنامج).
  • الفك (D): قراءة سجلات المصدر وضبط منطق التحكم.
  • التنفيذ (E): تنفيذ التعليمة.
  • الذاكرة (M): القراءة من ذاكرة البيانات أو الكتابة فيها.
  • الكتابة الخلفية (W): تخزين نتيجة في سجل وجهة.

تذكّر أن المصرّف يحوّل أسطر الشيفرة إلى سلسلة من تعليمات شيفرة الآلة لينفّذها المعالج. ولغة التجميع صورة مقروءة بشرياً من شيفرة الآلة. ويعرض المقتطف التالي سلسلة من تعليمات لغة تجميع مختلقة:

MOV M[0x84], Reg1     # move value at memory address 0x84 to register Reg1
ADD 2, Reg1, Reg1     # add 2 to value in Reg1 and store result in Reg1
MOV 4, Reg2           # copy the value 4 to register Reg2
ADD Reg2, Reg2, Reg2  # compute Reg2 + Reg2, store result in Reg2
JMP L1<0x14>          # jump to executing code at L1 (code address 0x14)

لا تقلق إن واجهت صعوبة في تحليل المقتطف — سنغطي لغة التجميع بمزيد من التفصيل في الفصول القادمة. ويكفي الآن التركيز على مجموعة الحقائق التالية:

  • كل معمارية ISA تعرّف مجموعة تعليمات.
  • تعمل كل تعليمة على معامل واحد أو أكثر (أي سجلات أو ذاكرة أو قيم ثابتة).
  • ليست كل التعليمات تحتاج إلى العدد نفسه من مراحل خط الأنابيب للتنفيذ.

في مناقشتنا السابقة، افتُرض أن كل تعليمة تستغرق العدد نفسه من الدورات للتنفيذ؛ غير أن هذا ليس هو الحال عادةً. فمثلاً، تتطلب تعليمة MOV الأولى المراحل الخمس كلها، لأنها تتطلب نقل بيانات من الذاكرة إلى سجل. وفي المقابل، تتطلب التعليمات الثلاث التالية أربع مراحل فقط (F وD وE وW) للتنفيذ بما أن العمليات لا تتضمن إلا سجلات لا الذاكرة. أما التعليمة الأخيرة (JMP) فهي نوع من التعليمات الفرعية أو الشرطية. والغرض منها نقل مسار التحكم إلى جزء آخر من الشيفرة. وتحديداً، تشير العناوين في منطقة الشيفرة من الذاكرة إلى تعليمات مختلفة في الملف التنفيذي. ولأن تعليمة JMP لا تحدّث سجلاً عاماً، تُحذف مرحلة الكتابة الخلفية، فيلزم ثلاث مراحل فقط (F وD وE). ونغطي التعليمات الشرطية بمزيد من التفصيل في الفصول القادمة عن لغة التجميع.

تحدث عثرة خط الأنابيب (pipeline stall) عندما تُضطر أي تعليمة إلى انتظار تعليمة أخرى لتنتهي من التنفيذ قبل أن تستطيع المتابعة. ويفعل المصرّفون والمعالجات ما بوسعهم لتجنّب عثرات خط الأنابيب من أجل تعظيم الأداء.

5.8.1. اعتبار في تخطيط خطوط الأنابيب: مخاطر البيانات

تحدث مخاطر البيانات (data hazard) عندما تحاول تعليمتان الوصول إلى بيانات مشتركة في خط أنابيب التعليمات. وكمثال، تأمّل أول زوج من التعليمات من مقتطف الشيفرة أعلاه:

MOV M[0x84], Reg1     # move value at memory address 0x84 to register Reg1
ADD 2, Reg1, Reg1     # add 2 to value in Reg1 and store result in Reg1

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

تذكّر أن تعليمة MOV هذه تتطلب خمس مراحل (لأنها تتضمن وصولاً إلى الذاكرة)، بينما تتطلب تعليمة ADD أربع مراحل فقط. وفي هذا السيناريو، ستحاول التعليمتان الكتابة إلى السجل Reg1 في الوقت نفسه (انظر الشكل 1).

يمنع المعالج السيناريو المذكور آنفاً بأن يُلزم أولاً كل تعليمة باستغراق خمس مراحل من خط الأنابيب للتنفيذ. وبالنسبة إلى التعليمات التي تستغرق عادةً أقل من خمس مراحل، تضيف وحدة المعالجة المركزية تعليمة «لا عملية» (NOP) (وتُسمى أيضاً «فقاعة» في خط الأنابيب) لتحل محل تلك المرحلة.

غير أن المشكلة لا تزال غير محلولة بالكامل. ولأن هدف التعليمة الثانية إضافة 2 إلى القيمة المخزّنة في السجل Reg1، تحتاج تعليمة MOV إلى الانتهاء من الكتابة إلى السجل Reg1 قبل أن تستطيع تعليمة ADD التنفيذ بشكل صحيح. وتوجد مشكلة مشابهة في التعليمتين التاليتين:

MOV 4, Reg2           # copy the value 4 to register Reg2
ADD Reg2, Reg2, Reg2  # compute Reg2 + Reg2, store result in Reg2

خطر بيانات 2 الشكل 2. يمكن للمعالج تقليل الضرر الناتج عن مخاطر خط الأنابيب بتمرير المعاملات بين التعليمات.

تحمّل هاتان التعليمتان القيمة 4 في السجل Reg2 ثم تضربانها في 2 (بإضافتها إلى نفسها). ومرة أخرى، تُضاف فقاعات لإلزام كل تعليمة باستغراق خمس مراحل من خط الأنابيب. وفي هذه الحالة، وبصرف النظر عن الفقاعات، تحدث مرحلة تنفيذ التعليمة الثانية قبل أن تنتهي التعليمة الأولى من كتابة القيمة المطلوبة (4) في السجل Reg2.

إضافة مزيد من الفقاعات حلّ غير أمثل، لأنه يعطّل خط الأنابيب. وبدلاً من ذلك، تستخدم المعالجات تقنية تسمى تمرير المعاملات (operand forwarding) يقرأ فيها خط الأنابيب النتيجة من العملية السابقة. وبالنظر إلى الشكل 2، بينما تنفّذ تعليمة MOV 4, Reg2، تمرّر نتائجها إلى تعليمة ADD Reg2, Reg2, Reg2. وبذلك، بينما تكتب تعليمة MOV في السجل Reg2، يمكن لتعليمة ADD استخدام القيمة المحدَّثة Reg2 التي تلقتها من تعليمة MOV.

5.8.2. مخاطر خطوط الأنابيب: مخاطر التحكم

خط الأنابيب مُحسَّن للتعليمات التي تحدث الواحدة تلو الأخرى. ويمكن للتغيرات في مسار التحكم في البرنامج الناشئة عن الشروط مثل عبارات if أو الحلقات أن تؤثر تأثيراً خطيراً في أداء خط الأنابيب. لنلقِ نظرة على مقتطف شيفرة مثال مختلف، أولاً بلغة C:

int result = *x; // x holds an int
int temp = *y;   // y holds another int

if (result <= temp) {
	result = result - temp;
}
else {
	result = result + temp;
}
return result;

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

  MOV M[0x84], Reg1     # move value at memory address 0x84 to register Reg1
  MOV M[0x88], Reg2     # move value at memory address 0x88 to register Reg2
  CMP Reg1, Reg2        # compare value in Reg1 to value in Reg2
  JLE L1<0x14>          # switch code execution to L1 if Reg1 less than Reg2
  ADD Reg1, Reg2, Reg1  # compute Reg1 + Reg2, store result in Reg1
  JMP L2<0x20>          # switch code execution to L2 (code address 0x20)
L1:
  SUB Reg1, Reg2, Reg1  # compute Reg1 - Reg2, store in Reg1
L2:
  RET                   # return from function

يحمّل هذا التسلسل من التعليمات بيانات من الذاكرة في سجلين منفصلين، ويقارن القيمتين، ثم يجري عمليات حسابية مختلفة بناءً على ما إذا كانت القيمة في السجل الأول أقل من القيمة في السجل الثاني. وتُمثَّل عبارة if في المثال أعلاه بتعليمتين: تعليمة المقارنة (CMP) وتعليمة القفز الشرطي «أقل من» (JLE). ونغطي التعليمات الشرطية بمزيد من التفصيل في فصول لغة التجميع القادمة؛ ويكفي الآن أن نفهم أن تعليمة CMP تقارن سجلين، بينما تعليمة JLE نوع خاص من التعليمات الفرعية تنقل تنفيذ الشيفرة إلى جزء آخر من البرنامج إذا وفقط إذا كان الشرط (أي أقل من أو يساوي في هذه الحالة) صحيحاً.

تحذير — لا تُثقل بالتفاصيل!

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

تحدث مخاطر التحكم (control hazard) عندما يواجه خط الأنابيب تعليمة تفرّع (أو شرطية). وعندما يحدث ذلك، يجب على خط الأنابيب أن «يخمّن» ما إذا كان التفرّع سيُسلك. وإذا لم يُسلك التفرّع، تستمر العملية في تنفيذ التعليمات التالية بالترتيب. تأمّل المثال في الشكل 3. فإذا سُلك التفرّع، ينبغي أن تكون التعليمة التالية التي تُنفَّذ هي SUB. غير أنه من المستحيل معرفة ما إذا كان التفرّع سيُسلك حتى تنتهي تعليمة JLE من التنفيذ. وعند تلك النقطة، تكون تعليمتا ADD وJMP قد حُمِّلتا بالفعل في خط الأنابيب. وإذا سُلك التفرّع، فيجب إزالة هذه التعليمات «غير المفيدة» من خط الأنابيب، أو تفريغها (flushed)، قبل إعادة تحميل خط الأنابيب بتعليمات جديدة. وتفريغ خط الأنابيب مكلف.

وهناك بضعة خيارات يمكن لمهندسي العتاد اختيار تنفيذها لمساعدة المعالج في التعامل مع مخاطر التحكم:

  • تعطيل خط الأنابيب: كحل بسيط، عند وجود تفرّع، أضف كثيراً من فقاعات NOP وعطّل خط الأنابيب حتى يتأكد المعالج من سلك التفرّع. ورغم أن تعطيل خط الأنابيب سيصلح المشكلة، فسيؤدي أيضاً إلى ضربة في الأداء (انظر الشكل 4).
  • تنبؤ التفرّع: الحل الأكثر شيوعاً استخدام متنبّئ التفرّع (branch predictor) الذي يتنبأ بالاتجاه الذي سيسلكه التفرّع بناءً على تنفيذات سابقة. ومتنبّئات التفرّع الحديثة جيدة ودقيقة جداً. غير أن هذا النهج تسبب مؤخراً في بعض الثغرات الأمنية (مثل Spectre1). ويصوّر الشكل 4 كيف قد يتعامل متنبّئ التفرّع مع خطر التحكم المذكور.
  • التنفيذ الراغب: في التنفيذ الراغب (eager execution)، ينفّذ المعالج جانبي التفرّع ويجري نقل بيانات شرطياً لا نقلاً للتحكم (ويُنفَّذ عبر تعليمتي cmov وcsel في x86 وARMv8-A على الترتيب). ويتيح النقل الشرطي للبيانات للمعالج مواصلة التنفيذ دون تعطيل خط الأنابيب. غير أن ليس كل الشيفرة قادرة على الاستفادة من التنفيذ الراغب، وقد يكون ذلك خطيراً في حالة إلغاء الإشارة إلى المؤشّرات والآثار الجانبية.

خطر تحكمي 2 الشكل 4. الحلول المحتملة للتعامل مع مخاطر التحكم.

المراجع

  1. بيتر برايت. Google: لن تستطيع البرمجيات أبداً إصلاح أخطاء من نوع Spectre Ars Technica 2019.

تخطيط خطوط الأنابيب في المعالج مثال واحد على التوازي على مستوى التعليمة (ILP)، حيث ينفّذ المعالج تعليمات متعددة بالتوازي في وقت واحد. وفي التنفيذ بتخطيط خطوط الأنابيب، ينفّذ المعالج تعليمات متعددة في وقت واحد بتداخل تنفيذها في خط الأنابيب. ويستطيع معالج بسيط بتخطيط خطوط الأنابيب تحقيق CPI مقداره 1، مكملاً تنفيذ تعليمة واحدة كل دورة ساعة. وعادةً ما تستخدم المعالجات الدقيقة الحديثة تخطيط خطوط الأنابيب مع تقنيات ILP أخرى، وتتضمن أنوية معالجة متعددة لتحقيق قيم CPI أقل من 1. ولهذه المعماريات الدقيقة، يُعدّ متوسط عدد التعليمات لكل دورة (IPC) المقياس الشائع لوصف أدائها. وتشير قيمة IPC الكبيرة إلى أن المعالج يحقق درجة عالية مستدامة من التنفيذ المتزامن للتعليمات.

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

عدد الترانزستورات التي يمكن أن تتسع في رقاقة مقياس تقريبي لأدائها. وقانون مور (Moore’s Law) ملاحظة قدّمها غوردون مور عام 1975 بأن عدد الترانزستورات لكل دائرة متكاملة يتضاعف كل سنتين تقريباً1,2. ويعني تضاعف عدد الترانزستورات لكل رقاقة كل سنتين أن معماريي الحواسيب يستطيعون تصميم رقاقة جديدة بمساحة تعادل ضعف مساحة دوائر التخزين والحساب، ما يضاعف قوتها تقريباً. وتاريخياً، استخدم معماريو الحواسيب الترانزستورات الإضافية لتصميم معالجات مفردة أكثر تعقيداً باستخدام تقنيات ILP لتحسين الأداء العام.

5.9.1. التوازي على مستوى التعليمة

التوازي على مستوى التعليمة (ILP) مصطلح لمجموعة من تقنيات التصميم المستخدمة لدعم التنفيذ المتوازي لتعليمات برنامج واحد على معالج واحد. وتقنيات ILP شفافة للمبرمج، أي أن المبرمج يكتب برنامج C تسلسلياً لكن المعالج ينفّذ عدة تعليمات منه في وقت واحد، بالتوازي، على وحدة تنفيذ واحدة أو أكثر. وتخطيط خطوط الأنابيب مثال على ILP، حيث يُنفَّذ تسلسل من تعليمات البرنامج في وقت واحد، كل منها في مرحلة مختلفة من خط الأنابيب. ويستطيع معالج بتخطيط خطوط الأنابيب تنفيذ تعليمة واحدة في كل دورة (وتحقيق IPC مقداره 1). ويمكن لأنواع أخرى من تصاميم ILP للمعالجات الدقيقة تنفيذ أكثر من تعليمة واحدة في دورة الساعة الواحدة وتحقيق قيم IPC أعلى من 1.

ومعالج المتجهات (vector processor) معمارية تنفّذ ILP عبر تعليمات متجهية خاصة تأخذ مصفوفات أحادية البعد (متجهات) من البيانات كمعاملات لها. وتُنفَّذ التعليمات المتجهية بالتوازي بمعالج المتجهات على وحدات تنفيذ متعددة، وكل وحدة تنفّذ عملية حسابية على عناصر فردية من معاملات متجهاتها. وفي الماضي، كثيراً ما استُخدمت معالجات المتجهات في الحواسيب المتوازية الكبيرة. وكان Cray-1 عام 1976 أول حاسوب فائق قائم على معالج متجهات، وواصلت Cray تصميم حواسيبها الفائقة بمعالجات متجهات طوال التسعينيات. غير أن هذا التصميم لم يستطع في النهاية منافسة تصاميم الحواسيب الفائقة المتوازية الأخرى، وتظهر معالجات المتجهات اليوم أساساً في أجهزة التسريع مثل وحدات معالجة الرسومات (GPU) المحسَّنة بوجه خاص لإجراء الحسابات على بيانات الصور المخزّنة في مصفوفات أحادية البعد.

والمعالج فائق التوسع (superscalar) مثال آخر على تصميم معالج بتقنية ILP. والمعالج فائق التوسع معالج واحد بوحدات تنفيذ متعددة وخطوط أنابيب تنفيذ متعددة. ويجلب المعالج فائق التوسع مجموعة تعليمات من تدفق تعليمات برنامج تسلسلي، ويقسّمها إلى تدفقات متعددة مستقلة من التعليمات تُنفَّذ بالتوازي بوحدات تنفيذه. والمعالج فائق التوسع معالج خارج الترتيب (out-of-order)، أي ينفّذ التعليمات خارج الترتيب الذي تظهر به في تدفق التعليمات التسلسلي. ويتطلب التنفيذ خارج الترتيب تحديد تسلسلات من التعليمات بلا تبعيات يمكن تنفيذها بأمان بالتوازي. ويحتوي المعالج فائق التوسع وظائف لإنشاء تدفقات متعددة من التعليمات المستقلة ديناميكياً لتغذية وحدات تنفيذه المتعددة. ويجب أن تنفّذ هذه الوظائف تحليل تبعيات لضمان الترتيب الصحيح لأي تعليمة يعتمد تنفيذها على نتيجة تعليمة سابقة في هذه التدفقات التسلسلية. وكمثال، يستطيع معالج فائق التوسع بخمس وحدات تنفيذ بتخطيط خطوط الأنابيب تنفيذ خمس تعليمات من برنامج تسلسلي في دورة واحدة (وتحقيق IPC مقداره 5). غير أنه بسبب تبعيات التعليمات، ليس صحيحاً دائماً أن يستطيع المعالج فائق التوسع إبقاء كل خطوط أنابيبه ممتلئة.

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

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

5.9.2. تعدد الأنوية وتعدد الخيوط في العتاد

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

وتعدد الخيوط في العتاد (hardware multithreading) تصميم معالج واحد يدعم تنفيذ خيوط عتادية متعددة. والخيط (thread) تدفق تنفيذ مستقل. فمثلاً، لبرنامجين قيد التشغيل لكل منهما خيطه المستقل من التنفيذ. ويمكن حينها لنظام التشغيل جدولة خيطَي تنفيذ هذين البرنامجين ليعملا «في الوقت نفسه» على معالج متعدد الخيوط. وقد يُنفَّذ تعدد الخيوط في العتاد بأن يتناوب المعالج بين تنفيذ تعليمات من تدفق تعليمات كل خيط من خيوطه في كل دورة. وفي هذه الحالة، لا تُنفَّذ تعليمات الخيوط العتادية المختلفة كلها تزامنياً في كل دورة. وبدلاً من ذلك، صُمّم المعالج ليبدّل بسرعة بين تنفيذ تعليمات من تدفقات تنفيذ خيوط مختلفة. وهذا يؤدي عادةً إلى تسريع تنفيذها ككل مقارنةً بتنفيذها على معالج أحادي الخيط.

ويمكن تنفيذ تعدد الخيوط في العتاد على معالجات دقيقة إما من نوع قياسي أو فائق التوسع. ويحتاج العتاد كحد أدنى إلى دعم جلب التعليمات من تدفقات تعليمات منفصلة متعددة (واحد لكل خيط تنفيذ)، وإلى مجموعات سجلات منفصلة لكل تدفق تنفيذ خيط. وهذه المعماريات متعددة الخيوط صراحةً4 لأنه، خلافاً للمعماريات فائقة التوسع، يُجدوَل كل تدفق من تدفقات التنفيذ مستقلاً بواسطة نظام التشغيل لتشغيل تسلسل منطقي منفصل من تعليمات البرنامج. وقد تأتي تدفقات التنفيذ المتعددة من برامج تسلسلية متعددة أو من خيوط برمجية متعددة من برنامج متوازٍ واحد متعدد الخيوط (نناقش البرمجة المتوازية متعددة الخيوط في الفصل 14).

المعماريات الدقيقة متعددة الخيوط في العتاد القائمة على معالجات فائقة التوسع لها خطوط أنابيب متعددة ووحدات تنفيذ متعددة، وبذلك تستطيع تنفيذ تعليمات من عدة خيوط عتادية في وقت واحد، بالتوازي، ما ينتج قيمة IPC أكبر من 1. أما المعماريات متعددة الخيوط القائمة على معالجات قياسية بسيطة فتنفّذ تعدد الخيوط المتشابك (interleaved multithreading). وتتشارك هذه المعماريات الدقيقة عادةً خط أنابيب وتتشارك دائماً وحدة الحساب والمنطق الوحيدة في المعالج (فيبدّل المعالج بين تنفيذ خيوط مختلفة على وحدة الحساب والمنطق). ولا يستطيع هذا النوع من تعدد الخيوط تحقيق قيم IPC أكبر من 1. وكثيراً ما يُسمى تعدد الخيوط العتادي الذي تدعمه المعماريات الدقيقة القائمة على فائق التوسع تعدد الخيوط المتزامن (SMT)4. ولسوء الحظ، كثيراً ما يُستخدم SMT للإشارة إلى نوعي تعدد الخيوط العتادي معاً، ولا يكفي المصطلح وحده دائماً لتحديد ما إذا كانت معمارية دقيقة متعددة الخيوط تنفّذ تعدد خيوط متزامناً حقيقياً أم متشابكاً.

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

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

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

5.9.3. بعض المعالجات المثالية

تُبنى المعالجات اليوم بمزيج من تقنيات ILP وتعدد الخيوط العتادي وتعدد الأنوية. بل يصعب إيجاد معالج غير متعدد الأنوية. ومعالجات فئة المكتب لها عادةً من نواتين إلى ثماني نوى، وكثير منها يدعم أيضاً مستوى منخفضاً من تعدد الخيوط لكل نواة. فمثلاً، تدعم معالجات AMD Zen متعددة الأنوية5 ومعالجات Intel Xeon وCore متعددة الأنوية بفرط الخيوط6 خيطين عتاديين لكل نواة. وتنفّذ أنوية Intel بفرط الخيوط تعدد الخيوط المتشابك. وبذلك لا تستطيع كل نواة من نوى Intel تحقيق IPC يتجاوز 1، لكن بعدة أنوية معالجة في الرقاقة، يستطيع المعالج تحقيق مستويات IPC أعلى.

أما المعالجات المصممة للأنظمة الراقية، كالمستخدمة في الخوادم والحواسيب الفائقة، فتحتوي أنوية كثيرة، لكل نواة درجة عالية من تعدد الخيوط. فمثلاً، معالج Oracle SPARC M7 7، المستخدم في الخوادم الراقية، له 32 نواة. ولكل من نوىه ثمانية خيوط عتادية، يمكن لخيطين منها التنفيذ تزامنياً، ما ينتج قيمة IPC قصوى قدرها 64 للمعالج. ويستخدم أسرع حاسوبين فائقين في العالم (حتى يونيو 2019)8 معالجات IBM Power 9.9 ولمعالجات Power 9 حتى 24 نواة لكل رقاقة، وتدعم كل نواة حتى ثمانية اتجاهات من تعدد الخيوط المتزامن. ويمكن لنسخة بـ24 نواة من معالج Power 9 تحقيق IPC مقداره 192.

الحواشي والمراجع

  1. لاحظ مور أول مرة تضاعفاً كل سنة في 1965، ثم حدّثه في 1975 ليكون كل أكثر من سنتين، وصار يُعرف بقانون مور.
  2. صمد قانون مور حتى نحو عام 2012 عندما بدأت التحسينات في كثافة الترانزستورات تتباطأ. وتوقع مور نهاية قانون مور في منتصف العشرينيات.
  3. «The End of Dennard scaling» لأدريان مكمنامين، 2013. https://cartesianproduct.wordpress.com/2013/04/15/the-end-of-dennard-scaling/
  4. «A Survey of Processors with Explicit Multithreading» لـ Ungerer وRobic وSilc. في ACM Computing Surveys، المجلد 35، العدد 1، مارس 2003، ص 29–63. http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.96.9105&rep=rep1&type=pdf
  5. معماريات AMD Zen: https://www.amd.com/en/technologies/zen-core
  6. معالجات Intel Xeon وCore بفرط الخيوط: https://www.intel.com/content/www/us/en/architecture-and-technology/hyper-threading/hyper-threading-technology.html
  7. معالج Oracle SPARC M7: http://www.oracle.com/us/products/servers-storage/sparc-m7-processor-ds-2687041.pdf
  8. قوائم Top 500: https://www.top500.org/lists/top500/
  9. معالج IBM Power 9: https://www.ibm.com/it-infrastructure/power/power9

قدّمنا في هذا الفصل معمارية الحاسوب، مركّزين على تصميم معالجه (CPU) وتنفيذه لفهم كيفية تشغيله برنامجاً. وتستند معالجات اليوم الحديثة إلى معمارية فون نيومان التي تعرّف حاسوباً عاماً ببرنامج مخزَّن. ويتيح التصميم عام الغرض لمعمارية فون نيومان تنفيذ أي نوع من البرامج.

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

تنفّذ جميع معماريات المعالجات معمارية مجموعة تعليمات (ISA) تحدد مجموعة تعليمات المعالج ومجموعة سجلاته وآثار تنفيذ التعليمات في حالة المعالج. وهناك معماريات ISA مختلفة كثيرة، وهناك غالباً تنفيذات معالجات دقيقة مختلفة لمعمارية ISA معينة. وتستخدم معالجات اليوم أيضاً مجموعة متنوعة من التقنيات لتحسين أداء المعالج، منها التنفيذ بتخطيط خطوط الأنابيب والتوازي على مستوى التعليمة والتصميم متعدد الأنوية.

لمزيد من الاتساع والعمق في تغطية معمارية الحاسوب، نوصي بقراءة كتاب عن معمارية الحاسوب1.

الحواشي

  1. من الاقتراحات «Computer Organization and Design: The Hardware and Software Interface» لديفيد أ. باترسون وجون ل. هينيسي.

تمارين إضافية

  1. أنشئ دائرة XOR من بتّة واحدة باستخدام بوابات AND وOR وNOT فقط. اعرض صراحةً جميع الخطوات بدءاً من جدول الحقيقة لـ XOR، ثم سرد التعبيرات المنطقية لوقت تكون فيه XOR هي 1، ثم ترجمة التعبيرات إلى دائرة.
  2. اسرد جدول الحقيقة لدائرة الجمع الكاملة من بتّة واحدة بثلاث قيم إدخال (A وB وCARRY IN) وقيمتَي خرج (SUM وCARRY OUT).
  3. أنشئ دائرة سلب من 4 بتّات باستخدام البوابات المنطقية الأساسية فقط (AND وOR وNOT)، ودائرة جمع من بتّة واحدة. افترض أن البتّة عالية الرتبة (البتّة 3) هي بتّة إشارة القيم الرباعية بالمتمّم الثنائي. راجع الفصل 4 لتفاصيل سلب أعداد المتمّم الثنائي.
  4. بالنسبة إلى دائرة المضمِّم رباعية الاتجاهات المعروضة في قسم دوائر التحكم، اشرح لماذا تؤدي قيمة إدخال S مقدارها 1 إلى إخراج المضمِّم لقيمة B.
  5. كم بتّة تحديد تلزم لمضمِّم بـ16 اتجاه؟ اشرح جوابك.
  6. ارسم دائرة مزلاج RS تخزّن 0. ثم تتبّع التحديثات في الدائرة لكتابة 1 فيها. استخدم شكل مزلاج RS في قسم دوائر التخزين كمثال.
  7. بالنسبة إلى شكل مزلاج D المسوَّر المعروض في قسم دوائر التخزين، ما قيم الإدخال التي تؤدي إلى كتابة 1 في المزلاج؟ وما المدخلات التي تؤدي إلى كتابة 0 في المزلاج؟
  8. اشرح لماذا لا أثر لمدخل D في مزلاج D المسوَّر على القيمة المخزّنة في المزلاج عندما يكون مدخل WE هو 0.