עד כה יכולנו להריץ פקודה אחת בכל פעם במעבד, אך גם ב- יש מקום לשיפור שכן עדיין יש רכיבים שעומדים ולא עושים כלום למשך זמן מה.
כעת אנו עומדים לצנרר את המעבד, זה ייתן לנו שיפור ב- אך לאור העובדה שכל פקודה כעת צריכה לעבור את כל השלבים, זאת בניגוד ל-, וגם לאור העובדה שאין פלופים אידיאליים - ה- יהיה גבוהה יותר - שזה רע.
כך נראה מעבד מצונרר:

נוכל לבצע אבסטרקציה ולקבל:

לכאורה נראה שרימינו פה - אנו משתמשים ב- פעמיים - איך זה יכול להיות?
- קריאה מהרגיסטר, שזה הדבר היחיד שמתבצע בשלב ה-, היא אסינכרונית ולכן יכולה להתבצע בכל זמן.
- כתיבה לרגיסטר, שזה הדבר היחיד שמתבצע בשלב ה-, היא סינכרונית ולכן נוכל לבצע אותה שכן אנו לא מבצעים עוד פניות סינכרוניות לרגיסטר.
בשונה מ- אנו לא צריכים את ה- ואנו יכולים להשתמש ב- רגיל.
אך יש לנו בעיה - אנו צריכים סיגנלי בקרה מסויימים עבור כל שלב בצינור - איך נפתור זאת? נשרשר את סיגנלי הבקרה באמצעות רגיסטרים גם כן.
כדי שזה יהיה יעיל, אנו נעביר רק את הסיגנלים שאנחנו צריכים:

יש לנו שלושה סוגי האזארדים:
- מבני -
- נתונים -
- בקרה -
מבני
הבעיה: שתי פקודות או יותר מתחרות על גישה לאותו משאב פיזי.
פתרון 1: גישה סדרתית, לפי תור, למשאב. חלק מהפקודות נאלצות להמתין.
פתרון 2: הוספת חומרה למכונה.
אם בניתם את המעבד נכון כמו שראינו בקורס, אין סכנה ל- מבני.
נתונים
אם נניח יש לנו שתי פקודות שמשתמשות ברגיסטר כאשר הראשונה משנה אותו והשניה משתמשת בו והן בהפרש הקטן מ- פקודות, הערך החדש של הרגיסטר לא ישמר.

איך נוכל לדאוג שזה לא יקרה?
- נוכל לפתור זאת באמצעות השהייה אבל, אנו נקבל בועה. כלומר, לא תתבצע שום פקודה עד שהפקודה תשמר.
- נוכל לפתור זאת בדרך טובה יותר באמצעות קידום נתונים. פה אנו שולפים את האופרנד ישירות משלב בצינור במקום להמתין לכתיבה שלו בחזרה ב-.

וכך זה נראה ב-:

המימוש המוצג פה הוא לא מלא והוא נותן לנו רק:
א.
ב.
ג.
אך אם נרצה לעשות דברים אחרים, כמו אם יש לנו כפול, לא נוכל לעשות זאת במימוש הזה.
add x1,x1,x2
add x1,x1,x3
add x1,x1,x4
נשים לב כי פה לא נוכל לבצע ולכן נדרש לעשות .
כפול
נממש כעת את הביעבוע הזה שהוא האפשרות היחידה שלנו לפתור את הבעיה שראינו.

