Micro-ottimizzazione - BAD vs Game Development


12

Nello sviluppo del gioco c'è molto C / C ++, nelle applicazioni aziendali C #. Ho visto gli sviluppatori C / C ++ esprimere preoccupazione per il modo in cui una singola riga di codice si traduce in assembly. In .NET alcuni vanno in IL, raramente.

In C #, la "microottimizzazione" è disapprovata, rara e solitamente una perdita di tempo. Questo non sembra essere il caso dello sviluppo del gioco.

Cosa crea specificamente questa incoerenza? I giochi spingono costantemente i limiti dell'hardware? In caso affermativo, poiché l'hardware migliora, dovremmo aspettarci che linguaggi di livello superiore prendano il controllo dell'industria del gioco?

Non sto cercando un dibattito sulla fattibilità di C # come sviluppatore di giochi. So che è stato fatto in una certa misura. Focus sulla micro-ottimizzazione. In particolare, la differenza tra Game Dev vs Applications dev.

AGGIORNAMENTO
Per gioco intendo uno sviluppo moderno e su larga scala. Ad esempio MMORPG, Xbox, PS3, Wii ...


3
Ho lavorato come sviluppatore di giochi e sviluppatore di applicazioni e le differenze sono discutibili. La micro ottimizzazione senza profilazione è disapprovata in entrambi. Molti giochi non hanno requisiti molto potenti e non richiedono alcuna ottimizzazione. Alcune applicazioni aziendali richiedono requisiti molto più rigorosi (ad es. Uptime e garanzie in tempo reale) rispetto a un gioco medio a 60Hz.
Dave Hillier,

1
Un fattore aggiuntivo è che nelle applicazioni aziendali, di solito è possibile scegliere l'hardware (entro limiti ragionevoli). Se ho bisogno di più potenza di elaborazione, posso semplicemente acquistare un altro server o pagare più tempo su AWS. Nei giochi che richiedono l'hardware più recente trasforma un gioco da $ 60 in un gioco da $ 1.060 e una scheda video. Se stai sviluppando per le console, l'aggiornamento dell'hardware potrebbe comportare un ritardo di anni in attesa della prossima generazione. Quando non è possibile ottenere hardware migliore, è necessario utilizzarlo meglio.
Andrew

Risposte:


17

Nelle applicazioni aziendali, la CPU non è sempre il collo di bottiglia. Un'applicazione aziendale passerebbe la maggior parte del tempo ad aspettare. Per esempio:

  1. in attesa di risultati dalla query del database
  2. in attesa della fine della richiesta Web
  3. in attesa che l'utente esegua un'azione dell'interfaccia utente

Ecco perché il codice che ottimizza le prestazioni di elaborazione non aggiunge troppo valore.

La considerazione principale è:

  1. Time to market
  2. Semplicità, qualcun altro può capire e mantenere il codice

6
Vorrei sottolineare che il codice che ottimizza le query del database può migliorare notevolmente l'usabilità delle applicazioni aziendali.
HLGEM

4
+1. L'ottimizzazione del database e della rete di solito darebbe più soldi per le applicazioni aziendali. Ad esempio, la scelta di JSON vs XML e l'ottimizzazione degli indici DB
Shamit Verma

2
+1 ma dovresti aggiungere l'altro lato dell'equazione: i "loop principali" e rendering (s) nei giochi su strega su cui si basa la fluidità del gioco fanno perdere ad ogni microsecondo una perdita di valore, perché la qualità è percepibile agli occhi e altri sensi.
Klaim

1
Ben detto. E in effetti, dopo aver svolto applicazioni aziendali e sviluppo di giochi, ho trascorso del tempo a studiare una complessa query SQL cercando di ottenere qualche prestazione in più, più o meno come ho passato il tempo a esaminare un ciclo interno in un gioco.
Carson63000,

Tutto ritorna all'ottimizzazione prematura è la radice di tutto il male . La profilatura rivela chiaramente che la maggior parte del tempo impiegato nell'applicazione aziendale media è di rete + I / O database.
Alex Reinking,

13

