8.1 צינור ההוראות תרגול
תרגול - צינור ההוראות¶
תרגיל 1 - ציור דיאגרמת צינור¶
נתונות 4 הוראות הבאות שרצות על צינור קלאסי בן 5 שלבים (IF, ID, EX, MEM, WB):
- ציירו דיאגרמת צינור (טבלה של הוראות מול מחזורי שעון) בהנחה שאין שום hazards. בכמה מחזורים מסתיימות כל 4 ההוראות?
- עכשיו שימו לב - הוראה 3 (
add ecx, eax) תלויה בהוראה 1 (mov eax, 10). זהו data hazard. בהנחה שהמעבד תומך ב-forwarding מפלט EX לכניסת EX, ציירו שוב את הדיאגרמה. האם נדרש עיכוב? - שנו את הוראה 1 ל-
mov eax, [mem](load מזכרון). עכשיו התוצאה מוכנה רק אחרי שלב MEM. ציירו שוב את הדיאגרמה עם forwarding מפלט MEM לכניסת EX. כמה בועות (stalls) נדרשות?
תרגיל 2 - זיהוי סכנות¶
נתון קטע האסמבלי הבא:
mov eax, [ebx] ; (1) קריאה מזכרון
add eax, ecx ; (2) חיבור
mov [edx], eax ; (3) כתיבה לזכרון
sub ecx, 5 ; (4) חיסור
cmp ecx, 0 ; (5) השוואה
jz done ; (6) קפיצה מותנית
- זהו את כל סכנות הנתונים (data hazards) בקטע הזה. לכל סכנה, ציינו בין איזה שתי הוראות היא קורית ובאיזה אוגר.
- איזה מהסכנות ניתן לפתור באמצעות forwarding בלבד? איזה דורש stall?
- זהו את סכנת הבקרה (control hazard). איזה הוראות כבר נכנסו לצינור כשהjz מתחיל להתבצע?
- אם הjz כן קופץ, כמה מחזורים הולכים לאיבוד בpipeline flush (בצינור 5 שלבים)?
תרגיל 3 - חישוב תפוקה¶
- צינור בן 5 שלבים מריץ 100 הוראות. בהנחה שאין hazards כלל:
- כמה מחזורי שעון לוקח להריץ את כל 100 ההוראות?
- מהי התפוקה (הוראות למחזור - IPC)?
-
מהי התפוקה אם לא היה צינור כלל (כל הוראה 5 מחזורים)?
-
עכשיו נניח שכל 5 הוראות יש branch שגורם ל-pipeline flush מלא (5 מחזורים מבוזבזים). חשבו מחדש:
- כמה מחזורים לוקח להריץ 100 הוראות?
-
מהי התפוקה בפועל?
-
חזרו על סעיף 2, אבל הפעם עם צינור בן 20 שלבים (כמו Pentium 4). כמה מחזורים מבוזבזים על כל branch? מה התפוקה?
תרגיל 4 - CISC לעומת RISC ומיקרו-פעולות¶
נתונה ההוראה הבאה בx86:
הוראה זו מבצעת: קריאה מכתובת ebx+ecx*4 בזכרון, חיבור הערך עם eax, וכתיבה חזרה לאותה כתובת.
- פרקו את ההוראה הזו למיקרו-פעולות (uops) פשוטות - כל uop מבצע פעולה אחת בלבד (חישוב כתובת, load, פעולה אריתמטית, store). כמה uops קיבלתם?
- ציירו את דיאגרמת הצינור עבור ה-uops (בצינור 5 שלבים). כמה מחזורים לוקח לבצע את כל ה-uops?
- ההוראה המקבילה ב-RISC (ARM) תיראה כך:
ldr r4, [r1, r2, lsl #2] ; load מכתובת r1+r2*4 לתוך r4 add r4, r4, r0 ; r4 = r4 + r0 str r4, [r1, r2, lsl #2] ; store חזרה לזכרון
כמה מחזורים לוקחות 3 ההוראות האלה בצינור (עם forwarding)? השוו לתוצאה מסעיף 2. - אם הצינור הפנימי של מעבד x86 עובד על uops, מה היתרון בכך שהמתכנת (או הקומפיילר) כותב הוראות CISC ולא RISC?