חדשות היום

שיטות חדישות לניהול מערכות ריבוי ליבות על ידי מערכת ההפעלה לזמן אמת INtime

Chris Main, TenAsys Corporation

תחילתו של רעיון – מערכות הפעלה ו-Busses של Intel
למערכות הפעלה שמיועדות לבנית מערכות משובצות דרושות תכונות שונות מאלו של מערכות מחשבים המוגדרות General Purpose בכך שהן דורשות דטרמיניסטיות, רובוסטיות, וסטביליות שלעיתים עומדים בסתירה למאפיינים הנדרשים ממערכות הפעלה כמו Windows או Linux.
במאמר המצורף נתייחס לאופן התכנון של מערכת הפעלה להבטחת דטרמיניסטיות (תגובות לארועים בזמן קצר מאד וללא חריגות מזמן זה) וסטביליות (הבטחת סדר פעולות להפעלת כל רכיב I/O גם במרווחי זמן קצרים ביותר בין פעולה לפעולה). מערכת שמבטיחה דטרמיניסטיות מבטיחה גם סטביליות ולפיכך המונח שיוזכר כאן הוא דטרמיניסטיות כמושג המוביל.
אם נרצה לבנות מערכת שתספק דרמיניסטיות וכזו שניתנת להגדלה, אנחנו חייבים לתכנן זאת מלכתחילה. ליבת התוכנה היא זו שצריכה להיבנות בהתאם ואי אפשר להכניס אותה במועד מאוחר יותר.
תכונות אלו הוטמעו כבר בשנות השבעים של המאה הקודמת בתשתית מערכת ההפעלה שתוכננה על ידי אינטל עבור המחשבים מסידרת X86. כאשר אינטל תיכננה אז את המחשבים למערכות משובצות, היא הגדירה Bus ששמו היה Multibus. להבדיל מאחרים שאיפשרו רק ל-master אחד להשתלט על ה-bus, איפשר Multibus לכמה Masters להשתלט. כבר מתחילת השמוש ב-Multibus כאבן בניין – נבנתה התוכנה למערכות הללו בצורה שאיפשרה לכרטיסי master שונים, שמריצים מערכות הפעלה שונות לגשת לכרטיסי ה-I/O שונים.
כל כרטיס master במערכת מבוססת Multibus הריץ את מערכת ההפעלה שלו. למשל מערכת הפעלה לזמן אמת של Intel RMX על כמה מהם, ומערכות הפעלה כמו Unix או Windows על אחרים.
חברת TenAsys שרכשה את כל
ה-Intellectual Properly של אינטל בנושא מערכות הפעלה לזמן אמת, הרחיבה את החזון של אינטל ומיישמת אותו – כולל שימוש בחלק מהקוד ה”ותיק”, בטכנולוגיה העכשווית של מעבדים מרובי ליבות. מערכת הפעלה לזמן אמת INtime רצה על חלק מהליבות, ומערכת הפעלה Windows על הליבות הנותרות.

