אלגוריתמים לניהול זיכרון דינמי – 236780 - Technion

‫הטכניון – מכון טכנולוגי לישראל‬
‫סמסטר אביב ‪2015‬‬
‫הפקולטה למדעי המחשב‬
‫אלגוריתמים לניהול זיכרון דינמי – ‪236780‬‬
‫תרגיל בית ‪1‬‬
‫להגשה עד יום ג' ‪ 19/5/2015‬ב‪ 12:00-‬בצהריים‬
‫בתא הגשת התרגילים של המקצוע בקומה ‪1‬‬
‫‪ .1‬תארו תוכנית שתגרום ל‪ lazy sweep-‬להתנהג כמו ‪ sweep‬רגיל‪ .‬כלומר‪ ,‬למרות‬
‫שה‪ collector-‬מנסה לבצע את ה‪ sweep-‬צעד אחר צעד‪ ,‬התוכנית תמיד תכריח אותו‬
‫לבצע את כל ה‪ sweep-‬בבת אחת‪
.‬‬
‫הערות‪:‬‬
‫א‪ .‬על התוכנית להצליח להקצות כל בקשה‪ ,‬כלומר היא אינה "עפה" בגלל מחסור‬
‫בזיכרון‪.‬‬
‫ב‪ .‬הפיתרון הטריביאלי של להקצות ולשחרר רק אובייקט אחד בכל מחזור איסוף‬
‫אינו מתקבל‪ .‬יש לאפשר ל‪ sweep-‬לשחרר לפחות ‪ 100‬אובייקטים בזמן האיסוף‪.‬‬
‫‪ .2‬שאלה זו מתייחסת ל‪:Generational Garbage Collection -‬‬
‫א‪ .‬בעת הרצת ‪ write barrier‬של ‪ card marking‬הניחו שמבצעים רק חישוב הכתובת של‬
‫הביט המתאים ל‪ card-‬ומדליקים אותו )ללא שום בדיקות נוספות(‪ .‬שימו לב‬
‫שפלטפורמות מודרניות לא מרשות לכתוב ביט לזיכרון אלא לכל הפחות בית שלם‪.‬‬
‫הדבר גורם לכך שכאשר מריצים ‪ write barrier‬כזה על מחשב רב‪-‬מעבדים צריך‬
‫לבצע פעולת סנכרון בין ה‪ mutators-‬בתוך ה‪.write barrier-‬‬
‫‪ .a‬הסבירו למה דרוש סנכרון‪.‬‬
‫‪ .b‬הציעו שיטה למנוע לחלוטין את הסנכרון ע"י הגדלת התקורה במקום‪ .‬מה‬
‫העלות במקום של השיטה שהצעתם? שימו לב שפעולה אטומית מפורשת‬
‫מהסוג של ‪ compare & swap‬נחשבת פעולת סנכרון‪.‬‬
‫‪ .c‬הציעו שיטה למנוע רק חלק מפעולות הסנכרון אבל ללא תקורה במקום‪.‬‬
‫)החלק של הפעולות שלא ידרוש סנכרון יכול להיות תלוי באפליקציה‪,‬‬
‫בהיסטוריה של הריצה וכו'( מה עלות השיטה )בזמן( ואילו מפעולות‬
‫הסנכרון היא חוסכת? ‬
‫ב‪.‬‬
‫נציע עתה שינוי ל‪ .Generational Garbage Collection-‬בשיטה החדשה‪ ,‬לעולם לא‬
‫נאסוף את הדור הצעיר לחוד‪ .‬כל איסוף קורה כשאין יותר מקום להקצאה ואז‬
‫אוספים גם את הדור הצעיר וגם את הדור המבוגר‪ .‬אבל‪ ,‬כל דור נאסף בשיטה‬
‫המתאימה‪ .‬הדור הזקן נאסף באמצעות ‪ mark and sweep‬והדור הצעיר נאסף‬
‫באמצעות ‪ .copying‬עליכם לציין יתרון אחד וחיסרון אחד של )מימוש יעיל של(‬
‫השיטה על פני ‪ generational garbage collection‬רגיל המשתמש ב‪ copying-‬לדור‬
‫הצעיר וב‪ mark and sweep-‬לדור המבוגר‪
.‬‬
‫‪ .3‬השאלה מתייחסת ל‪:Train Algorithm-‬‬
‫א‪ .‬מה יקרה אם נשנה את האלגוריתם באופן הבא‪ :‬כשמתחילים איסוף של רכבת‪,‬‬
‫יוצרים רכבת ‪ T‬חדשה )שמספרה גבוה מכל הרכבות הקיימות(‪ .‬כל אובייקט‬
‫שעבורו יש פוינטר כלשהו מחוץ לקרון הנאסף כרגע מועתק אל קרון ברכבת ‪.T‬‬
‫כשנגמר המקום בקרון שאליו מעתיקים ברכבת ‪ ,T‬פותחים קרון חדש ומתחילים‬
‫להעתיק אליו‪.‬‬
‫‪ .a‬האם כל המעגלים ייאספו גם לאחר השינוי? אם כן – הסבר כיצד‪ .‬אם לא –‬
‫הסבר מדוע לא‪.‬‬
‫‪ .b‬האם תמיד יהיה ניתן לאסוף רכיב קשיר לא נגיש שכולו בתוך הרכבת‬
‫הנוכחית?‬
‫‪ .c‬כיצד תשתנה תשובתכם ל‪ b-‬אם נוציא לרכבת ‪ T‬רק אובייקטים המוצבעים‬
‫מחוץ לרכבת הנוכחית?‬
‫ב‪ .‬כזכור‪ ,‬באלגוריתם המקורי נמצא באג הנובע מכך שהמצביעים משתנים ע"י‬
‫התוכנית בין איסוף קרון אחד למשנהו‪ .‬נציע תיקון שונה מזה שהוצג ע"י ‪Seligman-‬‬
‫‪ .Grarup‬עליכם לומר אם גם תיקון זה עובד כשורה )ולנמק( או להציע דוגמה נגדית‬
‫המוכיחה שאלגוריתם זה לא מתקן את הבאג‪
.‬‬
‫התיקון‪ :‬בעת ריצת התוכנית יש ‪ write barrier‬המעדכן את ה‪ .remembered set-‬נוסיף‬
‫ל‪ write barrier-‬בדיקה‪ :‬אם השינוי של המצביע הנוכחי מבטל הצבעה אל אובייקט‬
‫‪ A‬הנמצא ברכבת הנוכחית שאנו אוספים‪ ,‬אז נסמן את האובייקט ‪ A‬כאובייקט‬
‫מיוחד‪ .‬בעת איסוף הקרון‪ ,‬נעתיק את כל האובייקטים המיוחדים אל הרכבת‬
‫האחרונה ונוציא אותם מרשימת המיוחדים‪
.‬‬
‫בתשובתכם הפרידו בין שני מקרים‪ :‬מקרה בו ה‪ write-barrier-‬עובד גם על ה‪,roots-‬‬
‫ומקרה בו ה‪ write-barrier-‬לא פועל על ה‪.roots-‬‬
‫ג‪ .‬בהינתן שהרכבת התחתונה מכילה ‪ n‬קרונות ובכל קרון יש ‪ m‬אובייקטים תוך כמה‬
‫איסופים מובטח שרכבת זו תתרוקן או תיאסף? תארו את המקרה הגרוע ביותר‬
‫שיגרום למספר איסופים מקסימאלי לפני ריקון הרכבת לכל ‪ m‬ו‪ n-‬נתונים‪.‬‬
‫‪ .a‬הסבירו כמה איסופים צריך עבור הדוגמא שלכם‪.‬‬
‫‪ .b‬הוכיחו שזה המקרה הגרוע ביותר‪ .‬כלומר‪ ,‬לא ניתן להציג מקרה יותר גרוע‬
‫
‬
‫‪ .4‬שאלה זו מתייחסת לאלגוריתם ה‪ compaction-‬של ‪:Jonkers‬‬
‫א‪ .‬כזכור האלגוריתם משתמש בשרשור על‪-‬מנת לעדכן את המצביעים להצביע‬
‫למקום החדש של האובייקט‪ .‬הסבירו מהי פעולת השרשור וכיצד משתמשים‬
‫בה‪.‬‬
‫ב‪ .‬הסבירו כיצד ניתן לשלב את השרשור של השלב הראשון של האלגוריתם של‬
‫‪ Jonkers‬עם ה‪ trace-‬של האובייקטים בזמן ה‪ .mark-‬מה נותר לביצוע בפאזה‬
‫הראשונה של האלגוריתם המעודכן? ומה בפאזה השנייה?‬
‫ג‪ .‬האם ניתן להעביר יותר פעילות של הדחיסה לתוך ה‪) trace-‬ללא ביצוע ‪heap‬‬
‫‪ pass‬נוסף וללא שימוש בזיכרון נוסף( ואז לוותר על הפאזה הראשונה כולה?‬
‫ד‪ .‬כיצד ייקבע סדר האובייקטים בשרשרת של אובייקט כאשר יורץ האלגוריתם‬
‫שתכננתם בסעיף ב'?‬
‫ה‪ .‬האם ניתן לבצע את כל השרשורים בזמן ה‪ trace-‬בשיטה דומה לסעיף ב' ואז‬
‫לוותר על הפאזה הראשונה לחלוטין ולבצע מיד את הפאזה השנייה? אם כן –‬
‫הסבירו כיצד‪ .‬אם לא – נמקו‪.‬‬
‫ו‪ .‬כיצד ישפיע השינוי של סעיף ב' על ה‪ locality-‬של אלגוריתם הדחיסה? התייחסו‬
‫רק לשינוי שנגרם ע"י הכנסת השרשור של החלק הראשון אל תוך ה‪trace-‬‬
‫והוצאתו משלב המעבר הראשון‪ .‬האם אתם מצפים לשיפור ב‪ ?locality-‬הסבירו‪
.‬‬
‫הניחו שבניהם של אובייקטים נמצאים במקום אקראי כלשהו בזיכרון )ולאו‬
‫דווקא ליד האובייקטים ההורים(‪.‬‬
‫
‬
‫
‬
‫‪ .5‬נניח שהיה ניתן לקבל ממערכת ההפעלה מידע על "מצביעים הפוכים"‪ .‬כלומר‪ ,‬לכל‬
‫אובייקט היה ניתן לקבל )באופן פלאי( ביעילות רשימה של כל אבותיו ע"י הפעלת‬
‫קריאת מערכת "‪ "parents-get‬עם כתובת האובייקט‪) .‬רשימת האבות כוללת גם אבות‬
‫שהם שורשים‪ (.‬בשאלה זו נבדוק כיצד היה ניתן להשתמש בפעולה זו לאיסוף אשפה‪.‬‬
‫כשנאמר "נגיש"‪" ,‬אבות"‪ ,‬ו"בנים" נתכוון למושגים האלה ביחס למצביעים המקוריים‬
‫)ולא ההפוכים(‪
.‬‬
‫ניתן להניח שהרוטינה ‪ parents-get‬מתבצעת באופן אטומי והיא מודעת תמיד למצב‬
‫הנוכחי של ה‪ heap-‬על כל ההזזות שאובייקטים עברו עד נקודת הזמן שבו היא נקראה‪.‬‬
‫א‪ .‬האם בעזרת המידע על המצביעים ההפוכים בלבד ניתן לדעת עבור
‬
‫אובייקט נתון כלשהו אם הוא נגיש מהשורשים או לא )מבלי להתבונן במכוונים‬
‫ה"רגילים" שבתוך האובייקט(? נמקו‪.‬‬
‫ב‪ .‬במידה וגילינו שאובייקט אינו נגיש )מהשורשים(‪ .‬האם מובטח שגם כל בניו לא‬
‫נגישים? האם מובטח שגם כל אבותיו לא נגישים?‬
‫ג‪ .‬תארו אלגוריתם יעיל ככל האפשר ל‪ compaction-‬בסביבה זו המשתמש במעבר‬
‫אחד בלבד על ה‪) heap-‬בהינתן סימון מי מהאובייקטים חי ומי מת(‪ .‬הסבירו‬
‫את מחיר האלגוריתם בזמן ומקום‪.‬‬
‫ד‪ .‬נניח שכל תוכניות המחשב בג'אווה בעולם אינן מכוונות יותר משני מצביעים‬
‫אל אותו אובייקט‪) .‬כלומר לכל אובייקט יש לכל היותר ‪ 2‬אבות(‪ .‬תארו מימוש‬
‫)יעיל ככל יכולתכם( של ‪ .parent-get‬ניתן כמובן להשתמש ב‪ barrier-read-‬או‬
‫ב‪ ,barrier-write-‬בנוסף אולי לביצוע פעולות נוספות בזמן ה‪.compaction-‬‬
‫הסבירו את העלויות במקום וזמן‪.‬‬
‫ה‪ .‬עתה נניח שבתוכניות ג'אווה ל‪ 98%-‬מהאובייקטים יש לכל היותר שני אבות‪,‬‬
‫אבל לשאר האובייקטים ייתכנו יותר אבות‪ ,‬אך לכל היותר ‪ .10‬התוכלו לתאר‬
‫מימוש )יעיל ככל האפשר( של ‪ parent-get‬המסוגל לטפל גם ב‪2%-‬‬
‫האובייקטים הפופולאריים?‬
‫ו‪ .‬נניח שמנסים למקבל את האלגוריתם שהצעתם בסעיף ג' ע"י חלוקת ה‪heap-‬‬
‫לאזורים‪ .‬כל חוט מבקש אחריות על אזור )באופן מסונכרן( ואז מבצע‬
‫‪ compaction‬לוקלי באזור תוך הזזת האובייקטים בתוך האזור לתחילתו‪ .‬האם‬
‫ייתכן ‪ race‬בין חוטי ה‪ compaction-‬באלגוריתם‪
.‬‬
‫
‬
‫
‬