خط لوله کلاسیک

در تاریخ سخت‌افزار رایانه، برخی از واحدهای پردازش مرکزی رایه (RISC CPU) مجموعه دستورالعمل‌های اولیه کاهش‌یافته از راه‌حل‌هایی با ساختاری مشابه استفاده می‌کردند که اکنون **خط لوله RISC کلاسیک** نامیده می‌شود. این CPUها عبارتند از: **[[معماری میپس]]**، **[[اسپارک]]**، **[[موتورولا ۸۸۰۰۰]]** و در national CPU DLX که برای آموزش اختراع شد.

هر یک از این طراحی‌های RISC اسکالر کلاسیک واکشی می‌کند و سعی می‌کند یک دستور را در هر چرخه انجام بدهد. مفهوم مشترک هر طراحی یک خط لوله دستورالعمل اجرایی پنج مرحله ای است. در طول عملیات، هر مرحله خط لوله بر اساس یک دستورالعمل در یک زمان مشخص کار می‌کند. هر یک از این مراحل شامل مجموعه ای از فلیپ فلاپ‌ها برای حفظ حالت و منطق ترکیبی است که بر روی خروجی‌های آن فلیپ فلاپ‌ها عمل می‌کند.

### واکشی دستورالعمل
عملیات‌ها در حافظه هستند که خودن آن‌ها یک چرخه طول می‌کشد. این حافظه را می تو به SRAM یا یک کش عملیات در نظر گرفت. اصطلاح «تاخیر» اغلب در علوم کامپیوتر استفاده می‌شود و به معنای زمانی است که یک عملیات شروع می‌شود تا زمانی که آن عملیات کامل شود؛ بنابراین، عملیات واکشی دارای تأخیر یک سیکل ساعت است (در صورت استفاده از SRAM تک چرخه یا اگر دستورالعمل در حافظهٔ کش بود). بنابراین، در مرحله واکشی دستورالعمل، یک دستورالعمل ۳۲ بیتی از حافظه دستورالعمل واکشی می‌شود.

شمارنده برنامه یا PC یک رجیستر است که آدرسی را که به حافظه دستورالعمل ارائه می‌شود نگه می‌دارد. آدرس در شروع یک چرخه به حافظه دستورالعمل ارائه می‌شود. سپس در طول چرخه، دستورالعمل از حافظه دستورالعمل خوده می‌شود و در هم زم، محاسبه ای برای تعیین شمارنده برنامه بعدی جام می‌شود. شمارنده برنامه با افزایش چهار شمارنده برنامه و با تخاب اینکه آیا آن را به عنو شمارنده برنامه در نظر بگیرید یا نتیجه محاسبه شاخه / پرش را به عنو شمارنده برنامه محاسبه کنید. توجه داشته باشید که در RISC کلاسیک، تمام دستورالعمل‌ها طول یکسی دارند. (این چیزی است که RISC را از CISC جدا می‌کند). در طرح‌های اصلی RISC، دازه یک دستورالعمل ۴ بایت است، بنابراین همیشه ۴ را به آدرس دستورالعمل اضافه کنید، اما از PC + 4 برای یک شاخه، پرش، یا استثنا استفاده نکنید (**به شاخه‌های تأخیری** در زیر مراجعه کنید). (توجه داشته باشید که برخی از ماشین‌های مدرن از الگوریتم‌های پیچیده‌تری (پیش‌بینی شاخه و پیش‌بینی هدف شاخه) برای حدس زدن آدرس دستورالعمل بعدی استفاده می‌کنند)

### رمزگشایی دستورالعمل
چیزی که اولین ماشین‌های RISC را از ماشین‌های قبلی CISC متفاوت می‌کند، این است که RISC میکروکد ندارد. در مورد دستورالعمل‌های میکروکدگذاری‌شده CISC، پس از واکشی از کش دستورالعمل، بیت‌های دستورالعمل به پایین خط لوله منتقل می‌شوند، جایی که منطق ترکیبی ساده در هر مرحله خط لوله سیگنال‌های کنترلی را برای مسیر داده مستقیماً از بیت‌های دستورالعمل تولید می‌کند. در آن طرح‌های CISC، رمزگشایی بسیار کمی در مرحلهٔ رمزگشایی جام می‌شود. پیامد این عدم رمزگشایی این است که باید از بیت‌های دستورالعمل بیشتری برای مشخص کردن آنچه دستور جام می‌دهد استفاده شود. که بیت‌های کمتری برای چیزهایی مند شاخص‌های ثبت نام باقی می‌گذارد.