הצעות למימוש IPC – Inter Process Communication
מתכנני מערכות משובצות (Embedded) מעונינים להריץ את משימות האפליקציה בצורה כזו שעומס על משימה אחת לא ישפיע על הביצועים של משימה אחרת.
שאלת מפתח שמשפיעה על היכולת להגדיל את המערכת – Scalability – קשורה לאופן שבו תהליכים שרצים על מערכות ההפעלה השונות מתקשרים האחד עם השני או במילים אחרות: איך ממומש ה-IPC.
פתרון אחד לדילמה זו הוא הגדרת sockets למימשק בין שני תהליכים ספציפיים. החסרון המיידי הבולט של גישה זו הוא שיש צורך להגדיר עוד sockets כשהמערכת גדלה. חיסרון נוסף נעוץ בעובדה שתקשורת באמצעות sockets אינה דטרמיניסטית. לטיפול ב-socket ישנן מספר שכבות תוכנה כך שקשה לצפות מתי יגיב תהליך שנשלחה לו הוראת ביצוע מעל Socket. זו הסיבה שמערכות משובצות כמעט ואינן משתמשות ב socket כאמצעי תקשורת בין תהליכים.
דרך טובה יותר לבצע IPC היא על ידי שכבת transport “ניסתרת” שהמתכנת אינו רואה, ושאפשר לשנות אותה בתלות בקונפיגורציה מבלי שיש צורך לבצע שינוי בתוכנה. שכבת ה-Transport יכולה להשתמש ב-Shared Memory או ב-LAN וכאמור מבחינת היישום אין שוני בכתיבת התוכנה בתלות באופן שבו ממומש
ה-Transport.
מימוש ה-IPC ב-INtime
ב-INtime – מימוש הפתרון הוא באמצעות רשת של אובייקטים הקרויים Global Objects. לדרך תקשורת חדשנית זו ישנו API ל-Kernel לביצוע גילוי ותיחול של האוביקטים, כך שיישום שנטען על קונפיגורצית ריבוי ליבות ו\או ישום שמבוזר ברשת, יכול לתחל ולהתאים עצמו בצורה דינמית לסביבה – תוך כדי תהליך הטעינה הראשוני שלו.
אנו נשתמש במונח Node עבור ליבה של מעבד מרובה ליבות. Node שמריץ INtime יכול לתקשר באמצעים שיתוארו עם ליבות אחרות שמריצות INtime בין אם הליבה האחרת נמצאת על אותו המעבד, או על מעבד (ומחשב) אחר שמחובר לאותה רשת LAN.
כדי לאפשר את השיתוף והניצול האופטימלי בין הליבות, תוכננו בתוך INtime שני תהליכים מורכבים, שמפשטים למתכנן את בניית המערכת:
ובנוסף Global Object Manager שבקיצור נקרא .
ה-DSM הוא יישום שרץ על כל אחד מה Nodes בשיתוף עם “עמיתיו” שרצים על Nodes אחרים. היישום עוקב אחרי מצב המערכת ואחרי התקינות של מרכיבי המערכת ומנקה את המשאבים במקרה של סיום התהליכים או תקלה בהם. משימה נוספת היא הודעה לתהליכים אחרים על השינויים בסטטוס. ריבוי המשימות המוטלות עליו מראה את העומק שבו פועל ה-DSM, התורם לתקינות המערכת ומשחרר את כותב היישום מטיפול באותם נושאים.
בנוסף ל-DSM רץ כאמור על כל Node תהליך הקרוי Gobsnet Manager. תפקידו של תהליך זה הוא לאפשר לכל תהליך שרץ על מערכת הפעלה ב-Node אחד יכולת להעביר מידע ו\או להסתנכרן עם תהליך אחר שנמצא על Node אחר. בנוסף, ה-Gobsnet Manager מנקה את הרישום על כל ה-IPC Links שכבר לא נמצאים בשימוש ומשחרר את הזכרון שבו השתמשו. כמו “עמיתו” ה-DSM – ה-Gobsnet Manager משולב במערכת ההפעלה והתקורה (overhead) שלו נמוכה ביותר. השימוש בו מאפשר למפתח לתכנן דרך גידול (scaling) שנעזרת בהגדרות גמישות שישתנו אוטומטית עם הגידול. בצורה זו יותאם הגידול של האוביקטים המשמשים להעברת נתונים וסנכרון בין חלקי המערכת השונים – לגידול הכללי שבמערכת.
המימשק בצורה שתוארה הוא דטרמיניסטי ויעיל יותר מכל המימושים המסורתיים. באמצעותו יש למתכננים אפשרויות לקשר בין threads בצורות מגוונת, ולא להסתמך רק על מערכת תזמון מרכזית אחת.

שדרוג המערכת לצורך גידול – Scaling
נושא חשוב הוא שדרוגי התוכנה במערכות משובצות. אותה תוכנה בסיסית צריכה לשרת מספר רב יותר של יחידות I/O בעומסים גבוהים יותר מבלי לפגוע בדטרמיניסטיות. אי פגיעה בדטרמיניסטיות במהלך הגידול הינה דרישה שאופיינית למערכות משובצות ואינה נדרשת במערכות כמו Linux או Windows. כאשר המערכת לא תוכננה לגידול ומכילה “צמתות” שלא תוכננו לשרת יותר תהליכים, עלול השדרוג להיות יקר וקשה. צורת התקשורת והניהול של ה-Gobsnet וה-DSM שהוסברו לעיל מאפשרת לעבור לשימוש במעבדים חזקים ומרובי ליבות ללא השקעת פיתוח תוכנה, או לבזר את המערכת בחיבור LAN ובכך לתת למתכנן יתרון מעל מתחריו בניצול טכנולוגיות המתפתחות.

