In questa seconda parte del Sotto la Scocca voglio approfondire il ruolo della GPU e della memoria.
È facile dire “vogliamo più framerate, vogliamo più risoluzione, vogliamo più RAM, più teraflops” ma queste richieste come si legano all’hardware? Al passaggio dal 2D al 3D la richiesta di maggior potenza era abbastanza ovvia così come i benefici che apportava, ma una volta che il 3D si è stabilizzato, i cambiamenti sono diventati meno intuitivi. Direi di partire da come funziona una GPU a grandi linee.
Le schede grafiche sono tante, ma davvero tante. Ad ogni generazione AMD, Nvidia e tutti i progettisti di grafiche mobile fanno cambi alle proprie architetture per rendere più efficienti e per fargli fare trucchetti nuovi, cambiando anche radicalmente come operano ad un livello basso, come viaggia l’informazione al loro interno. Questa logica però è in generale gestita dai driver e dai transistor. Le operazioni che devono compiere concettualmente sono sempre le stesse. L’esatto ordine dipende da che procedure di programmazione (API) stiamo utilizzando, ma tutte hanno dei punti comuni. Abbiamo i processi suoi vertici, i processi sulla geometria, i processi sui pixel ed infine la generazione dell’output. Questi processi sono tutti gestiti da Shaders, cioè programmi che dicono come “ombreggiare” un’immagine. Il termine shader può anche essere usato per indicare i componenti hardware che eseguono i programmi shaders, ma dal contesto dovrebbe essere chiaro a quale dei farò riferimento. Questi dati vengono preparati dalla CPU e dati in pasto alla GPU.
La prima fase è quella del lavoro sui vertici. Un videogioco è un mondo tridimensionale che viene raffigurato su uno schermo bidimensionale, ma non c’è perdita di profondità, il mondo è in pieno 3D e noi possiamo muoverci al suo interno senza problemi. Questo perché i dati degli oggetti nel mondo hanno delle coordinate in uno spazio 3D, che devono essere trasformate per poterle fare stare nella giusta posizione rispetto al nostro punto di vista e questo porta con sé un sacco di informazioni e passaggi matematici. Con i vertex si fanno operazioni sulla posizione, sui colori, sulle texture, sul movimento e sull’illuminazione. In questa fase non si può generare nulla di nuovo in maniera dinamica, ma solo elaborare le informazioni che ci sono fornite così come sono.
Dopo questa prima fase si passa a quella della geometria, che sposta i calcoli dai vertici a triangoli. Questa fase è in grado di generare e distruggere elementi ed è la fase che di solito è usata per calcolare effetti dinamici e fatti al volo come le esplosioni, effetti particellar come quelli atmosferici e vengono generate informazioni per le ombre. Successivamente si passa alla fase conosciuta come rasterizzazione che trasforma i dati da vertici a pixel. Poi i Pixel Shaders fanno tutte le operazioni sui pixel rimanenti, applicando effetti e filtri come il motion blur. Poi questi dati vengono combinati e si ottiene l’immagine che finirà su schermo.
Per far capire un po’ come si pensa un hardware grafico, occorre fare un discorso un po’ più generale. Esistono due grandi realtà che si intersecano: l’hardware ed il software. Il software è il codice, un insieme di operazioni matematiche ed istruzioni. Attraverso queste è possibile ottenere ogni tipo di effetto voluto. Il problema è l’hardware sul quale gira il software: posso costruire un hardware che sa fare poche cose semplici per poi costruire tutti i processi complessi combinando le operazioni semplici, oppure posso costruire hardware specifico che sa fare l’operazione complessa in modo rapido, ma costa di più in termini di spazio, potenza e via dicendo, tutto dipende dalle mie richieste. Per questo per un lungo periodo, le schede grafiche hanno subito un avanzamento notevole che vedeva l’aggiunta di volta in volta di pezzi hardware speciali che velocizzavano operazioni prima lentissime oppure rendevano nuove operazioni possibili. Rispetto alle CPU, macchine generiche ma lente, le GPU erano macchine specializzate e veloci.
Per esempio, agli albori molti dei calcoli dell’illuminazione erano affidati al processore e sono negli anni 2000 questi sono stati spostati sulle GPU che hanno iniziato ad avere moduli appositi. Questi moduli hanno richiesto poi dei nuovi codici in grado di poter comandare questi nuovi componenti. Un tempo le schede grafiche erano formate da tanti pezzi che eseguivano funzioni fisse, poi si passò a funzioni fisse ma programmabili e infine ad hardware generico programmabile. Oggigiorno le architetture sono formate da shaders in grado di fare operazioni sia sui vertici che sui pixel in base alla necessità, da Texture Mapping Units che si occupano di applicare oggetti 2D come le texture su oggetti tridimensionali alle Raster Operation Pipeline che finalizzano l’immagine. Tutti questi componenti non sono sparsi a caso in una scheda, ma sono divisi in moduli con un numero specifico di Shaders, TMU e ROP così da ottimizzare il flusso di dati per modulo e avere architetture che scalano meglio.
Questo aumento di flessibilità ha portato alla nascita dei Compute Shaders, pezzi di codice generico in grado di essere eseguiti da una scheda grafica. Una GPU ora può essere anche vista come un gigantesco insieme di processori generici in grado di fare tante operazioni in parallelo che possono essere sfruttati per gli scopi più diversi. Nei videogiochi spesso si chiede alla GPU di farsi carico di calcoli fisici per esempio, in quanto possono gestire un numero di particelle su schermo ben maggiore rispetto ad una CPU. In Borderlands 2 per PC, con gli extra di PhysX abilitati, le armi acide generavano pozze di liquido dinamico che reagiva all’ambiente, le armi esplosive creavano centinaia di frammenti attivi che finivano al suolo. O nel Batman di Rocksteady, era implementato un fumo che reagiva al passare del giocatore e degli NPC. Passando ai giochi console, Assassin’s Creed Unity sfrutta la GPU per calcolare la fisica dei vestiti degli NPC, e questo è l’unico modo per poterla applicare alla loro ingente folla. Questo porta comunque uno svantaggio: se una parte della scheda grafica sta facendo calcoli compute, non può fare allo stesso tempo calcoli grafici, quindi è sempre un trade-off in base a ciò che si vuole.
Vista la complessità di una scheda grafica, entrano in gioco tanti valori numerici ideali che rappresentano la massima capacità teorica di calcolo di una determinata parte. I teraflop sono le massime operazioni al secondo degli shaders, il texture-fill rate indica la capacità massima di renderizzazione di texel (gli elementi costitutivi delle texture nello spazio tridimensionale), il pixel fill rate quanti pixel vengono elaborati. Per fare confronti che abbiano senso con pochi dati occorre soffermarsi su schede della stessa famiglia, mentre se si vogliono fare confronti con schede diverse, bisogna avere una visione dell’insieme che guardi a tutti gli elementi. Per questo in questa generazione è stato molto facile comparare a priori Xbox One e PS4: sia il loro processore che scheda grafica sono della stessa famiglia.
Una volta capito cosa fa la GPU direi di passare all’ultima parte fondamentale di un’architettura: la memoria. Per quanto ci piaccia pensare che i dati di un computer non siano fisici, in realtà lo sono. Ogni bit è rappresentato da un valore di tensione che da qualche parte deve essere immagazzinato e per essere usato deve essere letto e scritto. Questo richiede non solo capacità, ma anche velocità. La capacità si capisce facile: una texture dettagliata occupa più spazio di una meno dettagliata, così come una foto in 40 megapixel occupa più memoria di una da 1 megapixel ed è più bella da vedere. Per la velocità, spesso non ci si rende conto dei numeri in gioco, ma è facile arrivarci; immaginate di dover leggere 1GB di texture ogni volta che dovete disegnare un singolo frame. Fatelo 60 volte al secondo. Dovete essere in grado di spostare 60GB/s.
Le memorie sono organizzate in un calcolatore secondo una specifica gerarchia e svolgono ruoli diversi. Potete vederla come una struttura piramidale. Più le memorie sono capienti più sono lente e lontane da dove il dato va utilizzato. Il sistema cercherà sempre di cercare le informazioni delle quali necessita nelle memorie più vicini e veloci. Se non le trova si sposterà in quelle più lente fino a quando non trova il dato, per poi spostarlo ed usarlo. Il caricamento dei giochi è questo: prendere i dati dal CD o Hard Disk e spostarlo nelle varie RAM per avere il dato facilmente accessibile. L’immagine spiega meglio di mille parole, ma sappiate che non esiste un solo tipo di memoria e basta, ma ce ne sono molte e come queste comunicano tra di loro è importante per capire le performance possibili della macchina. Pensiamo a tutti gli open world che riescono ad operare grazie ad algoritmi che vanno sempre alla ricerca dei dati da spostare per poter offrire un gioco aperto senza caricamenti, perché il gioco sta caricando costantemente.
Per questo non basta dire “Ha 8Gb di Ram, è meglio di 4GB in automatico”. Ci sono molti altri fattori in gioco. Avere tanta capienza per poi non avere la capacità di elaborazione per usarla al meglio è uno spreco ad esempio, così come ci sono vantaggi e svantaggi nell’avere tanta memoria lenta o poca memoria veloce. L’xbox 360, One, Wii U ed altre console hanno ad esempio un piccolo pool di memoria superveloce sfruttata per eseguire calcoli sulla trasparenza ad esempio, ma la sua piccola dimensione (si parla di 32MB per la One) non le permette di fare “molto” in termini pratici e limita la grandezza della risoluzione per non sforare i 32MB. Sony con PS4 ha deciso di avere un singolo pool di “RAM grafica” ed ha 8GB che sono più veloci dell’Edram della One. C’è da considerare anche chi può accedere alla RAM. La CPU e la GPU possono condividere o meno le risorse e questo porta a dei cambiamenti nel come usarle, con tutti i pro e contro del caso. L’xbox 360 aveva 512MB di ram tutti insieme, mentre la PS3 aveva due gruppi divisi da 256MB e sappiamo quanto fosse più ostica la programmazione anche per questo (ma soprattutto per il suo processore Cell).
Tutti questi pezzi alla fine, quando interagiscono tra di loro, che benefici portano ad un gioco? Ogni era ha il suo marketing. Nel periodo Super Nintendo e Genesis si guardava la paletta di colori grafica, nell’epoca PS1 e PS2 il numero di poligoni. Più essi erano, meno spigolosi e più dettagliati erano i personaggi e l’ambiente, poi ci si è spostati sul framerate e sulla risoluzione. Queste cose cambiano nel tempo perché perdono di validità. Una volta raggiunti i 16 milioni di colori ci siamo seduti lì, così come l’aumentare i poligoni ad un certo punto diventava faticoso e si sono inventate un sacco di tecniche per aumentare dettaglio senza di loro, come la tessellatura. Al momento il framerate e la risoluzione non sembrano ancora passati di moda, visto che si sta spingendo per il 4k.
Tutte belle parole che però hanno il rischio di essere vuote se prese a se stanti. Siamo partiti dagli albori del 3D dove avevamo Link con una tunica verde, monocromatica, di un materiale non definito, con un volto spigoloso, con solo due occhi ed una bocca che si potevano animare poco. I programmatori dovevano escogitare un design dei personaggi (character design) che funzionasse con queste limitazioni. Oggi abbiamo un Link con una tunica che è un vestito completo, possiamo vederne la cotta di maglia sotto, capiamo che è un vestito a strati di materiali diversi, fatto per combattere. Link ha molte più animazioni facciali e più complesse, cosa che gli permette di comunicare più emozioni. Spesso si prendeva in giro David Cage quando nei suoi discorsi associava i poligoni alle emozioni, ma in realtà è così. Avere la possibilità di aumentare il dettaglio grafico di qualsiasi cosa, permette di raccontare di più. Io non credo di volere tornare indietro dopo aver visto la mimica facciale di The Witcher 3 e gli sviluppatori di L.A. Noire non avrebbero mai potuto dare vita al loro gioco basato sul riconoscimento dei movimenti facciali se non ci fosse stata la qualità di dettaglio minima offerta dalla generazione scorsa.
Pensiamo anche a cose più semplici come le mani. Vi ricordate i primi giochi 3d? Con i personaggi che avevano le mani a blocchi, con tutte le dita attaccate? Come potevano indicare o gesticolare? Come potevano usare gli oggetti? Come potevano stringere la mano alla propria amata incrociando le dita? Ovviamente non voglio ridimensionare il passato, ma chiarire che più si va avanti, più strumenti i programmatori avranno a disposizione. Prendiamo per esempio anche le ambientazioni: prima i campi di Hyrule avevano due alberi sparuti ed una texture verde per terra e basta. In Breath of the Wild avremo un Hyrule Field pieno di ciuffi d’erba mossi dal vento, alberi ovunque, cambiamento giorno-notte che influenza tutte le luci ed ombre dell’ambientazione, creando scorci che sono automatici e non toccati a mano dallo sviluppatore perché il gioco può permettersi di seguire le leggi fisiche naturali con simulazioni più accurate della luminosità e del calcolo dei riflessi.
E con questo posso dire di aver concluso la prima carrellata dall’alto. A questo punto vorrei chiedere a voi che leggete: quali argomenti vorreste vedere trattati, approfonditi o spiegati a grandi linee? Farò del mio meglio per chiarire i vostri dubbi o per approfondire determinati argomenti, quindi non fatevi remore nel commentare, la prossima puntata di Sotto la scocca potreste deciderla voi!

News
Kamiya conferma che Bayonetta, DMC, Viewtiful Joe, Okami e The Wonderful 101 fanno parte dello stesso universo narrativo
Hideki Kamiya conferma l’esistenza del “Kamiya-verse”, che unisce tutte le sue creazioni più famose in un universo narrativo unico.