تمام دستورالعمل‌های MIPS, SPARC و DLX حداکثر دارای دو ثبات ورودی هستند. در مرحله رمزگشایی، دیس‌های این دو رجیستر در داخل دستورالعمل مشخص می‌شوند و ایندکس‌ها به عنو آدرس به حافظه رجیستر ارائه می‌شوند؛ بنابراین دو ثبات نامگذاری شده از فایل ثبت خوده می‌شوند. در طرح MIPS، فایل رجیستر دارای ۳۲ ورودی بود.

همزمان با خودن فایل ثبات، منطق مسئله دستورالعمل در این مرحله تعیین می‌کند که آیا خط لوله آماده اجرای دستورالعمل در این مرحله است یا خیر. در غیر این صورت، منطق مسئله باعث می‌شود که هم مرحله Instruction Fetch و هم مرحله Decode متوقف شود. در یک چرخه استال، فلیپ فلاپ‌هایی که در ورودی قرار دارند. بیت‌های جدید را نمی‌پذیرند، بنابراین هیچ محاسبه‌ها جدیدی در طول آن چرخه جایگزین نمی‌شود.

اگر دستورالعمل رمزگشایی یک شاخه یا پرش باشد، آدرس هدف شاخه یا پرش به موازات خودن فایل ثبات محاسبه می‌شود. شرط شعاب در چرخه ایی که در ادامه آمده است محاسبه می‌شود (پس از خودن فایل رجیستر)، و اگر شعاب گرفته شود یا اگر دستور یک پرش باشد، به کامپیوتر در مرحله اول به جای PC افزایش یافته، هدف شاخه تعیین می‌شود. محاسبه شده است. برخی از معماری‌ها از واحد منطق حسابی (ALU) در مرحله اجرا استفاده می‌کنند، به قیمت کاهش دکی تو عملیاتی دستورالعمل.

مرحله رمزگشایی با فشار سخت‌افزاری بسیار زیادی به پای می‌رسد: MIPS امک شعاب در صورت مساوی بودن دو ثبات را دارد، بنابراین یک درخت AND با عرض ۳۲ بیت به صورت متوالی پس از خودن فایل ثبت اجرا می‌شود و یک مسیر حیاتی بسیار طولی را از طریق آن ایجاد می‌کند. مرحله (که به معنی چرخه کمتر در ثیه است). همچنین، محاسبه‌ها هدف شاخه به‌طور کلی به یک Add 16 بیتی و یک افزایش دهنده ۱۴ بیتی نیاز دارد. حل شعاب در مرحله رمزگشایی این امک را فراهم می‌کند که فقط خطای پیش‌بینی اشتباه شاخه تک چرخه داشته باشیم. از آنجایی که شاخه‌ها اغلب گرفته می‌شدند (و در نتیجه اشتباه پیش‌بینی می‌شدند)، پایین نگه داشتن این خطا بسیار مهم بود.

### اجرا کردن
مرحله اجرا جایی است که محاسبه‌ها واقعی رخ می‌دهد. به‌طور معمول این مرحله از یک ALU و همچنین یک جابه‌جا کنندهٔ بیت تشکیل شده است. همچنین ممکن است شامل یک ضرب‌کننده و تقسیم‌کننده چند چرخه ایی باشد.

ALU مسئول جام عملیات بولی (و، یا، نه، nand، نه، xor, xnor) و همچنین برای جام جمع و تفریق اعداد صحیح است. علاوه بر آن، ALU معمولاً بیت‌های وضعیتی را ارائه می‌کند، مند اینکه آیا نتیجه ۰ بوده یا نه، یا سرریزی رخ داده است.