הקצאת I/O לליבה – עוד שיפור לדטרמיניסטיות
הימנעות משימוש במערכת תיזמון מרכזית אחת חשובה לשימור הדטרמיניסטיות במערכות מרובות ליבות שמצפים מהם להתרחב על ידי שימוש בליבות נוספות. רוב מערכות ההפעלה למעבדים מרובי ליבות מסתמכות על מערכת תזמון (Scheduler) אחת שמקצה Threads לריצה על ליבה שמתפנה. בגישה זו, כאשר התקן I/O מפעיל פסיקה, זמן רב מתבזבז עד שמערכת התזמון קובעת ומפעילה את ה-Thread שצריך לטפל בפסיקה. דרך עדיפה היא להתייחס ל-Threads של היישום כישות בלתי תלויה ולהצמיד אותם לליבות ולהתקני I/O כבר בזמן טעינתם הראשונית. פרט להקצאה זו מאפשרים להם לתקשר ביניהם מבלי להפריע לתהליכים אחרים שאינם מעורבים. תכונה זו ניתנת לשימוש לטובת כל יישום. כל ההתקנים יושבים על אותו ה-BUS – למשל PCI או PCI Express, אבל כל התקן משוייך לליבה לפי “מפתח דטרמיניסטיות”: ככל שהדרישה עבור התקן ה-I/O הינה
ל-jitter נמוך יותר – הפסיקות של ההתקן יוקצו לליבות פנויות יותר – כאלה שמטפלות בפחות פסיקות. כדוגמא ניקח את האופן שבו TenAsys מטפלת ביישום שהוא IP Stack. כיון שזהו יישום חשוב במספר רב של מערכות , TenAsys מספקת אותו כחלק סטנדרטי במוצר הבסיסי. ל-INtime ישנה תמיכה נרחבת ביותר במסכי קונפיגורציה ל-IP Stack – ודרכם אפשר להתרשם איך נכון לבזר את התקני ה-I/O כשעובדים עם INtime.

דוגמא לביזור I/O
ב-IP Stack
IP Stack עבור INtime הינו process שרץ מעל מערכת ההפעלה, בדיוק כמו כל יישום שיכתוב הלקוח. היישום משתמש בחומרה שהינה כרטיס רשת, למשל כרטיס שיש לו ארבע יציאות LAN. לכל יציאה
() ישנה פסיקה משלו. בכרטיסים העכשויים הפסיקות הן מסוג הקרוי –
Message Signaled Interrupts. בשלב הקונפיגורציה “משייכים” כל port ואת הפסיקות שלו לליבה מסוימת. היישום עצמו של ה-stack רץ מעל עותק מלא של מערכת ההפעלה בכל ליבה. הפרדה זו של הפסיקה גורמת לכך שאין הפרעה מפסיקות אחרות על אותה ליבה, והפרדת היישום עצמו (ה-IP Stack במקרה הזה) גורמת לכך שהיישום של הטיפול במידע שנכנס או יוצא מה port לא מופרע על ידי IP Stack שרץ על port אחר. איור מספר 2 ממחיש את ההפרדה הזו עבור כרטיס LAN מרובה ports. באיור זה ניתן גם להתרשם מהשוני הקיים ממערכות הפעלה כמו Windows. בעוד שב-INtime ה-ports ניתן לשייך לכל ליבה בנפרד, ב-Windows אין שיוך פרטני, וכל הטיפול בהתקן כולל הפסיקות המגיעות מ-ports שונים – מטופלות על ידי ליבה אחת. תכונה יחודית זו מאפשרת ל-INtime דטרמיניסטיות מעולה של יישומים מעל Ethernet תוך כדי גידול ליניארי ביכולת הביצוע בתמיכה במספר רב יותר של ports כפי שמודגם באיור מספר 2.

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

על המחבר
Christopher Main הינו ה-CTO ואחד המייסדים של TenAsy Corporation.
Chris הוביל את הפיתוח של טכנולוגיית הוירטואליזציה ואת מערכת ההפעלה INtime מיומה הראשון בשנת 1997. Chris ממשיך בתפקידו זה לאורך השנים שבהם עודכנה ושודרגה INtime לתמיכה במעבדים חדשים, גירסאות חדשות של Windows ו-Visual Studio, ומענה לדרישות משתנות של לקוחות בשווקים התחרותיים של מערכות משובצות.

תגובות סגורות