במבחן הם ידרשו להגיד לנו האם למעבד יש או לא - אנחנו לא אמורים לדעת לבד.
בקרה
נניח ואנו מבצעים פקודת , הקפיצה תבוצע לכל הפחות בשלב ה- אך עד שהיא תקרה, שתי הפקודות הבאות יכנסו לצינור.
אם אנו קפצנו, שתי הפקודות הללו לא היו אמורות להתבצע.
⟸ על מנת לפתור זאת, אם הקפיצה כן נלקחת, נבצע ע"י המרת הפקודות הללו ל-.
⟸ כל שנלקח ב- פשוט עולה לנו ב- מחזורים 'ריקים'.
על מנת לשפר ביצועים, ניתן להשתמש ב"חיזוי קפיצות" כדי לנחש את כיוון ה- מוקדם יותר ב-.
⟸ רק במקרה שהחיזוי התגלה כשגוי נבצע .
תרגול
נתון מעבד V-RISC pipelined כאשר ה-branch מתבצע בשלב execute. המעבד מניח כי ה- branch אינו מתרחש ועושה flush במקרה שכן. המעבד בעל unit forwarding ,hazard load אשר מכניס bubble כפי שנלמד בכיתה.
main: addi t1,x0,1
lw t0, 0(x0)
loop: sub t0,t0,t1
bne t0,x0,loop
addi t2,x0.0xf
nop
nop
nop
nop
nop
א. ציינו בטבלה איזו פקודה, עד לשלב ה- מתבצע בכל שלב ב- (חלק מהשדות מולאו עבורכם).
ב. כמה מחזורי שעון תקח הרצת התוכנית הנ"ל?
פתרון א':

פתרון ב':
התוכנית תקח עד אשר כל הפקודות יתבצעו לא כולל ה--ים ולכן, מחזורי שעון!
נתון קטע הקוד הבא:
lw t2, 1000(t5)
add t3,t1,t2
sub t2,t1,t2
addi t0,t2,10
כדי להפעיל את הקוד הנ"ל במחשב ה- יש צורך אולי במעקפים הוספת שורה/שורות .
הסבירו היכן (אם בכלל) יש להוסיף nops ואלו מעקפים דרושים ב-pipeline (מאיזה חלק לאיזה חלק במעבד ה Pipeline)
תחילה אנו רואים שאנו טוענים את ואז ישר משתמשים בו בפקודה הבאה ולכן, נדרש פה לבצע הכנסה של כדי להשהות את ביצוע התוכנית למשך מחזור שעון אחד.
כעת, בזכות הכנסת ה-, נוכל לבצע מ- ל-
לאחר מכן אנו שוב משתמשים ב- בפקודה הבאה, אך הפעם זה לאחר שעשינו אחד ולכן, נוכל לבצע מ- ל-.
לאחר מכן אנו שוב משתמשים ב- ולכן, מכיוון שזה ערך חדש וזו פקודה שמגיעה ישר אחרי, נוכל לבצע מ- ל-.
מומלץ לשרטט טבלה כדי שהכל יהיה ברור.
נתון מעבד מצונרר אשר בו ה- מתבצע בשלב ה-.
מריצים על מעבד זה תוכנית אשר מכילה את הפקודות: אך ללא וללא .
המעבד מניח כי ה- אינו מתרחש ועושה במקרה שכן.
בחרו בטענה הנכונה:
- הרצת כל התוכנית על המעבד המתואר בשאלה תקח בהכרח זמן רב יותר מאשר הרצה על מעבד אשר בו הקפיצה תתרחש בשלב ה-.
- הרצת כל תוכנית על המעבד המתואר בשאלה תקח בהכרח אותו הזמן כמו הרצה על מעבד אשר בו הקפיצה תתרחש בשלב ה-.
- עבור תוכניות מסויימות התוכנית לא תרוץ כהלכה.
- ישנן תוכניות אשר מכילות פקודות בלבד אשר לא ירוצו כהלכה.
אנו יודעים כי לא יכולים להיות לנו בעיות או ולכן כל תוכנית אשר מכילה פקודות בלבד תרוץ כהלכה.
אם הקפיצה תתרחש בשלב ה- אז נגלה יותר מוקדם מה אנו נדרשים לבצע ואז לקפוץ מוקדם יותר ולבצע מוקדם יותר, אך נשים לב כי זה לא מתרחש עבור כל תוכנית, אלא רק בתוכנית עם שקופץ.
בהתאם להנ"ל - 2 לא נכון גם כן.
אם אנו מקבלים החלטה על בשלב ה-, כפי שנתון בשאלה, והפקודה הבאה היא ששומרת בזיכרון, היא כבר הגיעה לשלב ה- והיא שומרת שם ערך כשאנחנו לא אמורים ולכן תוכנית זו לא תרוץ כהלכה. (טענה 3 נכונה)
במעבד אמיתי, אי אפשר לבצע קפיצה ב-.
בהמשך לשאלה, אם נוסיף למעבד , זה לא ישנה כלום!!