Bit Shifter وظیفه تقال و چرخش را بر عهده دارد.

دستورالعمل‌های مربوط به این ماشین‌های ساده RISC را می تو با توجه به عملکرد عملیات به سه کلاس تأخیر تقسیم کرد:
* عملیات ثبت-ثبت (تأخیر یک چرخه): عملیات اضافه، تفریق، مقایسه و اعمال منطقی. در طول مرحله اجرا، دو آرگوم به یک ALU ساده وارد شدند که نتیجه را در پای مرحله اجرا ایجاد کرد.
* مرجع حافظه (تأخیر دو چرخه). همه بارها از حافظه در طول مرحله اجرا، ALU دو آرگوم (یک ثبات و یک آفست ثابت) را برای تولید یک آدرس مجازی در پای چرخه اضافه کرد.
* دستورالعمل‌های چند چرخه (تأخیر چرخه بسیاری). ضرب و تقسیم عدد صحیح و تمام عملیات ممیز شناور. در طول مرحله اجرا، عملوندهای این عملیات به واحد ضرب/تقسیم چند چرخه تغذیه شدند. بقیه خط لوله آزاد بود تا اجرا را ادامه دهد در حالی که واحد ضرب/تقسیم کار خود را جام می‌داد. برای جلوگیری از پیچیده شدن مرحله نوشتن و منطق مسئله، دستورالعمل‌های چند چرخه نتایج خود را در مجموعه ای جداگه از ثبات‌ها می‌نویسند.

### دسترسی به حافظه
اگر نیاز به دسترسی به حافظه داده باشد، در این مرحله جام می‌شود.

در طول این مرحله، دستورالعمل‌های تأخیر تک چرخه به سادگی نتایج خود را به مرحله بعدی ارسال می‌کنند. این ارسال تضمین می‌کند که دستورالعمل‌های یک و دو چرخه همیشه نتایج خود را در هم مرحله از خط لوله می‌نویسند تا فقط یک پورت نوشتن در فایل ثبت استفاده شود و همیشه در دسترس باشد.

برای ذخیره‌سازی مستقیم داده‌های نگاشت شده و برچسب‌گذاری شده مجازی، ساده‌ترین سازم‌های ذخیره‌سازی اطلاعات متعدد، از دو SRAM استفاده می‌شود که یکی داده‌ها را ذخیره می‌کند و دیگری برچسب‌ها را ذخیره می‌کند.

### جواب دادن
در این مرحله، هر دو دستورالعمل تک چرخه و دو چرخه، نتایج خود را در فایل ثبت می‌نویسند. توجه داشته باشید که دو مرحله مختلف به‌طور همزمان به فایل ثبات دسترسی دارند -- مرحله رمزگشایی خواندن دو رجیستر منبع است، در هم زم که مرحله نوشتن بازگشت در حال نوشتن یک ثبات مقصد دستورالعمل قبلی است. در سیلیکون واقعی، این می تود یک خطر باشد (برای اطلاعات بیشتر در مورد خطرها به زیر مراجعه کنید). این به این دلیل است که یکی از رجیسترهای مبدأ که در رمزگشایی خوده می‌شود، ممکن است با رجیستر مقصد که در نوشتن بازگشت نوشته می‌شود، یکی باشد. وقتی این اتفاق می‌افتد، سلول‌های حافظه یکس در فایل ثبات هم زم خوده و نوشته می‌شوند. در سیلیکون، بسیاری از پیاده‌سازی‌های سلول‌های حافظه هنگام خودن و نوشتن به‌طور همزم به درستی کار نمی‌کنند.

### خطرها
هنسی و پترسون اصطلاح ''خطر'' را برای موقعیت‌هایی ابداع کردند که در آن دستورالعمل‌ها در خط لوله پاسخ‌های اشتباهی را ایجاد می‌کنند.

