קצב מסגרות

ממוצע פריימים לשנייה

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

ערכי FPS‏ P90 ו-P99 ליציבות

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

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

מדדים

  • Average FPS (baseline): המדד הבסיסי הזה מספק ערך בסיס כללי של ביצועי המשחק. זהו מדד סטנדרטי, אבל החישוב הממוצע לא מאפשר לזהות ירידות לסירוגין בקצב הפריימים וגמגום קל, ולכן הוא לא מספיק כדי לייצג את חוויית הצפייה של המשתמשים.
  • P90 FPS (קו בסיס עקבי באחוזון ה-10): הנתון הזה מציין ש-90% מהפריימים חרגו מקו הבסיס העקבי הזה, ורק 10% מהפריימים האיטיים ביותר לקחו יותר זמן לרינדור. אם קצב הפריימים ב-P90 גבוה וקרוב לממוצע, המשחק פועל בצורה טובה באופן עקבי ברוב המקרים במהלך הסשן.
  • P99 FPS (מדד לגמגום בפריימים במאון ה-99): המדד הזה מציין ש-99% מהפריימים חרגו מהמדד הזה לגמגום, ומבודד באופן ספציפי את 1% הפריימים האיטיים ביותר. המדד הזה חיוני לזיהוי של גמגומים קצרים, עיכובים בטעינת נכסים וקפיצות פתאומיות בעיבוד של נכסים כבדים שגורמות לשיבושים גלויים.

דוגמאות

השוואה בין ה-FPS הממוצע לבין מדדי P90 ו-P99 מאפשרת לאבחן במדויק את ההתנהגות הבסיסית של המשחק.

תרחיש 1: עקומת אופטימלית (משחק שעבר אופטימיזציה)

  • ממוצע: 60 FPS‏ (16.6 אלפיות השנייה)
  • P90: ‏ 58 FPS‏ (17.2 אלפיות השנייה)
  • P99: ‏ 52 FPS‏ (19.2 אלפיות השנייה)
  • ניתוח: המדדים קרובים מאוד זה לזה. המשחק מרגיש חלק ועקבי. אין גמגום קל, ואפילו 1% המסגרות הכי גרועות כמעט לא מורגשות לעין האנושית.

תרחיש 2: צוואר בקבוק בעומס (מוגבל על ידי CPU/GPU)

  • ממוצע: 45 FPS‏ (22.2 אלפיות השנייה)
  • P90: 40 FPS ‏ (25.0 ms)
  • P99: 38 FPS (26.3 ms)
  • ניתוח: קצב הפריימים הממוצע נמוך יותר, אבל באופן עקבי. ערך P99 לא יורד באופן משמעותי בהשוואה לממוצע. המשמעות היא שהמערכת מוצפת בהגדרות גרפיות או במגבלות רזולוציה. המשחק לא ייראה כאילו הוא מגמגם, אלא כאילו הוא פועל בצורה איטית. בדרך כלל, כשמורידים את הגדרות הגרפיקה, המדדים האלה גדלים באופן אחיד.

תרחיש 3: 60 פריימים לשנייה לא יציבים (הידור של Shader / סטרימינג של נכסים גמגום)

  • ממוצע: 60 FPS‏ (16.6 אלפיות השנייה)
  • P90: 45 FPS (22.2 ms)
  • P99: 15 FPS (66.6 ms)
  • ניתוח: זהו התרחיש הגרוע ביותר. למרות שקצב הפריימים הממוצע נראה מצוין, הערך P99 מצביע על בעיה קריטית. ‫P99 ב-66.6ms פירושו שהמשחק קופא לחלוטין למשך כמה פריימים בכל פעם. הערך הזה מצביע על חריגים משמעותיים – בדרך כלל בגלל צווארי בקבוק במעבד, עיכובים בהזרמת נכסים (למשל, זיכרון RAM או אחסון איטיים) או תקלות שנגרמות בגלל קומפילציה של Shader.

מדידה

כדי למדוד ביעילות את קצב הפריימים הממוצע, P90 ו-P99, אפשר להשתמש בפקודה dumpsys surfaceflinger timestats ב-Android. הכלי הזה מספק את קצב הפריימים הממוצע (FPS) והיסטוגרמת תזמון presentToPresentלכל השכבות שעוברות רינדור. הזמן של פריים presentToPresent הוא המרווח בין הפריים הנוכחי לבין הפריים הקודם שמוצג.

