ניתוח תזמון השרשורים

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

  • קצב פריימים
  • ריבוי נימים (Multithreading) וטעינה מקבילה של נימים
  • הקצאת ליבות מעבד (CPU)

ריבוי שרשורים

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

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

משחק עם thread ראשי ו-thread של רינדור שעברו פרלליזציה טובה, וגם עם thread של עובד ו-thread של אודיו
איור 1. משחק עם thread ראשי ו-thread עיבוד מקביליים, וגם thread של עובד ו-thread של אודיו

הקצאת ליבות מעבד (CPU)

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

  • האם השרשורים של המשחק פועלים על הליבה המתאימה ביותר לעומס העבודה שלהם.
  • האם ה-threads של המשחק עוברים בין ליבות בתדירות גבוהה.

במכשירים מודרניים נעשה לעיתים קרובות שימוש בארכיטקטורה שנקראת חישוב הטרוגני, שבה לליבות יש רמות ביצועים שונות:

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

כדי לחקור את התנהגות ה-thread של המעבד, צריך להפעיל את האפשרות CPU בהגדרות הפרופיל כשמבצעים מעקב, ואז לעבור אל CPU Usage. אם תגדילו את התצוגה של חלק מהמעקב <200 ms, תוכלו לראות את התהליכים הנפרדים שפועלים בליבות של המעבד במכשיר. בדרך כלל, ליבות קטנות יותר מתאימות למדדים קטנים יותר (לדוגמה, מעבדי CPU‏ '0'-'3'), בעוד שליבות גדולות יותר מתאימות למדדים גבוהים יותר (לדוגמה, מעבדי CPU‏ '6'-'7'), וליבות ביניים, אם יש כאלה, יתאימו למדדים שביניהם (לדוגמה, מעבדי CPU‏ '5'-'6'). זהו הנוהג המקובל, אבל אין בכך ערובה.

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

משחק עם שרשור ראשי ושרשור עיבוד שפועלים בעיקר על הליבות הגדולות (CPU 6-7), שמוצגות בכחול בהיר
איור 2. משחק עם שרשור ראשי ושרשור עיבוד שפועלים בעיקר על ליבות גדולות (CPU 6-7), שמוצגות בכחול בהיר

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

משחק עם thread ראשי (Thread-7) ו-thread של רינדור (Thread-8) שעוברים בין ליבות, מוצגים בסגול
איור 3. משחק עם תהליכון ראשי (Thread-7) ותהליכון עיבוד (Thread-8) שעוברים בין ליבות, מוצגים בסגול

הגדרת שיוך CPU לשרשור מורה למערכת לתזמן אותו בליבה הנתונה כשהמשחק פועל בחזית. יש כמה גורמים שכדאי לקחת בחשבון כשעושים את זה:

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

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

  • אם תכפו את ההתאמה לליבות גדולות, יכול להיות שתגבירו שלא לצורך את צריכת הסוללה ואת העומס התרמי.

לכן, בדרך כלל מומלץ להימנע מהגדרה ידנית של שיוך ליבות CPU.