### خطرهای دستورالعمل
**خطرهای ساختاری زمی رخ می‌دهد که دو دستورالعمل ممکن است سعی کنند از منابع یکسی در یک زم استفاده کنند.** خطوط لوله RISC کلاسیک با تکرار سخت‌افزار از این خطرها جلوگیری کردند. به‌طور خاص، دستورالعمل‌های شاخه ایی می توستند از ALU برای محاسبه آدرس هدف شعبه استفاده کنند. اگر از ALU در مرحله رمزگشایی برای این منظور استفاده می‌شد، یک دستورالعمل ALU به دنبال یک شعبه می توست شاهد تلاش هر دو دستورالعمل برای استفاده همزم از ALU باشد. حل این تضاد با طراحی یک جمع‌کننده هدف شاخه تخصصی در مرحله رمزگشایی ساده است.

### خطرهای داده
**خطرهای داده زمی رخ می‌دهد که یک دستورالعمل، برنامه‌ریزی شده کورکوره، سعی می‌کند از داده‌ها قبل از در دسترس بودن داده‌ها در فایل ثبات استفاده کند.**

در خط لوله کلاسیک RISC، خطرهای داده به یکی از دو روش اجتناب می‌شود:

راه حل A. دور زدن

دور زدن نیز به عنو حمل و نقل عملوند شناخته می‌شود.

فرض کنید CPU در حال اجرای قطعه کد زیر است:
```nasm
SUB r3,r4 -> r10     ; Writes r3 - r4 to r10
AND r10,r3 -> r11    ; Writes r10 & r3 to r11
```
مراحل واکشی دستورالعمل و رمزگشایی دستور دوم را یک چرخه پس از اول ارسال می‌کند. همطور که در این نمودار نش داده شده است، آنها از خط لوله عبور می‌کنند:
وسط
در یک *خط لوله ساده*، بدون در نظر گرفتن خطر، خطر داده به صورت زیر پیشرفت می‌کند:

در چرخه ۳، دستورالعمل `SUB` مقدار جدید را برای `r10` محاسبه می‌کند. در هم چرخه، عملیات `AND` رمزگشایی می‌شود و مقدار `r10` از فایل رجیستر واکشی می‌شود. با این حال، دستورالعمل `SUB` هنوز نتیجه خود را روی `r10` است. بازنویسی این مورد معمولاً در چرخه ۵ (جعبه سبز) رخ می‌دهد؛ بنابراین، مقداری که از فایل رجیستر خوده شده و به ALU (در مرحله اجرای عملیات `AND` ، کادر قرمز رنگ) ارسال شده است، نادرست است.

درعوض، باید داده‌هایی را که توسط `SUB` محاسبه شده‌د، *قبل از* اینکه به‌طور معمول بازنویسی شوند، به مرحله Execute (یعنی به دایره قرمز در نمودار) عملیات `AND` برگردیم. راه حل این مشکل یک جفت مالتی پلکسر بای پس است. این مالتی پلکسرها در تهای مرحله رمزگشایی قرار دارند و خروجی‌های فلاپ شده آنها ورودی‌های ALU هستند. هر مالتی پلکسر بین:
# یک پورت خودن فایل ثبات (یعنی خروجی مرحله رمزگشایی، مند خط لوله ساده): فلش 
# خط لوله ثبت فعلی ALU (برای دور زدن یک مرحله): فلش 
# خط لوله ثبت فعلی مرحله دسترسی (که یا یک مقدار بارگذاری شده یا یک نتیجه ALU ارسال شده است، این امر دور زدن دو مرحله را فراهم می‌کند): فلش . توجه داشته باشید که این امر مستلزم آن است که داده‌ها در یک چرخه در زم به *عقب* منتقل شوند. اگر این اتفاق بیفتد، یک حباب باید وارد شود تا عملیات `AND` تا زمی که داده آماده شود متوقف شود.