בהמשך מפורטות ההוראות לאיסוף ולחישוב של המדדים האלה במשחק שלכם:

  1. מתחילים ללכוד: מריצים את הפקודה הבאה עם הדגלים enable ו-clear כדי להתחיל ללכוד מידע:

    adb shell dumpsys SurfaceFlinger --timestats -clear -enable
    
  2. הצגת מידע: אחרי שמשחקים במשחק מספיק זמן, מריצים שוב את הפקודה עם הדגל dump כדי להציג את המידע:

    adb shell dumpsys SurfaceFlinger --timestats -dump
    
  3. סינון לפי שכבה: המידע שמועבר מספק נתונים לכל השכבות שמעובדות על ידי SurfaceFlinger. כדי למצוא את הקטע שמתאים למשחק שלכם, צריך לסנן לפי layerName (לדוגמה, layerName = SurfaceView[com.example.yourgame...]).

    layerName = SurfaceView[com.google.test/com.devrel.MainActivity]@0(BLAST)#132833
    
  4. זיהוי FPS ממוצע: המערכת מחשבת את ה-FPS הממוצע לכל שכבה באופן אוטומטי, והוא מוצג ישירות בפלט של ה-dump (לדוגמה, averageFPS = 30.179).

    ...
    averageFPS = 30.179
    ...
    
  5. חישוב FPS של P90 ו-P99: כדי למצוא את מדדי P90 ו-P99, צריך לנתח את totalFrames ואת ההיסטוגרמה של התזמון presentToPresent שמופיעה בקובץ ה-dump.

    totalFrames = 1000
    ...
    presentToPresent histogram is as below:
    0ms=0 1ms=0 2ms=0 3ms=0 4ms=0 5ms=0 6ms=0 7ms=0 8ms=0 9ms=0 10ms=0 11ms=0 12ms=0
    13ms=0 14ms=0 15ms=0 16ms=850 17ms=0 18ms=0 19ms=0 20ms=0 21ms=0 22ms=0 23ms=0
    24ms=0 25ms=0 26ms=0 27ms=0 28ms=0 29ms=0 30ms=0 31ms=0 32ms=0 33ms=100 34ms=0
    36ms=0 38ms=0 40ms=0 42ms=0 44ms=0 46ms=0 48ms=0 50ms=35 54ms=0 58ms=0 62ms=0
    66ms=10 70ms=0 74ms=0 78ms=0 82ms=0 86ms=0 90ms=0 94ms=0 98ms=0 102ms=5 106ms=0
    110ms=0 114ms=0 118ms=0 122ms=0 126ms=0 130ms=0 134ms=0 138ms=0 142ms=0 146ms=0
    150ms=0 200ms=0 250ms=0 300ms=0 350ms=0 400ms=0 450ms=0 500ms=0 550ms=0 600ms=0
    650ms=0 700ms=0 750ms=0 800ms=0 850ms=0 900ms=0 950ms=0 1000ms=0
    

    א. דוגמה להמחשה (טבלת התפלגות מצטברת) נניח שבמהלך סשן המשחק נרשם ערך של 1,000 ב-totalFrames. כדי למצוא את הערכים P90 ו-P99, מחשבים את ערכי הסף של אלפיות השנייה שבהם ספירת הפריימים המצטברת מגיעה ל-900 פריימים (90%) ול-990 פריימים (99%), בהתאמה, בספירה מהמשבצת הנמוכה ביותר של אלפיות השנייה.

    זמן פריים (אלפיות השנייה) מספר הפריים (היסטוגרמה) מספר הפריים המצטבר סטטוס / חישוב של אחוזון
    ‫16 אלפיות השנייה 850 850 ‫85.0%
    ‫33ms 100 950 ‫95.0%
    (הגעתם ליעד של 900 המרות ברמת סמך של 90%! ‫→ 1000/33 = 30.3 FPS)
    ‫50 אלפיות השנייה 35 985 98.5%
    66ms 10 995 ‫99.5%
    (היעד של P99 (990) הושג! ‫← 1000/66 = 15.1 FPS)
    ‫102 אלפיות השנייה 5 ‫1,000 100%

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

    # Define target thresholds based on total frame count
    p90_target = totalFrames * 0.90
    p99_target = totalFrames * 0.99
    
    cumulative_frames = 0
    p90_fps = None
    p99_fps = None
    
    # Iterate through the parsed SurfaceFlinger histogram data (sorted by millisecond)
    for ms_bucket, frame_count in present_to_present_histogram:
        cumulative_frames += frame_count
    
        # Capture P90 when cumulative frames cross the 90% threshold
        if p90_fps is None and cumulative_frames >= p90_target:
            p90_fps = 1000 / ms_bucket
    
        # Capture P99 when cumulative frames cross the 99% threshold
        if p99_fps is None and cumulative_frames >= p99_target:
            p99_fps = 1000 / ms_bucket
            break # Optimization: stop iterating once both targets are found
    
  6. הפסקת התיעוד: אחרי איסוף כל המידע הנדרש, צריך להשבית את timestats באמצעות הדגל disable:

    adb shell dumpsys SurfaceFlinger --timestats -disable
    

סשנים איטיים

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

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

סיכום

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

מקורות מידע נוספים

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

  • תפקוד האפליקציה ל-Android: סשנים איטיים: הסבר על האופן שבו Google Play מודד ומדווח על תקופות ממושכות של רינדור איטי, שמשפיע ישירות על חוויית המשתמש. 'סשן איטי' מוגדר כסשן משתמש שבו יותר מ-25% מהפריימים איטיים (לדוגמה, עיבוד התמונה נמשך יותר מ-50 אלפיות השנייה, ששווה ל-20 FPS).
  • Android Developers: Optimize Game Performance: מידע על המרכז לאופטימיזציה של משחקים ל-Android. המדריך המקיף הזה כולל שיטות מומלצות וכלי פרופיל (כמו Android Performance Analyzer‏(APA) ו-Perfetto) שיעזרו לכם למקסם את הביצועים הכוללים של המשחק.