GTA Online. Famoso per i suoi tempi di caricamento lenti. Avendo ripreso il gioco per finire alcune delle rapine più recenti, il dev. T0ST è rimasto scioccato nello scoprire che si carica ancora lentamente come il giorno in cui è stato rilasciato .
Questa scioccante verità lo ha spinto a scoprire il perchè:
Per prima cosa voleva verificare se qualcuno avesse già provato a risolvere questo problema. La maggior parte dei risultati che ha trovato indicavano aneddoti su come il gioco fosse così sofisticato da dover essere caricato così lentamente, storie su come l'architettura di rete p2p sia pessima, alcuni modi elaborati di caricamento nella modalità storia... Qualche lettura in più gli ha dato modo di scoprire che avrebbe potuto risparmiare almeno 10-30 secondi di caricamento!
Nel frattempo un sondaggio ha tirato le righe sui malcontenti dovuti ai tempi di caricamento di GTA online.
Cercando di capire chi è il fortunato ~ 20% che ottiene tempi di caricamento inferiori a 3 minuti, si è imbattuto in alcuni benchmark con ... Sembra dipendere dall'hardware, ma qui qualcosa non torna ... Armato di strumenti così potenti come il Task Manager, ha iniziato a indagare su quali risorse potrebbero essere le cause del collo di bottiglia.
Dopo aver impiegato per caricare le risorse comuni utilizzate per le e , GTA decide di massimizzare sulla mia macchina e non fare nient'altro.
- Uso del disco?
- Utilizzo della rete? , ma fondamentalmente scende a zero dopo pochi secondi (a parte il caricamento dei banner informativi in rotazione).
- Utilizzo della GPU? .
- Utilizzo della memoria? Completamente ...
A questo punto il dev. sente odore di codice, codice davvero pessimo. La cosa strana è che il caricamento di GTA online utilizza solo la CPU. Come minimo ci sarebbe da aspettarsi grandi quantità di letture del disco che caricano risorse o carichi di richieste di rete che cercano di negoziare una sessione nella rete p2p. Ma questo? Questo è probabilmente un bug.
I sono un ottimo modo per trovare i colli di bottiglia della CPU. C'è solo un problema: la maggior parte di loro fa affidamento sulla strumentazione del codice sorgente per ottenere un'immagine perfetta di ciò che sta accadendo nei processi. Normalmente il tool (non aggiornato da 10 anni) raggrupperebbe le stesse funzioni insieme, ma poiché il dev. non ha simboli di debug, ha dovuto guardare gli indirizzi vicini per indovinare e cosa ha trovato? Non un collo di bottiglia !
Via con il disassemblatore. Il codice iniziale non sembra affatto giusto. La maggior parte dei giochi di alto profilo è dotata di protezione integrata contro il reverse engineering per tenere lontani pirati, imbroglioni e modder. Non che li abbia mai fermati. In questo caso, sembra esserci una sorta di offuscamento / crittografia in gioco che ha sostituito la maggior parte delle .
Le istruzioni devono essere prima di essere eseguite in un modo o nell'altro. Lo smontaggio della copia di memoria ora meno offuscata rivela che uno degli indirizzi ha un'etichetta estratta! È ? Scendendo nello stack di chiamate, quello successivo è etichettato e dopo che le etichette finiscono, c'è .
Sta analizzando qualcosa: ma cosa? Districare lo smontaggio avrebbe richiesto un'eternità, quindi il dev. ha deciso di scaricare alcuni campioni dal processo in esecuzione usando . Dopo alcuni passaggi di debug si scopre che è ... ! Stanno analizzando . Un enorme valore di con circa .
...,
{
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]
},
...
Che cos'è? Secondo alcune referenze, sembra trattarsi di dati per un “catalogo del negozio”. Si presume che contenga un elenco di tutti i possibili oggetti e aggiornamenti che puoi acquistare in GTA Online, con denaro di gioco, non con le microtransazioni. ? Non è niente! E l'utilizzo di sscanf potrebbe non essere ottimale, ma sicuramente non è così male?
Si scopre che il secondo colpevole viene chiamato proprio accanto al primo. Entrambi sono persino chiamati nella stessa istruzione come si vede in questa brutta decompilazione:
Il secondo problema? Subito dopo aver analizzato un elemento, viene (o in un elenco C ++ inline? non si capisce). Ogni voce ha un aspetto simile a questo:
struct {
uint64_t *hash;
item_t *item;
} entry;
Prima che venga archiviato controlla l'intero array, , confrontando l'hash dell'elemento per vedere se è nell'elenco o meno. La maggior parte di loro inutili. Ci sono hash unici, L'elemento è vuoto prima di caricare il JSON. E tutti gli elementi nel JSON sono unici!
Il piano del dev: scrivere una dll inserirla in GTA e agganciarla ad alcune funzioni. Fine.
Il problema JSON è complicato, non può essere sostituito il loro parser. Sostituire sscanf con uno che non dipende da strlen sarebbe più realistico. Ma c'è un modo ancora più semplice.
- hook strlen
- aspetta una lunga stringa
- Cache l'inizio e la lunghezza di esso
- se viene chiamato di nuovo all'interno dell'intervallo della stringa, restituisci il valore memorizzato nella cache
E per quanto riguarda il problema dell', è più semplice: salta completamente i controlli duplicati e inserisci gli elementi direttamente poiché sappiamo che i valori sono . il risultato:
Tempo di caricamento della modalità online originale: ~
Tempo con la sola patch di controllo della duplicazione:
Tempo con la sola patch del parser JSON:
Tempo con entrambi i problemi risolti:
miglioramento del tempo di caricamento del (bello!)
Qui, il poc di prova scritto dal dev.
Molto probabilmente, questo non risolverà i tempi di caricamento : potrebbero esserci altri colli di bottiglia su sistemi diversi, ma è un buco così grande che non si comprende il motivo per cui R * l'abbia mancato in tutti questi anni.
- C'è un collo di bottiglia della CPU a thread singolo durante l'avvio di GTA Online
- Si scopre che GTA fatica ad analizzare un file JSON da 10 MB
- Il parser JSON stesso è mal costruito / ingenuo
- Dopo l'analisi c'è una lenta routine di de-duplicazione degli elementi
Se questo in qualche modo raggiunge Rockstar: i problemi da un . La soluzione è anticipata dal dev.:
Fonte: T0ST da neel.lv
Tags
Leggi l'articolo su Gamelite.it
Articoli consigliati