منطق مرحله رمزگشایی رجیسترهای نوشته شده توسط دستورالعمل‌ها در مراحل اجرا و دسترسی خط لوله را با ثبات‌های خوده شده توسط دستورالعمل در مرحله رمزگشایی مقایسه می‌کند و باعث می‌شود مالتی پلکسرها جدیدترین داده‌ها را تخاب کنند. این مالتی پلکسرهای بای پس این امک را برای خط لوله فراهم می‌کند تا دستورهای ساده را فقط با تأخیر ALU، مالتی پلکسر و یک فلیپ فلاپ اجرا کند. بدون مالتی پلکسرها، تأخیر نوشتن و سپس خودن فایل ثبت نام باید در تأخیر این دستورالعمل‌ها لحاظ شود.

توجه داشته باشید که داده‌ها فقط می توند در زم *به جلو* منتقل شوند - اگر هنوز پردازش نشده باشد، نمی تو داده‌ها را به مرحله قبلی دور زد. در مورد بالا، داده‌ها به جلو منتقل می‌شوند (تا زمی که `AND` برای ثبت در ALU آماده شود، `SUB` قبلاً آن را محاسبه کرده است).
وسط
**راه حل B. قفل کردن خط لوله**

با این حال، دستورالعمل‌های زیر را در نظر بگیرید:
```nasm
LD  adr    -> r10
AND r10,r3 -> r11
```
داده‌های خوده شده از آدرس `adr` تا زمی که مرحله دسترسی به حافظه دستور `LD` جام نشود، در حافظه پنه داده وجود ندارد. در این زم، دستورالعمل `AND` در حال حاضر از طریق ALU است. برای حل این مشکل نیاز است که داده‌ها از حافظه در زم به عقب به ورودی ALU ارسال شوند. ممکن نیست. راه حل این است که دستور `AND` را یک چرخه به تأخیر بیندازید. خطر داده در مرحله رمزگشایی شناسایی می‌شود و مراحل واکشی و رمزگشایی **متوقف** می‌شوند - از فلاپ کردن ورودی‌هایش جلوگیری می‌شود و بنابراین برای یک چرخه در هم حالت باقی می‌مند. مراحل اجرا، دسترسی و بازنویسی در پایین‌دست، یک دستورالعمل بدون عملیات اضافی (NOP) را مشاهده می‌کند که بین دستورالعمل‌های `LD` و `AND` درج شده است.

این NOP یک *[[حباب (رایانه)|حباب]]* خط لوله نامیده می‌شود زیرا در خط لوله شناور است، مند حباب هوا در لوله آب، منابع را اشغال می‌کند اما نتایج مفیدی ایجاد نمی‌کند. سخت‌افزاری که برای تشخیص خطر داده و متوقف کردن خط لوله تا زمی که خطر پاک شود، **اینترلاک خط لوله** نامیده می‌شود.

با این حال، نیازی به استفاده از خط لوله برای ارسال اطلاعات نیست. مثال اول `SUB` به دنبال `AND` و مثال دوم `LD` و به دنبال آن `AND` را می‌توان با متوقف کردن مرحله اول به مدت سه چرخه تا زمانی که بازگشت به نوشتن حاصل شود و داده‌های موجود در فایل ثبات صحیح باشد حل شود و باعث ثبت صحیح می‌شود. مقداری که باید توسط مرحله رمزگشایی `AND` دریافت شود. این باعث می‌شود عملکرد بسیار خوبی ایجاد شود، زیرا پردازنده رم زیادی را صرف پردازش چیزی می‌کند، اما سرعت کلاک را می‌توان افزایش داد زیرا منطق ارسال کمتری برای انتظار وجود دارد.

هنگامی که کد ماشین برنامه توسط کامپایلر نوشته می‌شود، می تو این خطر داده را به راحتی تشخیص داد. ماشین MIPS استنفورد به جای داشتن مداری برای شناسایی و (به‌طور شدیدتر) توقف دو مرحله اول خط لوله، به کامپایلر برای اضافه کردن دستورالعمل‌های NOP در این مورد متکی بود. از این رو نام MIPS: ریزپردازنده بدون مراحل خط لوله در هم قفل شده است. معلوم شد که دستورالعمل‌های NOP اضافی اضافه شده توسط کامپایلر، باینری‌های برنامه را به دازه‌ای گسترش می‌دهد که نرخ ضربه کش دستورالعمل کاهش می‌یابد. سخت‌افزار Stall، اگرچه گرقیمت بود، اما برای بهبود نرخ ضربه کش دستورالعمل‌ها، در طرح‌های بعدی قرار گرفت، که در آن زم این مخفف دیگر معنی نداشت.