Nelle applicazioni aziendali, è molto raro che i microsecondi contino. Nei giochi, è un dato di fatto.

Se vuoi avere un gioco in esecuzione a 60 fotogrammi al secondo, hai ~ 16.67 millisecondi per fare tutto ciò che deve essere fatto per quel fotogramma: input, fisica, logica di gioco, audio, rete, AI, rendering e così via; se sei fortunato, correrai a 30 fps e avrai 33.3 millisecondi di lusso. Se un frame impiega troppo tempo, le tue recensioni ne risentiranno, i tuoi giocatori riempiranno di bile i forum di Internet e non venderai quanto potresti (per non parlare del colpo al tuo orgoglio professionale) e se sei davvero sfortunato, troverai il tuo team che codifica le applicazioni aziendali per vivere.

Ovviamente, gli sviluppatori di giochi non si preoccupano di ogni singola riga poiché, con esperienza e un profiler decente, impari quali linee devono preoccuparsi. D'altra parte, quelle preoccupazioni a volte toccheranno cose che nel mondo degli affari sarebbero probabilmente considerate nano-ottimizzazioni piuttosto che micro-ottimizzazioni.

Non aspettatevi che un linguaggio di alto livello espellesse il C ++ fino a quando non offrirete prestazioni comparabili e prevedibili.


8
Nelle applicazioni di trading ad alta frequenza, i microsecondi contano molto!
quant_dev,

2
@quant: come con la maggior parte delle applicazioni di elaborazione del flusso - robotica, reti elettriche, missilistica, tecnologia medica, ecc. Crea un numero eccessivo di arretrati e potrebbe essere troppo tardi al momento del recupero.
Aaronaught

@quant_dev: le applicazioni di trading ad alta frequenza sono molto rare.
molbdnilo,

Non più. Sono più rari delle applicazioni di contabilità, ma più comuni dei software di progettazione di aeroplani.
quant_dev,

I microsecondi contano anche nelle app aziendali, il collo di bottiglia si trova di solito altrove (attraverso la rete, in un database o in un file system).
RubberDuck,

9

Ok, quindi hai visto gli sviluppatori C e C ++ ossessionati dalle singole linee. Scommetto che non sono ossessionati da ogni linea.

Ci sono casi in cui desideri le massime prestazioni e questo include molti giochi. I giochi hanno sempre cercato di spingere i limiti delle prestazioni, al fine di avere un aspetto migliore rispetto alla concorrenza sullo stesso hardware. Ciò significa che si applicano tutte le solite tecniche di ottimizzazione. Inizia con algoritmi e strutture dati e passa da lì. Utilizzando un profiler, è possibile trovare dove viene impiegato più tempo e dove è possibile ottenere significativi guadagni dalla micro-ottimizzazione di alcune righe.

Questo non è perché le lingue costringono le persone a farlo, è che le persone scelgono le lingue in base a ciò che vogliono fare. Se vuoi estrarre l'ultimo bit di performance da un programma, non scriverai C # e non lo compilerai nel CLR e speri che il compilatore JIT (o qualunque cosa) faccia un buon lavoro, lo scrivi in ​​qualcosa in cui puoi controllare ampiamente Il risultato. Utilizzerai C o C ++ (e probabilmente un sottoinsieme limitato di C ++) e studierai l'output del linguaggio assembly e i risultati del profiler.

Ci sono molte persone che usano C e C ++ e non si preoccupano troppo dei dettagli della traduzione, purché sembri essere abbastanza veloce.


7

I giochi spingono costantemente i limiti dell'hardware?

Si lo fanno.

In caso affermativo, poiché l'hardware migliora, dovremmo aspettarci che linguaggi di livello superiore prendano il controllo dell'industria del gioco?

Non proprio perché, poiché l'hardware migliora, i consumatori si aspettano che anche i giochi migliorino. Non si aspettano di vedere la stessa qualità del gioco sviluppata in modo più efficiente perché gli sviluppatori hanno usato un linguaggio di livello superiore. Si aspettano che le loro calze vengano spazzate via da ogni nuova piattaforma.

