יצירת פרופיל למשחק WebGL שלך באמצעות הדגל about:tracing

Lilli Thompson
Lilli Thompson

אם אי אפשר למדוד אותו, אי אפשר לשפר אותו.

לורד קלווין

כדי שמשחקי HTML5 שלך יפעלו מהר יותר, עליך לזהות קודם את צווארי הבקבוק בביצועים, אבל זה יכול להיות קשה. הערכת הנתונים של פריימים לשנייה (FPS) היא התחלה, אבל כדי לראות את התמונה המלאה, צריך להבין את הניואנסים בפעילויות ב-Chrome.

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

שלום על:מעקב

הפתרון של Chrome:כלי המעקב מאפשר לכם לקבל גישה לכל הפעילויות של Chrome בתקופה מסוימת, עם רמת פירוט גבוהה כל כך עד כמה שקשה לכם במיוחד. רבות מהפונקציות ב-Chrome מותאמות להטמעה מחוץ לקופסה, כך שאפשר להמשיך להשתמש במעקב אחרי הביצועים בלי להגדיר אינסטרומנטציה ידנית. (עיינו בקטע מאוחר יותר על אינסטרומנטציה ידנית של JS)

כדי לראות את תצוגת המעקב, פשוט מקלידים "about:tracing" בסרגל הכתובות של Chrome.

סרגל הכתובות ב-Chrome
סוג "about:tracing" בסרגל הכתובות של Chrome

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

תוצאת מעקב פשוטה
תוצאת מעקב פשוטה

כן, זה מבלבל, בסדר. בואו נראה איך לקרוא את זה.

כל שורה מייצגת תהליך של יצירת פרופיל, הציר השמאלי מציין את הזמן וכל תיבה צבעונית היא קריאה לפונקציה אינסטרומנטלית. יש שורות שמייצגות כמה סוגים שונים של משאבים. הגורמים המעניינים ביותר ליצירת פרופיל משחקים הם CrGpuMain, שמציג את הביצוע של יחידת העיבוד הגרפית (GPU) ו-CrRendererMain. כל מעקב מכיל שורות CrRendererMain לכל כרטיסייה פתוחה במהלך תקופת המעקב (כולל הכרטיסייה about:tracing עצמה).

במהלך קריאת נתוני מעקב, המשימה הראשונה היא לקבוע איזו שורה של CrRendererMain תואמת למשחק שלך.

תוצאת מעקב פשוטה מודגשת
מודגשת תוצאה פשוטה של מעקב

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

איתור הפריים

אחרי שמוצאים את השורה הנכונה בכלי המעקב של המשחק, השלב הבא הוא למצוא את הלולאה הראשית. הלולאה הראשית נראית כמו דפוס שחוזר על עצמו בנתוני המעקב. אפשר לנווט בנתוני המעקב באמצעות המקשים W , A , S , D , A ו-D כדי לנוע שמאלה או ימינה (קדימה ואחורה) ו-W ו-S כדי להגדיל או להקטין את התצוגה של הנתונים. אפשר לצפות שהלולאה הראשית תהיה תבנית שחוזרת על עצמה כל 16 אלפיות השנייה אם המשחק פועל ב-60Hz.

נראה כמו שלוש מסגרות הפעלה
נראה כמו שלוש מסגרות הפעלה

לאחר שתזהו את פעימות הלב של המשחק, תוכלו לבדוק מה בדיוק הקוד עושה בכל פריים. כדי להגדיל את התצוגה, משתמשים במקשי הקיצור W, A, S, D עד שאפשר לקרוא את הטקסט בתיבות של הפונקציות.

עמוק בתוך מסגרת הביצוע
ניתוח מעמיק של מסגרת הביצוע

באוסף התיבות הזה מוצגת סדרה של קריאות לפונקציות, שכל אחת מהן מיוצגת על ידי תיבה צבעונית. לכל פונקציה נשלחה קריאה דרך התיבה שמעליה, כך שבמקרה הזה ניתן לראות את הפונקציה MessageLoop::RunTask שנקראת RenderWidget::OnSwapBufferscomplete , שנקראת RenderWidget::DoDeferredUpdate וכן הלאה. קריאת הנתונים האלה תאפשר לכם לקבל תמונה מלאה של מה שנאמר ומה משך הזמן של כל הפעלה.

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

הוספת תגי מעקב

למרבה המזל, יש דרך ידידותית להוסיף לקוד שלך הגדרה ידנית כדי ליצור נתוני מעקב: console.time ו-console.timeEnd.

console.time("update");
update();
console.timeEnd("update");
console.time("render");
update();
console.timeEnd("render");

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

תגים נוספו באופן ידני
תגים שנוספו ידנית

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

GPU או CPU?

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

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