### خطرها را کنترل کنید
**خطرهای کنترلی ناشی از شعاب مشروط و بدون قید و شرط است.** خط لوله کلاسیک RISC شاخه‌ها را در مرحله رمزگشایی حل می‌کند، که به این معنی است که تکرار تفکیک شاخه دو چرخه طول می‌کشد. سه مفهوم وجود دارد:
* تکرار تفکیک شعاب از مدارهای کمی عبور می‌کند: خودن کش دستورالعمل، خودن فایل ثبت، محاسبه شرایط شعاب (که شامل یک مقایسه ۳۲ بیتی در CPUهای MIPS است)، و مالتی پلکسر آدرس دستورالعمل بعدی.
* از آنجایی که اهداف شاخه و پرش به موازات رجیستر خوده شده محاسبه می‌شوند، ISAهای RISC معمولاً دستورالعمل‌هایی ندارند که به آدرس register+offset منشعب می‌شوند. پرش به ثبت نام پشتیبی می‌شود.
* در هر شاخه ای که گرفته می‌شود، دستورالعمل بلافاصله پس از شاخه همیشه از کش دستورالعمل واکشی می‌شود. اگر این دستورالعمل نادیده گرفته شود، یک جریمه IPC برای هر شاخه گرفته شده یک چرخه وجود دارد که به دازه کافی بزرگ است.

چهار طرح برای حل این مشکل کارایی با شاخه‌ها وجود دارد:
* Predict Not Taken: همیشه دستور بعد از شاخه را از کش دستورالعمل واکشی کنید، اما فقط در صورتی آن را اجرا کنید که شاخه گرفته نشده باشد. اگر شعاب گرفته نشود، خط لوله پر می مد. اگر شعاب گرفته شود، دستورالعمل فلاش می‌شود (به گونه ای علامت گذاری می‌شود که گویی یک NOP است)، و فرصت یک چرخه برای اتمام یک دستورالعمل از بین می‌رود.
* Branch Likely: همیشه دستورالعمل را بعد از شاخه از کش دستورالعمل واکشی کنید، اما فقط در صورتی آن را اجرا کنید که شاخه گرفته شده باشد. کامپایلر همیشه می‌تود شکاف تأخیر شاخه‌ای را در چنین شاخه‌ای پر کند، و از آنجایی که شعبه‌ها اغلب گرفته می‌شوند، چنین شاخه‌هایی جریمه IPC کمتری نسبت به نوع قبلی دارند.
* شکاف تأخیر شعبه: همیشه دستورالعمل را بعد از شاخه از کش دستورالعمل واکشی کنید و همیشه آن را اجرا کنید، حتی اگر شاخه گرفته شده باشد. به جای دریافت جریمه IPC برای بخشی از شاخه‌هایی که گرفته شده (شاید ۶۰٪) یا گرفته نشده است (شاید ۴۰٪)، شکاف‌های تأخیر شعبه برای شاخه‌هایی که کامپایلر نمی تود شکاف تأخیر شعاب را برنامه‌ریزی کند، جریمه IPC می‌گیرد. طراح SPARC, MIPS و MC88K یک شکاف تأخیر شعاب را در ISA خود طراحی کردند.
* پیش‌بینی شاخه: به موازات واکشی هر دستورالعمل، حدس بزنید که آیا دستورالعمل یک شاخه است یا پرش، و اگر چنین است، هدف را حدس بزنید. در چرخه پس از شاخه یا پرش، دستورالعمل را در هدف حدس زده شده بیاورید. هنگامی که حدس اشتباه است، هدف نادرست واکشی شده را شستشو دهید.

