הרעיון: דפדוף paging וזכרון וירטואלי.1.2.3 לחלק את מרחב הכתובות לדפים בגודל קבוע )למשל )4KB את הדפים ממפים לזכרון פיסי a. לא רציף b. לא כולם העברה מזכרון לדיסק לפי הצורך מספר הדף: page = addr 4K המיקום בדף: off = addr % 4K כל מה שצריך הוא שתהיה לנו טבלת מיפוי )דומה לטבלה משבוע שעבר( table page לוקחים ממנה את מספר הדף, הוא מזהה כניסה לתוך טבלת הדפים. איך עושים את זה? יהיה לנו רגיסטר שמצביע להתחלת טבלת הדפים מחברים את הכתובת ומקבלים את המיקום בטבלה. מה שכתוב שם הוא איפה הדף ממופה בזכרון הפיסי. גם הוא מחולק ליחידות בגודל 4K שנקראות מסגרת )frame( ומה שאנחנו רוצים לעשות הוא למפות דפים לתוך.frame כל הדפים הם באותו גודל, לכן כל דף יכול להתמפות לכל frame פנוי. אל המיקום של ה frame מתוך ה page table נחבר את ה offset ונקבל את המיקום בזכרון. 1
כל התהליך הזה צריך להעשות על כל גישה לזכרון. זה אומר שאין לנו הרבה זמן לעשות את התהליך הזה... מהירות המעבד היא באזור 2 ג'יגה, נניח לצורך הפשוטות ג'יגה, לכן בכל שניה יש 10 ב 9 סייקלים, כלומר ננו שניות. הקריאה הזו לזכרון נעשית בכל סייקל, לכן לא יכול להעשות על ידי מערכת ההפעלה, בה כל פעולה לוקחת לפחות כ 1000 סייקלים. כלומר, דרושה תמיכת מעבד. מערכת ההפעלה בכל זאת קשורה לזה היא עושה שני דברים: היא מארגנת את הטבלה הזו table( )page היא זו שמנהלת את המיפוי- מחליטה לכל דף באיזה frame הוא ישכון. דבר שני הוא שכאשר תהליך מתחיל לרוץ היא רושמת ברגיסטר שזוהי הכתובת המתאימה לתהליך הספציפי הזה. לכל תהליך יש מיפוי של מרחב הכתובות שלו עם page table משלו. כאשר עוברים מתהליך אחד לאחר כל מה שצריך לעשות הוא להחליף את הערך של הרגיסטר ולהצביע על טבלה אחרת ואז תתאפשר גישה לדפים של התהליך החדש. עד כה תארנו מצב סטטי בו הכל מאורגן ואנחנו רוצים להגיע למקום מסוים. מה קורה עד למצב זה? איך הגענו למצב המסודר הזה? הצורה שבה הדברים האלו עובדים נקראת.demand paging המצב הטבעי הוא שלא כל מרחב הכתובות ממופה ל frameים. כי אין מספיק מקום וכי אנחנו עדים לא צריכים אותו. מרחב הכתובות כולל גם את הקוד של התוכנית, וקוד של תוכנית בכל ריצה ספציפית משתמשים בחלק קטן מאוד של הקוד. לדוגמה, קוד שגיאה לא מגיעים אליו בהרצה נכונה של התוכנית. כלומר, אין צורך להעלות את כל הקוד לזכרון. מה עושים? התהליך אומר "אני רוצה לקחת פקודה מכתובת מסוימת". כאשר הוא מגיע לשלב הקריאה מטבלה מגלים שאין מיפוי. אם קיים מיפוי, יהיה ביט נוסף בשורה המתאימה בטבלה שיסמן האם הדף ממופה. אם אין מיפוי )כלומר הביט לא דולק( נרצה ליצור מיפוי. נקבל סוג של אקספשיין המעבד לא יכול לבצע את הפעולה הנוכחית. בניגוד לאקספשיינים הקודמים הוא אינו מצביע על באג או בעיה בתוכנית. הבעיה היא של מערכת ההפעלה שלא עשתה את המיפוי. 2
מערכת ההפעלה תטפל באקספשיין הזה אשר נקרא page fault בעיה במיפוי הדף. מערכת ההפעלה צריכה למצוא מסגרת פנויה בזכרון ולמפות את הדף למקום הזה בזכרון. לאחר שעשתה זו מחזירה את התהליך לריצה בדיוק מהמקום בו היה האקספשיין והפעם הוא יכול להמשיך לרוץ. התהליך הזה לא אמור לקרות הרבה פעמים. כל ביצוע מיפוי כזה עולה לפחות פי 1000 מקריאה רגילה. הדפים שלא ממופים לזכרון היכן הם נמצאים? ב.HD להגיע ל HD לוקח כמה מילי שניות. המיפוי עושה העברה מזכרון לדיסק לפי הצורך. מערכת ההפעלה בסה"כ צריכה למצוא מסגרת פנויה. אם אין מסגרת פנויה, אנחנו צריכים לפנות דף אחד ולהעביר אותו לדיסק. כלומר, בכל פעולה כזו אנחנו מעבירים דפים הלוך ושוב בין הזכרון לדיסק. כאן נמצא האלגוריתם המעניין. המעבד נותן עוד תמיכה במנגנון המיפוי - למנגנון המיפוי יש cache מיוחד משלו. נקרא.TLB כך המיפוי יכול להעשות תוך סייקל אחד. יתרונות וחסרונות של המנגנון גמישות אנחנו לא מוגבלים בגודל. מספר הדפים שאנחנו מקצים גדול. ווירטואליזציה - רוצים לנתק בין ה"תדמית" של הזכרון לפיסיות שלו. כל תהליך חושב שיש לו מרחב כתובות גדול משלו, למרות שזה מנותק מכמה זכרון פיסי יש לנו עבור התהליך. אנחנו עושים את זה בצורה שהתהליך לא ישים לב. פרגמנטציה מקטין את הפרגמנטציה. כל דף של 4K אפשר לשים במסגרת של 4K אין בעיה של קטע פנוי שלא ניתן להקצות אותו )פרגמנטציה חיצונית(. כשהקצנו אותו לא בטוח שהסגמנט צריך את כל ה 4K. כלומר, על כל קטע רציף שמקצים בדפים אנחנו מצפים לאבד לכל היותר 4K ובממוצע 2K על כל דף. כלומר, פרגמנטציה פנימית נמוכה, וחיצונית לא קיימת. אגלוריתם לדפדוף הכי פשוט: FIFO לא כל כך יעיל. חלק מהגרסאות של חלונות משתמשות בזה. 3
הכי טוב: נעביר לזכרון דפים שלא נשתמש בהם או רחוק בעתיד. חסרון: לא יודעים את העתיד אבל: יש לוקאליות מתוך כל מרחב הכתובות הגדול של התוכנית, בכל רגע נתון התוכנית נוטה להתרכז באזור מסוים. פתרון: אלגוריתם.Least Recently Used LRU מי שלא השתמשתי בו הכי הרבה זמן בעבר, בסכוי טוב אני כבר לא צריך אותו, לכן נזרוק אותו. חסרון האלגוריתם: דורש להחזיק רשימה של אלמנטים ולדאוג לסידור לפי סדר השימוש בהם. מאוד לא יעיל. מה עושים? לגבי כל דף, בנוסף לביט ה,valid יש ביט נוסף.used כל פעם שעושים מיפוי ועוברים דרך כניסה למיפוי מדליקים את ה.used bit למעשה, כל פעם שנעשה מיפוי לדף מסוים, הביט ידלק כלומר, לכל מקום שיש לו מיפוי הביט דלוק. אלגוריתם השעון )נקרא גם )second chance קירוב ל LRU אנחנו רוצים להסתכל על הזכרון הפיסי ולמצוא מסגרת שלא השתמשנו בה הרבה זמן. מחלקים את הקבוצות ל 2 אלו שהשתמשנו בהם לאחרונה ואלו שלא השתמשנו בהם לאחרונה נעשה את זה בצורה מעגלית הזכרון יצויר בצורה מעגלית. המחוג מצביע על המסגרת עליה מסתכלים כרגע. אם ה used bit של המסגרת שמסתכלים עליה הוא 1, עוברים למסגרת הבאה ומאפסים את ה used bit שלו. ממשיכים עד שמוצאים מסגרת עם 0, used bit לכן מצאנו מסגרת שמאז הסיבוב הקודם לא נגענו בה, לכן נזרוק אותה ונכניס במקומה את הדבר החדש והביט שלו ידלק. תנאים ליעילות וכדאיות דפדופים 1. לוקאליות לתוכנית יש working set קבוצת הדפים שבה היא משתמשת. קב' הדפים שניגשנו אליהם ב 13000 )לדוגמה( הפקודות האחרונות מזהות לנו בקירוב טוב את הפקודות הבאות 2. דיסק יותר גדול ויותר זול 4
מחיר לוקח זמן לטפל ב.page faults כאשר הנתונים לא נמצאים בזכרון, מערכת ההפעלה מתפעלת את המצב כפי שראינו לעיל מעבר הלוך ושוב בין הזכרון לדיסק. זמן של פעולת דיסק עולה. בזמן הזה התהליך מחכה להעתק הנתונים, ולא יכול לעשות כלום ביניתיים )לא יכול לבצע את הפעולה עד שלא נסיים להעביר את הקובץ( כל כמה זמן זה קורה? עובד טוב אם יש מספיק זכרון פיסי לכן הזמן של ריצה בין page faults גדול יחסית. הבעיה: thrashing כל פעם שמשרתים page fault אנחנו בוחרים לא טוב. כל הזמן יש לנו page faults וזה מעט מאוד את המערכת. איך המשתמש מזהה את זה? הכל תקוע שום דבר לא זז. איך מערכת ההפעלה תזהה את זה? תספור.page faults אם יש כל הזמן page faults מערכת ההפעלה יכולה למדוד ולהבין שאנחנו ב.thrashing מה מערכת ההפעלה יכול לעשות בנידון? אפשר לבנות יותר זכרון פיסי לא על ידי מערכת ההפעלה. התהליכים יקטינו את ה working set שלהם לא ניתן לעשות. מערכת ההפעלה יכולה להרוג את התהליך, וזה יעבוד אבל קצת דרסטי. אפשר לבחור תהליך אחד כקורבן ונעתיק את כל הדפים שלו ל.HD הפעולה הזו נקראת swap.out התהליך הזה עכשיו לא יכול לרוץ. אפשר להחזיר אותו לחיים אח"כ. ברגע שעושים,swap out לפחות התהליך הזה מפסיק להעמיס על הזכרון הפיסי. כל מה שהיה שייך לתהליך הזה מחולק עכשיו בין האחרים. בתקווה, עכשיו ה working set של התהליכים שנשארו יכנסו לזכרון הפיסי. אם לא, נעשה swap out להליך נוסף וכן הלאה. דפדוף גלובלי - כל המערכת כיחידה אחת. בדפדוף גלובלי לא צריך לחשוב כמה דפים לתת לכל אחד מהתהליכים. המחיר הוא שיכול להיווצר מצב.thrashing פתרון נוסף הוא לעשות דפדוף לוקלי ואז כל תהליך יכול לדפוק רק את עצמו. דפדוף לוקלי מכריח ליצור אלגוריתם לכמה דפים להקצות לכל תהליך. 5