خطرهای داده در پایپ‌لاین: Forwarding در مقابل Stalling

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

خطرهای دادهForwardingتوقف پایپ‌لاین

~4 دقیقه مطالعه · آخرین به‌روزرسانی ۱۵ شهریور ۱۴۰۵

خطر داده چیست

در یک پردازنده پایپ‌لاین‌شده، چند دستور به‌طور هم‌زمان در حال پیشرفت هستند. یک Data Hazard زمانی رخ می‌دهد که یک دستور نیاز دارد از مقداری استفاده کند که یک دستور قبلی، که هنوز در حال حرکت در پایپ‌لاین است، هنوز محاسبه‌اش را تمام نکرده و آن را به فایل رجیستر write back نکرده است.

این توالی از دستورات را در نظر بگیرید:

add a, b, c
sub d, a, e

دستور دوم به مقدار a نیاز دارد، اما دستور اول تا زمانی که دستور دوم به decode می‌رسد هنوز به مرحله write-back خودش نرسیده است. بدون هیچ تصحیحی، دستور دوم یک مقدار قدیمی و بی‌اعتبار از a را از فایل رجیستر می‌خواند.

راه‌حل اول: Forwarding

Forwarding (که Bypassing نیز نامیده می‌شود) این مسئله را بدون از دست دادن هیچ سیکل ساعتی حل می‌کند، با افزودن سیم‌کشی اضافه که یک نتیجه را مستقیماً از جایی که محاسبه می‌شود به جایی که نیاز است مسیریابی می‌کند، و کاملاً از مسیر معمول از طریق فایل رجیستر عبور می‌کند.

بدون forwarding:
add نتیجه را محاسبه می‌کند → در فایل رجیستر نوشته می‌شود (سیکل ۵)
sub به نتیجه نیاز دارد → از فایل رجیستر خوانده می‌شود (سیکل ۳) — خیلی زود، مقدار نادرست

با forwarding:
add نتیجه را در مرحله EX محاسبه می‌کند (سیکل ۳)
نتیجه مستقیماً به مرحله EX دستور sub فوروارد می‌شود (سیکل ۴)

از آنجا که نتیجه‌ای که دستور دوم نیاز دارد درست پس از مرحله execute دستور اول در دسترس است، مسیرهای سخت‌افزاری اضافی می‌توانند آن مقدار را به‌موقع به جلو تغذیه کنند تا دقیقاً وقتی دستور دوم نیاز دارد به آن برسد، و از هر سیکل هدررفته جلوگیری می‌کنند.

وقتی Forwarding به‌تنهایی کافی نیست

Forwarding بیشتر خطرهای داده را حل می‌کند، اما نه همه آن‌ها را. یک Load-Use Hazard به‌طور خاص زمانی رخ می‌دهد که دستوری بلافاصله پس از یک load به مقداری نیاز دارد که آن load در حال بازیابی آن است:

ld a, 0(b)
add d, a, e

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

راه‌حل دوم: Stalling

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

ld a, 0(b)      : IF ID EX MEM WB
[حباب وارد شده]
add d, a, e     : IF ID  --  EX MEM WB

این کار عمداً یک سیکل را هدر می‌دهد به‌جای تولید یک نتیجه نادرست، که همیشه مبادله درست است، چون دقت نمی‌تواند به قیمت سرعت فدا شود.

چرا این تمایز برای طراحی کامپایلر اهمیت دارد

از آنجا که توقف‌های load-use به‌طور خاص یک سیکل هزینه دارند، کامپایلرهایی که این خطر را می‌فهمند گاهی می‌توانند دستورات مستقل را طوری بازچینی کنند که بلافاصله پس از یک load قرار گیرند، و آنچه در غیر این صورت یک سیکل توقف هدررفته بود را با کار مفید پر کنند — تکنیکی به نام Instruction Scheduling، که مستقیماً به درک علت دقیق این خطر متکی است.

نوشته و پژوهش‌شده توسط دکتر شاهین صیامی

مقالات مرتبط

اصول کش: حافظه کوچک و سریع چگونه پیش‌بینی می‌کند بعداً چه چیزی نیاز است

یک کش فقط به این دلیل کار می‌کند که برنامه‌ها تمایل دارند داده یکسان یا نزدیک به هم را به‌طور تکراری دسترسی کنند نه به‌صورت تصادفی. این مقاله اصل محلیت که کش را مؤثر می‌کند را توضیح می‌دهد، یک کش مستقیم‌نگاشت‌شده چگونه داده را با استفاده از یک آدرس مکان‌یابی می‌کند، و در یک hit کش در مقابل یک miss کش چه اتفاقی می‌افتد.

ادامه

سلسله‌مراتب حافظه: چرا کامپیوترها از چند نوع حافظه استفاده می‌کنند

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

ادامه

تصورات غلط رایج درباره طراحی پردازنده و تصویر کلی فصل چهارم

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

ادامه

پایپ‌لاین‌های دنیای واقعی: مقایسه ARM و Intel، و تسریع ضرب ماتریس

مفاهیم نظری پایپ‌لاین در پردازنده‌های تجاری واقعی شکل مشخصی به خود می‌گیرند، که بسته به اهداف طراحی‌شان از نظر عمق پایپ‌لاین و عرض صدور به‌طور گسترده متفاوت‌اند. این مقاله مقایسه می‌کند ARM Cortex-A53 و Intel Core i7 چگونه پایپ‌لاینینگ را متفاوت برای کارایی توان در مقابل کارایی خام پیاده‌سازی می‌کنند، سپس نشان می‌دهد موازی‌سازی سطح دستور چگونه ضرب ماتریس را در عمل تسریع می‌کند.

ادامه

موازی‌سموازی‌سازی سطح دستور: اجرای بیش از یک دستور به‌طور هم‌زمانازی سطح دستور: اجرای بیش از یک دستور به‌طور هم‌زمان

موازی‌سازی سطح دستور: اجرای بیش از یک دستور به‌طور هم‌زمان

ادامه

یک پردازنده پایپ‌لاین‌شده چگونه استثناها را مدیریت می‌کند

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

ادامه