הערכת ביצועים

השתמש ב-Simpleperf כדי להעריך את הביצועים של מכשיר. Simpleperf הוא כלי מקורי ליצירת פרופילים הן ליישומים והן לתהליכים מקוריים באנדרואיד. השתמש ב-CPU Profiler כדי לבדוק את השימוש ב-CPU באפליקציה ואת פעילות השרשור בזמן אמת.

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

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

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

כתוצאה מכך, במכשיר מהיר, צינור ה-UI הוא הדבר החשוב ביותר במערכת מלבד מה שנדרש כדי לשמור על צנרת ה-UI פונקציונלית. משמעות הדבר היא שצינור ממשק המשתמש צריך להקדים כל עבודה אחרת שאינה נחוצה עבור ממשק משתמש נוזלי. כדי לשמור על ממשק משתמש זול, סנכרון רקע, מסירת הודעות ועבודות דומות חייבות להתעכב אם ניתן להפעיל עבודה בממשק המשתמש. מקובל להחליף את הביצועים של פעולות ארוכות יותר (זמן ריצה של HDR+, הפעלת יישומים וכו') כדי לשמור על ממשק משתמש זורם.

קיבולת מול ריצוד

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

קיבולת

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

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

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

לְהִתְעַצְבֵּן

בעוד שקל לראות את הקיבולת הנדרשת לעומס עבודה, ריצוד הוא מושג מעורפל יותר. לקבלת מבוא טוב לריצוד כמכשול למערכות מהירות, עיין במקרה של ביצועי מחשב-על חסרים: השגת ביצועים אופטימליים ב-8,192 המעבדים של ASCl Q. (זהו חקירה של מדוע מחשב העל ASCI Q לא השיג את הביצועים הצפויים שלו ומהווה מבוא נהדר לאופטימיזציה של מערכות גדולות.)

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

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

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

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

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

צריכת זיכרון

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

ניתוח ביצועי המכשיר הראשוניים

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

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

  1. בצע אתחול של המערכת לממשק המשתמש כשכל מנהלי ההתקן פועלים וכמה הגדרות בסיסיות של מושל תדרים (אם תשנה את הגדרות מושל התדרים, חזור על כל השלבים למטה).
  2. ודא שהקרנל תומך בנקודת העקיבה sched_blocked_reason וכן נקודות עקיבה אחרות בצינור התצוגה שמציינות מתי המסגרת נמסרת לתצוגה.
  3. קח עקבות ארוכים של כל צינור ממשק המשתמש (מקבלת קלט דרך IRQ ועד לסריקה סופית) תוך הפעלת עומס עבודה קל משקל ועקבי (למשל, UiBench או מבחן הכדור ב- TouchLatency) .
  4. תקן את נפילות המסגרת שזוהו בעומס העבודה הקל והעקבי.
  5. חזור על שלבים 3-4 עד שתוכל לרוץ עם אפס פריימים שנפלו למשך 20+ שניות בכל פעם.
  6. עברו למקורות אחרים גלויים למשתמש של ג'אנק.

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

  • ודא לליבה שלך יש את תיקון נקודת המעקב sched_blocked_reason . נקודת עקיבה זו מופעלת עם קטגוריית מעקב מתזמן ב-systrace ומספקת את הפונקציה האחראית לשינה כאשר השרשור הזה נכנס לשינה בלתי ניתנת להפסקה. זה קריטי לניתוח ביצועים מכיוון ששינה ללא הפסקה היא אינדיקטור נפוץ מאוד של ריצוד.
  • ודא שיש לך מספיק מעקב עבור צינורות ה-GPU והתצוגה. ב-SOCs האחרונים של Qualcomm, נקודות עקיבה מופעלות באמצעות:
  • adb shell "echo 1 > /d/tracing/events/kgsl/enable"
    adb shell "echo 1 > /d/tracing/events/mdss/enable"
    

    אירועים אלה נשארים מופעלים כאשר אתה מפעיל את systrace כך שתוכל לראות מידע נוסף במעקב על צינור התצוגה (MDSS) בקטע mdss_fb0 . ב-Qualcomm SOCs, לא תראה שום מידע נוסף על ה-GPU בתצוגת systrace הרגילה, אבל התוצאות נמצאות ב-trace עצמו (לפרטים, ראה הבנת systrace ).

    מה שאתה רוצה מסוג זה של מעקב אחר תצוגה הוא אירוע בודד שמצביע ישירות על מסגרת שנמסרה לתצוגה. משם, אתה יכול לקבוע אם פגעת בזמן הפריימים שלך בהצלחה; אם אירוע X n מתרחש פחות מ-16.7ms לאחר אירוע X n-1 (בהנחה של תצוגת 60Hz), אז אתה יודע שלא עשית תקלות. אם ה-SOC שלך לא מספק אותות כאלה, עבוד עם הספק שלך כדי לקבל אותם. איתור באגים ריצוד קשה ביותר ללא אות סופי של השלמת מסגרת.

שימוש באמות מידה סינתטיות

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

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

שקול שני SOCs המריצים Benchmark X המציג 1000 פריימים של ממשק משתמש ומדווח על זמן העיבוד הכולל (ציון נמוך יותר טוב יותר).

  • SOC 1 מציג כל פריים של Benchmark X ב-10 אלפיות השנייה ומקבל ציונים של 10,000.
  • SOC 2 מציג 99% מהפריימים ב-1ms אבל 1% מהפריימים ב-100ms ומקבל ציונים של 19,900, ציון טוב יותר באופן דרמטי.

אם המדד מעיד על ביצועי ממשק משתמש ממשי, SOC 2 לא יהיה שמיש. בהנחה של קצב רענון של 60Hz, ל-SOC 2 תהיה מסגרת דחופה כל 1.5 שניות של פעולה. בינתיים, SOC 1 (ה-SOC האיטי יותר לפי Benchmark X) יהיה נזיל לחלוטין.

שימוש בדוחות באגים

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

שימוש ב-TouchLatency

מספר דוגמאות להתנהגות רעה מגיעות מ-TouchLatency, שהוא עומס העבודה התקופתי המועדף בשימוש עבור Pixel ו-Pixel XL. זה זמין frameworks/base/tests/TouchLatency ויש לו שני מצבים: חביון מגע וכדור מקפץ (כדי להחליף מצבים, לחץ על הכפתור בפינה השמאלית העליונה).

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

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

מכיוון שהריצוד הוא לעתים קרובות (אך לא תמיד) משתנה של מהירות שעון, השתמש בבדיקה שפועלת בשעונים נמוכים מאוד כדי לאבחן ריצוד מהסיבות הבאות:

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