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

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

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

~4 min read · Updated Sep 6, 2026

خطر داده چیست

در یک پردازنده پایپ‌لاین‌شده، چند دستور به‌طور هم‌زمان در حال پیشرفت هستند. یک 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، که مستقیماً به درک علت دقیق این خطر متکی است.

Written & researched by Dr. Shahin Siami

Related Articles

تصورات غلط رایج درباره محاسبات موازی و درس‌های نهایی کتاب

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

Continue

واقعیت‌های عملی: بنچمارک CPU در مقابل GPU و ضرب ماتریس چندپردازنده‌ای

مقایسه منصفانه یک CPU و یک GPU نیازمند مدلی است که هم توان عملیاتی محاسباتی و هم محدودیت‌های پهنای باند حافظه را با هم در نظر بگیرد. این مقاله مدل roofline مورد استفاده برای مقایسه سخت‌افزار واقعی مانند Intel Core i7 و NVIDIA Tesla GPU را معرفی می‌کند، سپس نشان می‌دهد ضرب ماتریس چگونه در سراسر چند پردازنده تسریع می‌شود، به‌عنوان کاربرد عملی نهایی مفاهیم موازی این فصل.

Continue

بنچمارک کردن چندپردازنده‌ها و مدل‌سازی کارایی موازی

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

Continue

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

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

Continue

کلاسترها، کامپیوترهای در مقیاس انبار، و توپولوژی‌های شبکه

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

Continue

مقدمه‌ای بر GPU: موازی‌سازی عظیم برای بارهای کاری سنگین از نظر داده

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

Continue