اولاً، شاخه‌های تأخیری بحث برگیز بودند، زیرا معنای آنها پیچیده است. یک شاخه تأخیری مشخص می‌کند که پرش به مک جدید *پس* از دستور بعدی اتفاق می‌افتد. دستور بعدی دستوری است که به‌طور اجتناب ناپذیری توسط کش دستورالعمل پس از شاخه بارگیری می‌شود.

شاخه‌های تأخیری مورد تقاد قرار گرفته است به عنو یک تخاب کوتاه مدت ضعیف در طراحی ISA:
* کامپایلرها معمولاً در یافتن دستورالعمل‌های مستقل منطقی برای قرار دادن بعد از شاخه مشکل دارند (دستورالعمل بعد از شاخه، شکاف تأخیر نامیده می‌شود)، بنابراین باید NOPها را در شکاف‌های تأخیر وارد کنند.
* پردازنده‌های Superscalar که چندین دستورالعمل را در هر چرخه دریافت می‌کنند و باید نوعی پیش‌بینی شاخه داشته باشند، از شاخه‌های تأخیری بهره نمی‌برند. Alpha ISA شاخه‌های تأخیری را کنار گذاشت، زیرا برای پردازنده‌های فوق اسکالر در نظر گرفته شده بود.
* جدی‌ترین اشکال برای شاخه‌های تأخیری پیچیدگی کنترل اضافی آنهاست. اگر دستور شکاف تأخیر استثنا داشته باشد، پردازنده باید به جای دستورالعمل بعدی، در شاخه راه دازی مجدد شود. پس استثناها اساساً دارای دو آدرس هستند، آدرس استثنا و آدرس راه‌دازی مجدد، و ایجاد و تمایز صحیح بین این دو در همه موارد منبع اشکال برای طراحی‌های بعدی بوده است.

### استثناها
فرض کنید یک RISC 32 بیتی یک دستورالعمل ADD را پردازش می‌کند که دو عدد بزرگ را اضافه می‌کند و نتیجه در ۳۲ بیت قرار نمی‌گیرد.

ساده‌ترین راه حل، که توسط اکثر معماری‌ها ارائه شده است، حسابی بسته‌بندی است. اعداد بزرگتر از حداکثر مقدار ممکن رمزگذاری شده، مهم‌ترین بیت‌های آن‌ها را تا زمی که جا بیفتند، بریده می‌شوند. در سیستم اعداد صحیح معمولی ۳۰۰۰۰۰۰۰۰۰+۳۰۰۰۰۰۰۰۰۰=۶۰۰۰۰۰۰۰۰۰. با حساب ۳۲ بیتی بدون علامت، ۳۰۰۰۰۰۰۰۰۰+۳۰۰۰۰۰۰۰۰۰=1705032704 (6000000000 mod ۲^۳۲). این ممکن است خیلی مفید به نظر نرسد. بزرگ‌ترین مزیت محاسبه حسابی این است که هر عملیات یک نتیجه کاملاً مشخص دارد.

اما برنامه‌نویس، به خصوص اگر به زبی برنامه‌نویسی کند که از اعداد صحیح بزرگ پشتیبی می‌کند (مثلاً Lisp یا Scheme)، ممکن است نیازی به پیچیدن محاسبات نداشته باشد. برخی از معماری‌ها (مثلا MIPS)، عملیات افزودن ویژه ای را تعریف می‌کند که به جای بسته‌بندی نتیجه، به مک‌های ویژه در سرریز منشعب می‌شود. نرم‌افزار در محل مورد نظر مسئول رفع مشکل است. این شاخه خاص استثنا نامیده می‌شود. استثناها با شاخه‌های معمولی تفاوت دارند زیرا آدرس هدف توسط خود دستورالعمل مشخص نشده است و تصمیم شعبه به نتیجه دستورالعمل بستگی دارد.

رایج‌ترین نوع استثنای قابل مشاهده نرم‌افزار در یکی از ماشین‌های کلاسیک RISC، *[[تی‌ال‌بی|خطای TLB]]* است.