מעקבי GPU ומעבד (CPU)

אתם יכולים לראות שכל פריים במשחק גורמת לפעולת המעבד (CPU) ב-CrRendererMain וגם ב-GPU. במעקב שלמעלה מוצג תרחיש פשוט מאוד שבו גם המעבד (CPU) וגם ה-GPU לא פעילים במשך רוב כל פריים של 16 אלפיות השנייה.

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

console.time("update");
doExtraWork();
update(Math.min(50, now - time));
console.timeEnd("update");

console.time("render");
render();
console.timeEnd("render");

עכשיו תראו מעקב שנראה כך:

מעקבי GPU ומעבד (CPU)

מה המעקב הזה עוזר לנו? אנחנו יכולים לראות שהפריים בתמונה עולה בערך מ-2,270 אלפיות השנייה עד 2,320 אלפיות השנייה, כלומר כל פריים לוקח בערך 50 אלפיות השנייה (קצב פריימים של 20Hz). לצד תיבת העדכון מוצגים שורות צבעוניות של תיבות צבעוניות שמייצגות את פונקציית העיבוד, אבל העדכון עצמו שולט במלואו.

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

מה קורה כשקוד ההצללה עצמו איטי וה-GPU עמוס מדי? מה קורה אם מסירים את העבודה המיותרת מהמעבד ונוסיף במקום זאת קצת עבודה בקוד של תוכנת ההצללה למקטעים. הנה כלי יקר להצללה של מקטעים:

#ifdef GL_ES
precision highp float;
#endif
void main(void) {
  for(int i=0; i<9999; i++) {
    gl_FragColor = vec4(1.0, 0, 0, 1.0);
  }
}

איך נראה עקבות של קוד שמשתמש בכלי ההצללה הזה?

מעקבי GPU ומעבדי CPU כשמשתמשים בקוד GPU איטי
מעקבי GPU ומעבדי CPU כשמשתמשים בקוד GPU איטי

שוב, שימו לב למשך הפריים. כאן הדפוס החוזר נע מ-2,750 אלפיות השנייה ל-2,950 אלפיות השנייה, ומשך זמן של 200 אלפיות השנייה (קצב פריימים של כ-5Hz). השורה של CrRendererMain ריקה כמעט לחלוטין, כלומר המעבד (CPU) לא פעיל רוב הזמן בזמן שה-GPU עמוס מדי. זה סימן בטוח לכך שתוכנות ההצללה כבדות מדי.

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

דוגמאות אמיתיות

עכשיו נראה איך נראה מעקב אחר נתוני מעקב ממשחק אמיתי. אחד הדברים המגניבים במשחקים שפותחו עם טכנולוגיות אינטרנט פתוחות הוא האפשרות לראות מה קורה במוצרים המועדפים עליך. אם ברצונך לנסות את כלי הפרופיילינג, יש לך אפשרות לבחור את כותרת WebGL המועדפת עליך מחנות האינטרנט של Chrome ולפרופיל אותה באמצעות about:tracing. זו דוגמה למעקב מתוך המשחק Skid Racer המעולה של WebGL.

עוקבים אחרי משחק אמיתי
מעקב אחרי משחק אמיתי

כל פריים נמשך כ-20 אלפיות השנייה, כלומר קצב הפריימים הוא בערך 50 FPS. אפשר לראות שהעבודה מאוזנת בין המעבד (CPU) ל-GPU, אבל ה-GPU הוא המשאב עם הכי הרבה ביקוש. אם אתם רוצים לראות איך נראית יצירת פרופיל לדוגמה של משחקי WebGL, נסו לשחק עם כמה מהכותרים בחנות האינטרנט של Chrome שפותחו באמצעות WebGL, כולל:

סיכום

אם אתם רוצים שהמשחק יפעל ב-60Hz, אז כל הפעולות צריכות להתאים ל-16 אלפיות השנייה של מעבד (CPU) ול-16 אלפיות שנייה של זמן GPU. יש לך שני משאבים שניתן להשתמש בהם במקביל, ואפשר לעבור ביניהם כדי למקסם את הביצועים. המידע על תצוגת מעקב ב-Chrome הוא כלי חשוב שעוזר לכם להבין מה הקוד שלכם עושה בפועל, והוא יעזור לכם לנצל את זמן הפיתוח ולמקסם את זמן הפיתוח.

מה השלב הבא?

מלבד GPU, אפשר גם לעקוב אחרי חלקים אחרים של זמן הריצה של Chrome. Chrome Canary, גרסת השלב המוקדם של Chrome, משמש למעקב אחר IO, IndexedDB ומספר פעילויות נוספות. כדאי לקרוא את המאמר הזה ב-Chromium כדי להבין טוב יותר את המצב הנוכחי של אירועי המעקב.

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