Certo, c'è qualche movimento. Quando ero un ragazzo e per la prima volta ero interessato allo sviluppo del gioco, era un'assemblea scritta a mano, o tirava fuori il diavolo. Questa era l'era del Commodore 64. Oggi, ovviamente, C ++ è la lingua franca della maggior parte dello sviluppo di giochi. E in effetti, abbiamo anche visto il movimento verso l'uso del C ++ per il codice motore e un linguaggio di scripting di livello superiore per il codice della logica di gioco. ad esempio LUA o il motore Unreal ha il suo linguaggio UnrealScript.


1
+1 una buona parte degli sviluppatori di giochi in questi giorni usa uno strato di motore iper-ottimizzato scritto da qualcun altro, quindi usa qualcosa come Python o C ++ meno meticoloso per mettere insieme le cose.
Morgan Herlocker,

Rilevante notare che Unreal ha ora spostato i suoi script "all'indietro", da UnrealScript a C ++. È una cosa grandiosa del C ++ moderno che ti permetta di scrivere sia codice a bassa latenza micro-ottimizzato, sia logica concisa di alto livello. La maggior parte delle altre lingue raggiunge livelli elevati solo sacrificando la latenza e spesso anche le prestazioni.
circa il

7

In C #, la "microottimizzazione" è disapprovata, rara e solitamente una perdita di tempo. Questo non sembra essere il caso dello sviluppo del gioco.

Se riesci a assemblare la tua applicazione con un codice di alto livello e un codice di libreria, sicuramente è una perdita di tempo. Scrivilo in una lingua interpretata se vuoi in quel caso; non farà molta differenza. Se stai cercando di implementare un motore di illuminazione globale all'avanguardia che voxelizza al volo i contenuti dinamici della scena in tempo reale come ha fatto CryEngine 3 , non puoi naturalmente scappare dalla necessità di microottimizzare.


0

"Gioco" è un termine piuttosto completo. Se avessi, per esempio, un MMORPG, piccole ottimizzazioni avrebbero effetto su molti giocatori.

I giocatori sono, e probabilmente sono sempre stati, abituati a una quantità relativamente grande di cose che accadono contemporaneamente, in tempo reale. Sicuro; un tempo, l'obiettivo era avere un reattivo Pacman o Tetris. Ma dovevano ancora essere reattivi. Al giorno d'oggi, 3DMMORPG su connessioni di rete a caduta di pacchetti.

Sono sicuro di voler ottimizzare.



0

Ho sempre trovato il termine "micro-ottimizzazione", piuttosto ambiguo. Se alcune modifiche a livello di istruzione al layout della memoria e ai modelli di accesso rendono qualcosa 80 volte più veloce da un professionista disciplinato che misura i loro hotspot senza ridurre la complessità algoritmica, è una "micro-ottimizzazione"? Per me questa è una "mega-ottimizzazione" per rendere qualcosa 80 volte più veloce su un caso d'uso reale. Le persone tendono a parlare di queste cose come tali ottimizzazioni hanno effetti microscopici.

Non lavoro più in Gamedev ma lavoro in VFX in aree come il tracciamento dei percorsi e ho visto molte implementazioni di BVH e alberi KD là fuori che elaborano ~ 0,5 milioni di raggi al secondo su una scena complessa (e questo è con valutazione multithread). In parole povere, tendo a vedere un'implementazione diretta di un BVH in un contesto di raytracing a meno di 1 milione di raggi / sec anche con una valutazione multithread. Tranne Embree ha un BVH in grado di elaborare oltre 100 milioni di raggi sulla stessa scena con lo stesso hardware.

Ciò è interamente dovuto alle "microottimizzazioni" secondo cui Embree è 200 volte più veloce (stesso algoritmo e struttura dati), ma ovviamente il motivo per cui è molto più veloce è perché gli sviluppatori di Intel sono professionisti che si affidano ai loro profilatori e misurazioni e sintonizzato davvero le aree che contavano. Non stavano cambiando il codice, volenti o nolenti, per intuizioni e per apportare modifiche che apportavano miglioramenti dello 0,000000001% a scapito della degradabilità significativa della manutenibilità. Si trattava di ottimizzazioni molto precise applicate in mani giudiziose: avrebbero potuto essere microscopiche in termini di messa a fuoco ma macroscopiche in termini di effetto.

