ניתוח באמצעות רינדור GPU בפרופיל

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

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

ייצוג חזותי

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

איור 1. תרשים רינדור פרופיל ב-GPU

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

איור 2. מקרא לתרשים לעיבוד של GPU של הפרופיל

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

שלבים והמשמעות שלהם

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

טיפול בקלט

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

כשפלח גדול

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

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

אנימציה

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

כשפלח גדול

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

מדידה/פריסה

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

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

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

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

כשפלח גדול

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

הקוד שהוספתם אל onLayout(boolean, int, int, int, int) או onMeasure(int, int) יכולות גם להוביל לביצועים בעיות נפוצות. Traceview וגם השירות Systrace יכול לעזור לך לבדוק את קריאות ה-calltacks לזיהוי בעיות שייתכן שיש בקוד.

ציור

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

בסרגל 'שרטוט' אפשר לראות כמה זמן עובר עד להשלמת הפקודות ברשימת התצוגה, עבור כל התצוגות שצריך לעדכן במסך המסגרת הזו. זמן המדידה חל על כל קוד שמוסיפים לממשק המשתמש האובייקטים באפליקציה. דוגמאות לקוד כזה יכולות להיות onDraw(), dispatchDraw(), והdraw ()methods השייכים למחלקות המשנה של כיתה אחת (Drawable).

כשפלח גדול

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

סנכרון/העלאה

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

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

הערה: במכשירי Lollipop, השלב הזה סגול.

כשפלח גדול

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

כדי לכווץ את הסרגל אפשר להשתמש בטכניקות כמו:

  • מוודאים שהרזולוציות של מפת הסיביות לא גדולות בהרבה מהגודל שבו הן תוצג. לדוגמה, האפליקציה לא אמורה להציג מסך בגודל 1,024x1,024 כתמונה בגודל 48x48.
  • ניצול היתרונות של prepareToDraw() כדי להעלות באופן אסינכרוני מפת סיביות לפני שלב הסנכרון הבא.

בעיות בפקודות

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

כדי שהמערכת תצייר רשימות תצוגה למסך, היא תשלח את את הפקודות הנחוצות ל-GPU. בדרך כלל הוא מבצע את הפעולה הזו באמצעות OpenGL ES.

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

כשפלח גדול

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

Kotlin

for (i in 0 until 1000) {
    canvas.drawPoint()
}

Java

for (int i = 0; i < 1000; i++) {
    canvas.drawPoint()
}

הנפקה הרבה יותר יקרה מאשר:

Kotlin

canvas.drawPoints(thousandPointArray)

Java

canvas.drawPoints(thousandPointArray);

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

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

מאגרי נתונים זמניים של תהליכים/החלפה

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

כשפלח גדול

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

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

המפתח לפתרון הבעיה הזו הוא הפחתת המורכבות של העבודה שמתרחשת ב-GPU, בדומה למה שהייתם עושים ב-'Issue Commands'. שלב אחד.

שונות

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

כשפלח גדול

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