חדשות היום

חמישה מיתוסים באשר לגודל הקוד של מיקרו-בקרי 32 ביט

ג’וזף ייו ואנדרו פריים, ARM

מאז שהחלו לצאת לשוק מעבדי 32 ביט כדוגמת ה-Cortex-M3 של ARM, יותר ויותר משתמשי מיקרו-בקרים מגלים את היתרונות הטמונים במעבר למוצרי 32 ביט – דרישות הספק נמוכות יותר, יעילות אנרגיה טובה יותר, ממדי קוד קטנים יותר ורמת ביצועים גבוהה בהרבה. בעוד שרוב היתרונות הטמונים בשימוש במיקרו-בקרי 32 ביט ידועים לכול, רבים אינם מודעים ליתרון של ממדי קוד שמציעים המיקרו-בקרים הללו. מיקרו-בקרים של 32 ביט יכולים להקטין את ממדי קוד היישום ובמקביל עדיין להשיג רמה גבוהה של ביצועי מערכת בשילוב עם קלות שימוש.

המיתוסים הרווחים באשר לגודל הקוד
מיתוס מס’ 1: למיקרו-בקרים של 8 ביט ושל 16 ביט יש ממדי קוד קטנים יותר
ישנה תפיסה רווחת – אך שגויה – לפיה המעבר ממיקרו-בקר של 8 ביט למיקרו-בקר של 32 ביט מוביל לקוד בממדים הרבה יותר גדולים. מאין נובעת השגיאה הנפוצה הזו? רבים סבורים כי מיקרו-בקרים של 8 ביט משתמשים בפקודות של 8 ביט ואילו מיקרו-בקרים של 32 ביט משתמשים בפקודות של 32 ביט. במציאות, רוב הפקודות במיקרו-בקרים של 8 ביט הן של 16 ביט, 24 ביט או בממדים אחרים העולים על 8 ביט. לכן, האם ממדי הקוד יהיו טובים יותר אם נעבור למיקרו-בקר של 16 ביט? לא בהכרח.
ומה עם ממדי קוד עבור מיקרו-בקרי Cortex מבית ARM? המעבדים Cortex-M3
ו-Cortex-M0 של ARM מבוססים טכנולוגיית Thumb-2, המספקת צפיפות קוד מצוינת. למיקרו-בקרים המבוססים Thumb-2 יש פקודות באורך 16 ביט כמו גם פקודות באורך 32 ביט. ברוב המקרים מהדר C משתמש בגרסת ה-16 ביט של הפקודה ואילו פקודת ה-32 ביט תשמש רק במצבים שבהם לא ניתן לבצע את הפעולה עם פקודה באורך 16 ביט. כתוצאה מכך, רוב הפקודות בתוכניות של מיקרו-בקר ARM Cortex הן כאלו של 16 ביט. וחשוב לציין שזה אפילו קטן יותר מכמה מהפקודות המשמשות במיקרו-בקרים של 8 ביט.
מיתוס מס’ 2: היישום שלי מעבד רק נתונים של 8 ביט ושל 16 ביט
רבים מהמפתחים חושבים שאם היישום שלהם מעבד רק נתונים של 8 ביט הרי שאין טעם לעבור למיקרו-בקר של 32 ביט. עם זאת, כאשר בוחנים את הפלט ממהדר ה-C בקפידה, מגלים שברוב המקרים סוג הנתונים של ה”מספר הצנוע” (humble integer) הוא של 16 ביט. לכן, כאשר יש לולאת “ for” עם מספר שלם המשמש כאינדקס לולאה, כשמשווים בין ערך לבין ערך מספר שלם, או כשמשתמשים בפונקצית ספריית C המשתמשת במספר שלם, למעשה משתמשים בנתונים של 16 ביט או יותר.
עובדה זו יכולה להשפיע על ממדי הקוד ועל הביצועים בדרכים שונות ומגוונות, לדוגמה:
* עבור כל חישוב של מספר שלם יהיה על מעבד של 8 ביט להשתמש בכמה פקודות כדי לבצע את הפעולות. זה מגדיל באופן ישיר את ממדי הקוד ואת מספר מחזורי השעון.
* אם ערך המספר השלם צריך להישמר בזיכרון, או אם יש צורך להעלות ערך מיידי
מ-ROM של התוכנית אל המספר השלם הזה, משימה כזו תצריך כמה פקודות וכמה מחזורי שעון.
* כיוון שמספר שלם יכול למלא עד שני אוגרים (רגיסטרים) של 8 ביט, יידרשו יותר אוגרים כדי להכיל את אותה כמות של משתני מספר שלם. כאשר מספר האוגרים בבנק איננו מספיק כדי להכיל את המשתנים המקומיים, חלקם חייבים להישמר בזיכרון. לכן כאשר משתמשים במיקרו-בקר של 8 ביט זה עשוי ליצור מצב שבו נדרשות יותר גישות זיכרון, מה שמגדיל את ממדי הקוד ומקטין את רמת הביצועים ואת התייעלות ההספק. אותה בעיה מופיעה גם כשרוצים לעבד נתוני 32 ביט על מיקרו-בקרים של 16 ביט.
* כשמשתמשים במיקרו-בקר של 8 ביט נדרשים יותר אוגרים כדי להכיל מספר שלם בעת העברת משתנים לפונקציה באמצעות הצבר (stack), או בעת שמירת תכני אוגר במהלך החלפת הקשרים או שירות פסיקות. עובדה זו מובילה לכך שמספר פעולת הצבר הנדרשות גבוה ממספר הפעולות הנדרשות במיקרו-בקרים של
32 ביט. זה מגדיל את ממדי התוכנית ויכול להשפיע גם על השהיית הפסיקות כיוון ששגרת שירות פסיקות (ISR) חייבת לוודא שכל האוגרים שבהם נעשה שימוש נשמרים בזמן הזנת ה-ISR ומשוחזרים בזמן יציאת ה-ISR. אותה בעיה חלה גם על העיבוד של נתוני 32 ביט על מיקרו-בקרים של 16 ביט.
ויש עוד חדשות רעות למשתמשים במיקרו-בקרים של 8 ביט: מצביעי כתובות זיכרון מצריכים כמה בייטים כך שעיבוד נתונים הכרוך בשימוש במצביעים (פוינטרים) עלול להיות מאוד בלתי יעיל.
מיתוס מס’ 3: מעבד 32 ביט אינו יעיל בטיפול בנתונים של 8 ביט ושל 16 ביט
כל מעבדי 32 ביט יעילים מאוד בטיפול בנתונים של 8 ביט ושל 16 ביט. ישנן פקודות גישת זיכרון קומפקטיות עבור נתוני 8, 16 ו-32 ביט, חתומים ולא חתומים. יש גם מספר פקודות הכלולות במיוחד לצורך המרת סוג הנתונים. בסך הכול הטיפול בנתוני 8 ו-16 ביט במעבדי 32 ביט הוא קל ויעיל ממש כמו הטיפול בנתוני 32 ביט.
מיתוס מס’ 4: ספריות C עבור מעבדי ARM נוטות להיות גדולות מדי
ישנן כמה אפשרויות של ספריית C עבור מעבדי ARM. יש כמה יצרניות מהדרים שפיתחו ספריות C עם טביעת רגל קטנה בהרבה במיוחד עבור יישומי מיקרו-בקר. לדוגמה, לכלי הפיתוח של ARM יש גרסה קטנה יותר של ספריית C המכונה  MicroLib. ספריות C אלה מתוכננות במיוחד עבור מיקרו-בקרים ומאפשרות קוד יישום בעל ממדים קטנים ויעילות גבוהה.
מיתוס מס’ 5: טיפול בפסיקות על מיקרו-בקר של ARM מסובך יותר
במיקרו-בקרים ממשפחות Cortex של ARM שגרות שירות הפסיקות הן פשוט תת-שגרות C רגילות. פסיקות עם וקטורים (vectored interrupts) או פסיקות קינון
(nested interrupts) נתמכות על-ידי בקר הפסיקות NVIC, ללא צורך בהתערבות תוכנה. למעשה, תהליך ההתקנה והעיבוד של בקשת פסיקה הוא הרבה יותר פשוט במיקרו-בקרים הללו מאשר עם מיקרו-בקרים של 8 או של 16 ביט, כיוון שבאופן כללי צריך רק לתכנת את רמת הקדימות של פסיקה ולאחר מכן לאשר הפעלתה.
וקטורי הפסיקה נשמרים בטבלת וקטורים בתחילת הזיכרון, בדרך כלל בתוך ההבזק, ללא צורך בשלבי תכנות תוכנה כלשהם. כאשר מתבצעת בקשת פסיקה המעבד מביא באופן אוטומטי את וקטור הפסיקה המתאים ומתחיל לבצע את ה-ISR. חלק מהאוגרים נדחפים אל הצבר על-ידי רצף חומרה ומשוחזרים באופן אוטומטי עם יציאת ה-handler של הפסיקה. שאר האוגרים שאינם מכוסים ברצף צברי החומרה נדחפים אל הצבר על-ידי קוד שמחולל מהדר C רק במקרה שנעשה שימוש באוגר והוא עבר שינויים בתוך ה-ISR.
אז מה עם המעבר למיקרו-בקרים של 16 ביט?
מיקרו-בקרים של 16 ביט יכולים להיות יעילים בטיפול במספרים שלמים של 16 ביט ובנתונים של 8 ביט, עם זאת, גודל הקוד עדיין איננו מטבי כמו בשימוש במעבדי 32 ביט:
* הטיפול בנתוני 32 ביט: אם היישום מצריך טיפול במספר שלם ארוך כלשהו (32 ביט) או בסוגים של נקודה צפה (floating point), הרי שיעילותם של מעבדי 16 ביט יורדת מאוד כיוון שנדרשות כמה פקודות עבור כל פעולת עיבוד, כמו גם העברות נתונים בין המעבד לזיכרון.
* שימוש באוגרים: כאשר מעבדי 16 ביט מבצעים עיבוד של נתוני 32 ביט נדרשים שני אוגרים כדי להכיל כל משתנה של 32 ביט. זה מקטין את מספר המשתנים שבנק האוגרים מסוגל להכיל, מה שמקטין את מהירות העיבוד ומגדיל את מספר פעולות הצבר וגישות הזיכרון
* מוד מיעון זיכרון: רבות מהארכיטקטורות של 16 ביט מספקות רק מוד מיעון בסיסי בדומה לזה של ארכיטקטורות של 8 ביט. כתוצאה מכך צפיפות הקוד גרועה כאשר משתמשים בארכיטקטורות הללו ביישומים המצריכים עיבוד של מערכי נתונים מורכבים
* מגבלת 64Kbytes: רבים ממעבדי ה-16 מוגבלים ל-64K bytes של זיכרון ניתן למיעון, מה שמקטין את הפונקציונליות של היישום. ישנן ארכיטקטורות של 16 ביט עם הרחבות המאפשרות גישה לזיכרון של יותר מ-64Kbytes, אולם להרחבות הללו יש תקורה של מחזורי שעון וקוד פקודה.

מסקנות
מעבדי 32 ביט מספקים ממדי קוד זהים לאלו של ארכיטקטורות 8 ביט ו-16 ביט, ולעתים אף טובים מהם, ובה בעת הם מספקים רמת ביצועים טובה יותר.
עבור המשתמשים במיקרו-בקרים של 8 ביט, המעבר לארכיטקטורת 16 ביט יכול לפתור חלק מהבעיות המוּבְנוֹת בארכיטקטורה של 8 ביט. עם זאת, עדיין לא ניתן להשוות את היתרונות הכוללים של המעבר מ-8 ל-16 ביט ליתרונות שמשיגים כשעוברים למעבדי Cortex של 32 ביט.
כיוון שצריכת ההספק והעלות של מיקרו-בקרים של 32 ביט קטנו מאוד בשנים האחרונות, מעבדי ה-32 ביט נהיו הבחירה המועדפת והכדאית עבור רוב הפרוייקטים של יישומים משובצים.

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