ידע בתכנות עזר לשחקן להוריד משמעותית את זמן הטעינה של משחק האונליין הפופולרי. כל הפרטים כאן בכתבה!
מכירים את זה שאתם טוענים משחק בן 7 שנים על מחשב חדש ועדיין לוקח לו כ-6 דקות לעלות, אתם מגרדים בראש ולא מבינים איך? אז t0st, גיימר שהוא במקרה גם מתכנת, גם חשב כמוכם. הוא לא הבין למה לוקח ל-GTA V יותר מ-6 דקות לטעון את GTA Online והוא החליט לבדוק את העניין. את מהלך האירועים הוא מפרט בבלוג שזהו הפוסט היחיד בו בפירוט רב ומקצועי. אני אנסה לפרט איך הוא עשה זאת בשפה פשוטה שגם לא-מתכנתים יבינו.
האם מישהו תיקן את זה קודם?
כל מתכנת מתחיל יודע שלא שווה לפתור בעיות לבד אם מישהו פתר אותן כבר קודם. לכן הוא התחיל בלחפש באינטרנט אם מישהו פתר את הבעיה. מה שהוא מצא זה המון תירוצים על כך שהמשחק מאוד מורכב ולכן הטעינה כלכך איטית, אחרים דיברו על ארכיטקטורת הרשת של המשחק (איך שהמשחק מתקשר עם אנשים אחרים, במקרה הזה p2p). חלק הורידו את זמן הטעינה ע״י מספר מודים וקפיצה על הסמל של *R בטעינה של המשחק. זה הוריד בין 10-30 שניות.
בדיקות ביצועים
לאחר הרצת מספר בדיקות על המחשב שלו כדי לבדוק את הבעיה. הוא השווה בין טעינה של מצב הסיפור לטעינה של מצב האונליין. טעינת מצב הסיפור לקחה רק דקה ועשר שניות (או 70 שניות) לעומת 6 דקות במצב האונליין.
האם זאת רק הבעיה שלי?
כדי לשלול את ההשערה שהבעיה היא במחשב שלו, t0st רצה לבדוק אם הוא היחיד שנתקל בבעיה. המעבד שבו t0st השתמש הוא לא מעבד חזק (מדובר במעבד AMD ישן, FX-8350) ולכן הוא פנה לקהילה לבדוק אם הבעיה היא רק אצלו. הוא מצא שמעל מ-80% מהקהילה מחכה בין 3 ל-6 דקות כדי שהמשחק יטען. 18.8% מחכים פחות מ-3 דקות ומעל שליש מהקהילה (35.1%) מחכים מעל ל-6 דקות! אז t0st הלך לבדוק מה קרה.
בדיקת פעילות החומרה
המשתמש הסתכל על הפעילות של החומרה ב-Task Manager. לאחר דקה של טעינת GTA Online והשוואה למצב הסיפור של המשחק נראה שבדקה הראשונה הם מתנהגים דומה. במצב האונליין, לאחר דקה אחת כל המשאבים הפסיקו לעבד (זיכרון, דיסק, אינטרנט, כרטיס מסך) וכל מה שנשאר זו עבודה על ליבה אחת (מתוך 8) של המעבד. את השלבים הבאים אתמצת יותר, כי הם מאוד טכניים.
מה הבעיה בפועל?
חברנו t0st הריץ תוכנת profiling (בדיקת כמות קריאות של התוכנה למעבד) וראה שיש שתי כתובות שהמעבד חוזר אליהן במעל 90% מהפעמים. בעזרת dissassmebler (תוכנה שמפרקת פעולה של תוכנה לפעולות assembly, שפת תכנות שמדברת ישירות עם המעבד) הוא שם לב שיש משהו שעובד כמו הצפנה. בפירוק נוסף הוא שם לב לבעיה: התוכנה מנסה לפרק קובץ JSON בגודל 10MB. קובץ JSON הוא קובץ המכיל מידע בפורמט מסוים של "מפתח" ו-"ערך". במצב שלנו זה נראה כך:
```
{ "key": "WP_WCT_TINT_21_t2_v9_n2", "price": 45000, "statName": "CHAR_KIT_FM_PURCHASE20", "storageType": "BITFIELD", "bitShift": 7, "bitSize": 1, "category": ["CATEGORY_WEAPON_MOD"] },
```
אפשר להבין מהקובץ שזה תיאור של החנות של רוקסטאר. אבל לעבד קובץ JSON, גדול ככל שיהיה, לא צריך לקחת כלכך הרבה זמן (יש בו כ-63 אלף רשומות). הבעיה היא שהצורה שבה רוקסטאר עיבדה את קובץ ה-JSON הוא מאוד לא יעיל והוא קורא לפונקציה בשם strlen (אורך המחרוזת) - פונקציה מאוד לא יעילה. אח״כ הקוד מנסה להכניס את הרשומה שקיבלת מאותו ה-JSON לרשימה כשגם בהכנסה לרשימה, הוא מחפש שאין ערך key זהה כבר ברשימה (שאפשר לראות בדוגמה למעלה). כלומר, כל פעם שאנחנו טוענים את הקובץ אנחנו עושים שתי פעולות לא יעילות מאוד:
- בודקים מה האורך של כל הרשומה עבור כל ערך בה
- מחפשים ברשימה שאין לנו כבר key שווה למה שקיבלנו
מה הבעיה פה? תחשבו שאתם צריכים לקרוא רשימה של משחקים:
[ { ״שם״: ״קאונטר סטרייק״}, { ״שם״: ״קול אוף דיוטי״} ]
עכשיו אתם צריכים להכניס את כל מה שכתוב ברשימה למעלה לרשימה חדשה. אבל כל פעם שאתם קוראים מילה, כמו ״שם״, אתם צריכים לקרוא את כל הרשימה מההתחלה עד הסוף ואז כשאתם רוצים להכניס את הרשומה לרשימה חדשה אתם צריכים לקרוא את כל הרשימה החדשה שהכנסתם. עכשיו תכפילו את זה ב-63 אלף רשומות כאלו. הבנתם? בשפה מקצועית, אנחנו מקבלים פה סיבוכיות של כמות (מילים ברשימה * כמות תווים * כמות אובייקטים ברשימה). או בקיצור - המון פעולות מיותרות.
הפתרון
מה שחברנו t0st עשה זה נטרל את פונקצית ה-strlen בעזרת שמירת התוצאה הקודמת (caching) והחזרת התוצאה הקודמת פחות השינוי שביקשה התוכנה. בשביל לפתור את בעית ההכנסה לרשימה הוא פשוט נטרל את המנגנון שמחפש אם יש ערך כפול - הרי רוקסטאר כבר שולחת רשימה שבה אין ערכים כפולים. למה לבדוק את זה שוב? והופה, עכשיו GTA Online נטען לו בדקה וחמישים שניות עם שני התיקונים.
כמה השינויים הם דרסטיים?
- זמן טעינה מקורי של מצב האונליין: 6 דקות
- אחרי שתיקן את בדיקת הכפילויות: 4 דקות ו-30 שניות
- אחרי שתיקן את הקריאות ל-strlen: הצליח להגיע ל-2 דקות ו-50 שניות
- אחרי שתיקן את שתי הבעיות: דקה ו-50 שניות.
או בקיצור: הגיע הזמן שברוקסטאר יתקנו את הבעיה במשחק שרץ מעל 7 שנים. אם משתמש פשוט שאין לו גישה לקוד המקור של המשחק יכול לעשות את זה - גם החברה שפיתחה אותו יכולה.
הנה הפוסט המקורי של t0st שוב למי שרוצה לקרוא אותו, ולמי שמעוניין להפעיל את הפתרון על המחשב שלו, הנה ה-git עם הפתרון של t0st. על אחריותכם בלבד כמובן! מה אתם חושבים על כל הסיפור הזה? נשמח לשמוע אתכם!
*רוצים לקבל את כל החדשות החמות ישר לנייד? הצטרפו לערוץ הטלגרם של Vgames!*
בר הוכמן - כתב תוכן
משחק על: PC, PS4, Xbox One
בחיים לא תנצחו אותי ב: קרב Roadhogs ב-Overwatch.
המשחק שהגדיר לי את הילדות: לא בטוח אם Oddworld או The Neverhood. בכל מקרה הילדות שלי הייתה מוזרה.
כשאני לא משחק אני: סטודנט למדעי המחשב בסבל וכדורסלן בחסד.
מסר לעולם: לא תמיד התפוח הכי אדום הוא בהכרח תפוח.
תגובות
1
13:24 02.03.2021 | Big Danny K
כמובן שאני הספקתי להכיר את רוקסטאר ואת חברת האם שלהם, הם לא יתקנו שום דבר ובטח ישלחו לו מכתב התראה לפני תביעה על זה שהעז לחטט ולתכנת את המשחק שלהם, את "הקניין הרוחני שלהם"
2
20:34 02.03.2021 | shlulu
כתבה מצוינת! תגובה ראשונה שלי בכלל באתר.
עוד תוכן כזה יהיה מעולה.
3
00:22 04.03.2021 | בר הוכמן - כתב תוכן
shululu - שמח לשמוע. באם אתקל בעוד מידע מעניין כזה, אשמח לכתוב!
4
| פורסם ע"י