Naturalmente con i requisiti di frequenza dei fotogrammi in tempo reale dei giochi, a seconda del livello elevato o basso con cui stai lavorando con il motore di gioco (anche i giochi realizzati con UE 4 sono spesso implementati almeno parzialmente in script di alto livello, ma non, diciamo, le parti più critiche del motore fisico), le microottimizzazioni diventano un requisito pratico in alcune aree.

Un'altra area di base che ci circonda quotidianamente è l'elaborazione delle immagini, come la sfocatura delle immagini ad alta risoluzione in tempo reale e forse fare altri effetti su di esse come parte di una transizione che probabilmente abbiamo visto da qualche parte, forse anche un effetto OS. Non è possibile implementare necessariamente tali operazioni di immagine da zero ciclicamente attraverso tutti i pixel di un'immagine e aspettarsi tali risultati in tempo reale a frame rate corrispondenti. Se è la CPU di solito guardiamo al SIMD e qualche micro-tuning, o stiamo guardando gli shader GPU che tendono a richiedere un tipo di mentalità a livello micro per scrivere in modo efficace.

In caso affermativo, poiché l'hardware migliora, dovremmo aspettarci che linguaggi di livello superiore prendano il controllo dell'industria del gioco?

Dubito piuttosto che i soli progressi dell'hardware potrebbero farlo, perché man mano che l'hardware avanza, anche le istruzioni e la tecnologia (es: fisica su GPU), le tecniche e le aspettative dei clienti per ciò che vogliono vedere e la concorrenza, in modi in cui spesso gli sviluppatori passano di nuovo a basso livello, come anche nel caso degli sviluppatori Web che ora scrivono shader GLSL di basso livello in WebGL (lo sviluppo web di questo tipo particolare è probabilmente anche di livello inferiore rispetto a un decennio o due fa, dato che GLSL è un linguaggio di livello C di livello estremamente basso, e non avrei mai immaginato un decennio o due fa che alcuni sviluppatori web avrebbero accettato di scrivere shader di GPU di basso livello).

Se ci sarà un modo in cui le aree critiche per le prestazioni passeranno a linguaggi di livello superiore, dovrà provenire maggiormente dal software, dai compilatori e dagli strumenti di cui disponiamo a mio avviso. Il problema per me in un futuro prevedibile non è che l'hardware non sia abbastanza potente. Ha più a che fare con il modo in cui non riusciamo a trovare il modo di parlarci nel modo più efficace ogni volta che cambia e avanza senza tornare di nuovo nella sua lingua. È in realtà il rapido ritmo con cui l'hardware cambia che rende la programmazione di alto livello piuttosto sfuggente per queste aree come la vedo io, poiché se ipoteticamente il nostro hardware ha smesso di avanzare all'improvviso per i decenni successivi,

