לדלג לתוכן

מה זה Context Switch ואיך המחשב שלכם "מריץ" עשרות תוכניות בבת אחת

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

אז איך בדיוק זה עובד

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

הפעולה הזאת של לעצור תהליך אחד ולהתחיל להריץ תהליך אחר נקראת context switch, החלפת הקשר.

מה זה בעצם ה"הקשר" הזה

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

המעבד שומר את כל המידע הזה, טוען את המידע השמור של התהליך הבא, ומתחיל להריץ אותו כאילו כלום לא קרה.

מי מחליט מתי להחליף - Scheduler

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

המחיר שיש להחלפה הזאת

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

זו הסיבה שכאשר יש יותר מדי החלפות הקשר בזמן קצר, תופעה שנקראת thrashing, הביצועים הכוללים של המערכת יורדים בצורה חדה. המעבד מבזבז יותר זמן על ניהול ההחלפות עצמן מאשר על ביצוע עבודה בפועל.

אז זה מולטיטסקינג אמיתי

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

ואם אתם מתלבטים באמצע הדרך, יש קהילה שלמה בדיסקורד שאפשר להתייעץ איתה.

הצטרפו לקהילה בדיסקורד

לסיכום

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