sovraccarico calcolo in C # - Uso getter / setter vs modifica di array direttamente e colata velocità

StackOverflow https://stackoverflow.com/questions/3018536

Domanda

Stavo per scrivere un post prolisso, ma io bollire giù qui:

Sto cercando di emulare lo stile grafico della vecchia scuola del NES tramite XNA. Tuttavia, il mio FPS è lento, cercando di modificare 65K pixel per fotogramma. Se ho appena scorrere tutti 65K pixel e impostarle a qualche colore arbitrario, ho 64FPS. Il codice che ho fatto per guardare-up ciò che i colori devono essere posizionati dove, ottengo 1FPS.

Credo che sia a causa della mia codice oggetto-orented.

In questo momento, ho cose suddivisi in circa sei classi, con getter / setter. Sto indovinando che sto chiamando almeno 360K getter per fotogramma, che credo sia un sacco di spese generali. Ogni classe contiene o / e-o 1D o 2D array contenente elenchi personalizzati, int, colori, o Vector2D, byte.

Che cosa succede se ho combinato tutte le classi in un solo, e accessibile il contenuto di ciascun array direttamente? Il codice sarà un pasticcio, e fosso i concetti di object-oriented di codifica, ma la velocità potrebbe essere molto più veloce.

Sono, inoltre, non preoccupati per le violazioni di accesso, come tutti i tentativi di ottenere / impostare i dati nelle matrici saranno fatto in blocchi. Per esempio, tutta la scrittura per gli array avrà luogo prima che i dati si accede da loro.


Come per la fusione, ho affermato che sto usando enumerazioni personalizzati, int, colori, e Vector2D, byte. Quali tipi di dati sono più veloci da utilizzare e l'accesso in .NET Framework, XNA, XBox, C #? Penso che costante fusione potrebbe essere una causa di rallentamento qui.

Inoltre, invece di utilizzare la matematica per capire quali dati indici devono essere collocati in, ho usato precalcolate ricerca tavoli, quindi non è necessario utilizzare la moltiplicazione costante, addizione, sottrazione, divisione per frame. :)

È stato utile?

Soluzione

C'è una presentazione straordinaria dalla GDC 2008, che vale la pena leggere se siete uno sviluppatore di XNA. Si chiama Capire XNA Framework prestazioni .

Per la vostra attuale architettura - non hai realmente descritto abbastanza bene per dare una risposta definitiva - che probabilmente stanno facendo troppo inutili "roba" in un loop stretto. Se dovessi tirare a indovinare, mi piacerebbe suggerire che il metodo attuale è thrashing la cache -. È necessario correggere il layout dei dati

Nel caso ideale si dovrebbe avere una bella e grande varietà di piccole-come-possibile Tipi di valore (struct non classi), e un ciclo pesantemente inline che infila i dati in esso linearmente.

( A parte : riguardo a ciò che è veloce: Integer e floating point per la matematica è molto veloce - in generale, non si dovrebbe usare ricerca tabelle chiamate di funzione sono abbastanza veloce - al punto che la copia di grandi dimensioni. struct quando si passano loro sarà più significativo il JIT sarà inline getter e setter semplici -. anche se non si deve dipendere da esso per qualsiasi altra cosa in linea nei cicli molto stretti -. come il vostro blitter)

TUTTAVIA - anche se ottimizzato - la tua attuale architettura fa schifo. Quello che state facendo vola a fronte di come un moderno funziona GPU. Si dovrebbe essere il caricamento del sprite sulla vostra GPU e lasciandolo composita scena.

Se si desidera modificare i vostri sprites a livello di pixel (per esempio: scambio di pallet come lei ha detto), allora si dovrebbe utilizzare pixel shader. La CPU sui 360 (e su PC) è veloce, ma la GPU è molto più veloce quando si sta facendo qualcosa di simile!

Il href="http://creators.xna.com/en-us/sample/spriteeffects" rel="nofollow noreferrer"> campione XNA è un buon posto per iniziare.

Altri suggerimenti

Hai profilato il codice per determinare dove il rallentamento è? Prima di andare riscrivere l'applicazione, si dovrebbe almeno sapere quali parti devono essere riscritti.

ho il forte sospetto che il sovraccarico di funzioni di accesso e le conversioni di dati è banale. E 'molto più probabile che i vostri algoritmi stanno facendo un lavoro inutile, valori che potrebbero cache, e altre cose che possono essere affrontate senza far saltare in aria il vostro disegno oggetto ricalcolare.

Stai specificando un colore e come per ogni pixel o qualcosa del genere? Se questo è il caso credo che si dovrebbe davvero pensare l'architettura un po 'di più. Iniziare a utilizzare sprite che accelerare le cose.

Modifica

Va bene Penso che quello che la soluzione potrebbe essere di carico diversi sprite con colori diversi (uno sprite di pochi pixel) e riutilizzare quelli. È più veloce di scegliere lo stesso sprite di assegnare un colore diverso per ciascun pixel come sprite è già stato caricato in memoria

Come per qualsiasi problema di prestazioni, si dovrebbe profilo l'applicazione per identificare i colli di bottiglia piuttosto che cercare di indovinare. Dubito seriamente che getter e setter sono alla radice del problema. Il compilatore inline quasi sempre questo tipo di funzioni. Sono anche curioso di sapere cosa hai contro la matematica. Moltiplicando due numeri interi, per esempio, è una delle cose più veloci del computer può fare.

scroll top