Stranamente in questi giorni, quando lavoro in aree critiche per le prestazioni, devo pensare in qualche modo a un livello più basso di quello che ho iniziato (anche se ho iniziato nell'era Borland Turbo C DOS). Perché allora la cache della CPU era quasi inesistente. Per lo più era solo DRAM e registri, il che significava che potevo concentrarmi maggiormente sulla complessità algoritmica e scrivere strutture collegate come alberi in un modo molto semplice senza avere un grande impatto sulle prestazioni. In questi giorni i dettagli di basso livello della cache della CPU dominano il mio pensiero quasi quanto l'algoritmo stesso. E allo stesso modo abbiamo macchine multi-core che devono farci pensare al multithreading e agli atomici e ai mutex e alla sicurezza dei thread e alle strutture di dati simultanee e così via, che direi che è, sotto molti aspetti, un focus di livello molto più basso (come in, non così umanamente intuitivo) rispetto a quando ho iniziato.

Stranamente mi sembra molto vero ora. Penso di essere più influenzato dalle complessità e dai dettagli di base e di basso livello dell'hardware oggi rispetto a 30 anni fa, facendo del mio meglio per togliermi gli occhiali nostalgia. Ovviamente potremmo aver parlato un po 'di assemblaggio qui e abbiamo dovuto affrontare alcuni dettagli cruenti come XMS / EMS. Ma per la maggior parte direi che c'era meno complessità e consapevolezza dell'hardware e del compilatore di cui avevo bisogno allora rispetto a oggi quando lavoro in aree critiche per le prestazioni. E questo sembra quasi vero per l'intero settore se mettiamo da parte come la scritturaif/else dichiarazioni in un modo leggermente più umanamente leggibile e considera quante persone in generale in questi giorni stanno pensando di più ai dettagli di livello inferiore dell'hardware (da più core alle GPU al SIMD alla cache della CPU e ai dettagli interni di come i loro compilatori / interpreti / le biblioteche funzionano e così via).

Alto livello! = Meno efficiente

Tornando a questa domanda:

In caso affermativo, poiché l'hardware migliora, dovremmo aspettarci che linguaggi di livello superiore prendano il controllo dell'industria del gioco?

Per me non si tratta di hardware. Si tratta di ottimizzatori e strumenti. Quando ho iniziato, le persone praticamente scrivevano tutti i giochi per console in assembly, e c'era un vero vantaggio in termini di prestazioni, soprattutto in considerazione della mancanza di compilatori di qualità che generavano 6502.

Quando l'ottimizzazione dei compilatori C è diventata più intelligente nelle loro ottimizzazioni, hanno iniziato a raggiungere un punto in cui il codice di livello superiore scritto in C era in competizione e talvolta superava anche il codice scritto dai migliori esperti di assemblaggio in molte aree (anche se non sempre), e ciò ha reso quindi quindi un gioco da ragazzi adottare C almeno per la maggior parte della codifica per un gioco. E un cambiamento simile è avvenuto gradualmente a un certo punto con il C ++. L'adozione del C ++ è stata più lenta poiché ritengo che l'incremento della produttività nel passaggio dall'assemblaggio al C potrebbe probabilmente raggiungere un accordo unanime da parte di gamingevs che scrivono giochi non banali interamente in ASM invece di passare dal C al C ++.

Ma questi cambiamenti non derivavano dal fatto che l'hardware diventasse più potente tanto quanto gli ottimizzatori per questi linguaggi che rendevano il livello più basso (sebbene non sempre del tutto ci siano alcuni casi oscuri) obsoleto.

Se riesci a immaginare uno scenario ipotetico in cui potremmo scrivere il codice nel codice di livello più alto immaginabile, senza preoccuparti di multithreading o GPU o mancati cache o qualcosa del genere (forse nemmeno strutture di dati specifici) e l'ottimizzatore era come un'intelligenza artificiale intelligente e potrebbe capire i layout di memoria più efficienti riorganizzando e compattando i nostri dati, scoprendo che potrebbe usare qualche GPU qua e là, parallelizzare un po 'di codice qua e là, usare qualche SIMD, magari profilare se stesso e continuare a ottimizzare ulteriormente il suo IR come noi umani rispondendo agli hotspot del profiler, e lo ha fatto in un modo che batte i migliori esperti del mondo, quindi sarebbe un gioco da ragazzi anche per coloro che lavorano nei settori più critici per le prestazioni adottarlo ... e questo è un progresso proveniente da ottimizzatori ridicolmente intelligenti, non hardware più veloce.


0

In C #, la "microottimizzazione" è disapprovata, rara e solitamente una perdita di tempo. Questo non sembra essere il caso dello sviluppo del gioco.

Hai un problema di terminologia qui. Stai usando le parole correttamente, ma gli sviluppatori di giochi e gli uomini d'affari usano lo stesso termine in due modi molto diversi.

Per le imprese, "micro ottimizzazione" significa accelerare un passo molto piccolo nel processo aziendale globale implementato dal software. Il motivo per cui è disapprovato è in genere uno di:

  1. Soldi extra spesi per offrire lo stesso valore commerciale, a una velocità più rapida di pochi secondi. Il denaro risparmiato nei miglioramenti della velocità proviene da un diverso pool di denaro (il tempo dell'utente), quindi l'azienda generalmente non beneficia dello sforzo che spende, il cliente lo fa a spese dell'azienda.
  2. In genere i programmatori aziendali hanno una cattiva visibilità nel processo aziendale globale, quindi un'ottimizzazione di un singolo passaggio potrebbe non offrire buoni benefici al processo complessivo. Ad esempio, se si rende il 3% del processo 10 volte più veloce, è stato accelerato l'intero processo del 2,7%.
  3. In genere il business ha un ampio elenco di lavori rimanenti che hanno un certo valore aziendale e darebbe la priorità all'aggiunta di quel valore invece di fornire lo stesso valore in un tempo (probabilmente) inferiore.

Lo sviluppo del gioco è una bestia diversa. La "microottimizzazione" sta risparmiando una piccola quantità di tempo in una funzione o routine.

  1. I sistemi di gioco tendono ad essere mantenuti nel ciclo di rendering. Attualmente lo standard aureo è di 60 fotogrammi al secondo, quindi tutto ciò che verrà calcolato deve essere eseguito e reso sullo schermo in 1/60 di secondo.
  2. Ciò significa che spesso le stesse routine vengono chiamate da migliaia a centinaia di migliaia di volte nel corso di un gioco. Pertanto, un miglioramento di 10 volte in una singola funzione è amplificato in termini di valore dal numero di volte in cui si avvertiranno i benefici del miglioramento.
  3. Il mancato raggiungimento della velocità di rendering ha un impatto sulla presentazione del gioco. Il video diventerà instabile, i personaggi si animeranno con salti e salti anziché movimenti fluidi. Questo porta immediatamente il giocatore fuori dall'immersione del gioco e nel regno di mettere in discussione il valore del gioco.

Quindi, negli affari, a nessuno importa se la forma di un processo aziendale in 4 fasi si presenta in 0,6 secondi o 0,5 secondi. Durante il gioco, ci si preoccupa se una routine che impiega 200 ms può essere ridotta all'esecuzione in 100 ms.

Riguarda il valore fornito al cliente, le esigenze del cliente e il rapporto costi-benefici della modifica.


-1

Ha a che fare con il motivo per cui quello strumento è stato selezionato per un determinato lavoro.

I golfisti ossessioneranno la direzione e la forza che applicano con un putter, non tanto quando usano il guidatore.

Perché? Perché sono diversi tipi di colpi. Per un disco, vuoi farlo nel fairway alla massima distanza. Per un putt, vuoi metterlo esattamente nel buco.

Lo stesso vale qui. Gli sviluppatori di giochi scelgono C ++ perché offre loro il controllo sulle prestazioni di diverse operazioni. Se lo hai scelto, vorrai sfruttarlo.


-3

La maggior parte delle applicazioni aziendali sono scritte come strumenti interni. Le aspettative sull'usabilità di questi strumenti sono molto inferiori rispetto al software venduto ai clienti di massa. È abbastanza comune che un'app aziendale interna abbia menu e finestre di dialogo che reagiscono lentamente ai clic del mouse, finestre che vengono ridisegnate con ritardo o persino una GUI scritta in Swing (l'orrore!). Questo per una serie di motivi (è più importante che il software sia personalizzabile piuttosto che molto "scattante", gli utenti del software non hanno scelta se utilizzare o meno il software in questione, le persone che realizzano il decisione di installare il software non utilizzarlo da soli ...). La conseguenza di tutto ciò è che gli sviluppatori di questi strumenti non impiegano molto tempo a ottimizzare la reattività dell'applicazione, ma ci teniamo molto all'estensibilità e al numero di funzionalità. Base clienti diversa => obiettivi di progettazione diversi => metodologia diversa.

Si noti che un'applicazione aziendale destinata a un pubblico di massa, come Excel, è fortemente ottimizzata.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.