استثناها با شاخه‌ها و پرش‌ها متفاوت هستند، زیرا سایر تغییرها جری کنترلی در مرحله رمزگشایی حل می‌شوند. استثناها در مرحله بازنویسی حل می‌شوند. هنگامی که یک استثنا تشخیص داده می‌شود، دستورالعمل‌های زیر (قبل از این در خط لوله) به عنو نامعتبر علامت گذاری می‌شوند و همطور که به تهای لوله می‌رسند، نتایج آنها دور ریخته می‌شود. شمارنده برنامه به آدرس یک کنترل‌کننده استثنای خاص تنظیم می‌شود و ثبات‌های ویژه با مک استثنا و علت نوشته می‌شوند.

برای آس کردن (و سریع) نرم‌افزار برای رفع مشکل و راه دازی مجدد برنامه، CPU باید یک استثنای دقیق داشته باشد. استثنای دقیق به این معنی است که تمام دستورها تا دستور استثنا اجرا شده د و دستورالعمل استثنا و همه چیزهای بعد از آن اجرا نشده باشد.

برای گرفتن استثنائات دقیق، CPU باید تغییرها را در حالت قابل مشاهده نرم‌افزار در ترتیب برنامه *جام* دهد. این commit منظم به‌طور طبیعی در خط لوله کلاسیک RISC اتفاق می‌افتد. اکثر دستورالعمل‌ها نتایج خود را در فایل ثبت در مرحله نوشتن باز می‌نویسند و بنابراین این نوشتن‌ها به‌طور خودکار به ترتیب برنامه اتفاق می‌افتد. دستورالعمل‌های ذخیره شده، اما نتایج خود را در مرحله دسترسی در صف داده‌های ذخیره شده می‌نویسند. اگر دستور ذخیره یک استثنا داشته باشد، ورودی Store Data Queue باطل می‌شود تا بعداً در حافظه کش داده SRAM نوشته نشود.

### مدیریت از دست دادن حافظه پنه
گاهی، کش داده یا دستورالعمل حاوی داده یا دستورالعمل لازم نیست. در این موارد، CPU باید تا زمی که حافظه پنه با داده‌های لازم پر شود، کار را به حالت تعلیق درآورد و سپس باید اجرا را از سر بگیرد. مشکل پر کردن حافظه پنه با داده‌های مورد نیاز (و به‌طور بالقوه بازنویسی خط کش تخلیه شده به حافظه) مختص سازم خط لوله نیست و در اینجا مورد صحبت قرار نمی‌گیرد.

دو استراتژی برای رسیدگی به مشکل تعلیق/رزومه وجود دارد. اولی یک سیگنال استال عمومی است. این سیگنال، زمی که فعال می‌شود، از پیشروی دستورالعمل‌ها در خط لوله، به‌طور کلی با خارج کردن ساعت به فلیپ فلاپ‌ها در شروع هر مرحله، جلوگیری می‌کند. نقطه ضعف این استراتژی این است که تعداد زیادی فلیپ فلاپ وجود دارد، بنابراین سیگنال عمومی استال زم زیادی برای تشار نیاز دارد. از آنجایی که ماشین به‌طور کلی باید در هم چرخه ای که شرایطی را که نیاز به استال را شناسایی می‌کند، متوقف شود، سیگنال استال به یک مسیر بحری محدود کننده سرعت تبدیل می‌شود.

روش دیگر برای مدیریت تعلیق/ادامه، استفاده مجدد از منطق استثنا است. دستگاه در دستورالعمل متخلف استثنا قائل می‌شود و تمام دستورالعمل‌های بعدی باطل می‌شوند. هنگامی که حافظه پنه با داده‌های لازم پر شد، دستورالعملی که باعث از دست رفتن حافظه پنه شده است مجدداً راه دازی می‌شود. برای تسریع رسیدگی به خطاهای حافظه نه داده، دستورالعمل را می تو مجدداً راه دازی کرد تا چرخه دسترسی آن یک چرخه پس از پر شدن حافظه پنه داده اتفاق بیفتد.

## جستارهای وابسته
قون آهن عملکرد پردازنده

## منابع

*