Il ruolo della CPU – Sotto la Scocca

sottolascocca-cpu-01-nintendon

Ad ogni nuova console che si affaccia sul mercato, iniziano come di consueto le discussioni sui sogni e sulle speranze che i giocatori ripongono nella nuova macchina. Sempre più negli ultimi anni si stanno diffondendo discorsi di natura tecnica, con gente che desidera questa o quella potenza senza però avere un’idea ben precisa di come tutto funziona all’interno della console. Con questa serie voglio provare a fare luce su alcuni dei misteri e dei meccanismi di funzionamento dell’hardware e come questo viene sfruttato per portare alla luce le esperienze che tutti amiamo o odiamo.

L’elemento più importante di un videogioco è l’esperienza. Questa deriva dalla somma di tutti gli elementi che normalmente vediamo divisi, come il gameplay, l’audio, la storia, la grafica, il level design e via dicendo. Tutte queste cose però non esistono nel vuoto, ma vengono eseguite da macchine, che hanno determinate caratteristiche hardware che influenzano direttamente tutti gli elementi che possono essere generati. Ma qual è il legame tra hardware e videogioco? Io lo vedo un po’ come quello che lega un compositore agli strumenti musicali. Più note ho a disposizione, più capacità di espressione ho. Posso sì creare una grande melodia anche con un controfagotto che va da 30 a 200Hz, ma se ho un pianoforte, che va da 27,5 a 4100Hz ho semplicemente più possibilità e posso esprimermi in modo più complesso, più completo.

blockdia_wiiu_full

Il diagramma a blocchi dei componenti del Wii U e come sono collegati. La CPU è solo “Espresso”

In una console da gioco ci sono due elementi fondamentali che svolgono i calcoli matematici e logici necessari a dare la vita ai videogiochi: la CPU e la GPU. In questo primo articolo punterò l’attenzione sull’elemento forse meno considerato in tutti i discorsi del web: la CPU, l’unità di calcolo centrale, cosa ben strana a mio avviso, in quanto la CPU è la vera anima di una console ed è grazie alla sua evoluzione che è possibile fare un salto generazionale. Questa è la visione di Mark Cerny, il capo architettura della Playstation 4, che collega un salto generazionale al miglioramento del processore e ad un aumento massivo della capacità di memoria.

Questo perché? La risposta è molto semplice: il processore governa ogni aspetto del gioco che non sia il disegno diretto dell’immagine ed in un videogioco questo carico di lavoro è molto. Quando noi giocatori premiamo il tasto A per far saltare Mario su un nemico, il processore deve andare a trovare l’animazione del salto, fare i calcoli della fisica del salto e dell’impatto con il nemico, gestire l’intelligenza artificiale nel nemico, trovare tutti i file audio necessari e dire all’unità grafica cosa deve andare a disegnare. Immaginate questo processo in un Mario Kart invece, dove da tenere sott’occhio ci sono tutti i piloti, ognuno dei quali può usare un oggetto. È facile capire come maggiore è la complessità, maggiore è la richiesta della CPU ed ovviamente è vero l’opposto: maggiore potenza ha la nostra CPU, più possiamo permetterci complessità in un mondo di gioco.

multitreaded-rendering

Carico di lavoro su 6 core. I riquadri arancioni indicano lavori legati alla grafica, quelli grigi sono IA, Fisica e Logica

Ovviamente una CPU non esiste nel vuoto ma deve lavorare insieme alla GPU. Ci sono due elementi che vincolano le due componenti. Il primo tassello sono le Draw Call, le chiamate al disegno. Praticamente, la GPU non ha la più pallida idea di cosa c’è sulla scena. La CPU deve recuperare tutte le informazioni sui modelli, su quante texture sono ad esso applicate, come sono gestiti i punti luce ed altro ancora. Come sono effettivamente organizzati i dati dipende dal motore grafico in uso, ma in generale più oggetti ci sono sulla scena e più istruzioni la CPU dovrà preparare per la GPU. L’idea nella programmazione sta nell’ottimizzare il flusso delle Call così da non spendere troppo tempo con il processore che prepara e manda istruzioni, e con la GPU che non sa cosa fare mentre aspetta i comandi.

L’altro elemento che lega i due componenti è il framerate obiettivo del progetto. Avere un gioco che va a 60 frame al secondo vuol dire che ogni immagine deve essere preparata entro 16 millisecondi, altrimenti il framerate diminuisce. Sia il processore che la scheda grafica devono fare tutti i calcoli entro questo lasso di tempo. L’equilibrio tra i componenti diventa essenziale, così come una programmazione in grado di aggirare i cosiddetti colli di bottiglia. Prendiamo l’esempio del New Nintendo 3DS. Si passa da 2 core a 268Mhz del vecchio modello a 4 core a 804Mhz. Un aumento di 6 volte. La scheda grafica non è stata toccata e riceve solo 4MB in più di memoria, ma la quantità di dati che può processare rimane la stessa. Hyrule Warriors Legends è forse il migliore esempio. Sul modello precedente infatti ci sono meno nemici a schermo, ma nonostante questo il framerate supera a fatica i 20fps. Su New ci troviamo sui 30 fissi. Questo accade perché la scheda grafica del 3DS non è adeguatamente alimentata dal processore, che deve farsi carico di gestire tutti i nemici su schermo, la loro posizione, come il giocatore interagisce con essi: tutto questo è decisamente troppo e la GPU è costretta ad andare alla velocità del componente più scarso, ad aspettare i comodi del processore. Quindi avere più core ed averli più veloci è sempre meglio?

ubisoft-cloth-simulation-ps4-vs-ps3

Come si può vedere, per eseguire questo codice di calcolo di danzatrici, la CPU della PS3 è più veloce di quella della PS4!

In linea di massima sì, anche se ogni processore ha un suo ciclo di istruzione, ovvero un parametro che indica quanti cicli ci vogliono per eseguire effettivamente un’istruzione, quindi confrontare direttamente le frequenze non è la cosa più corretta da fare. Esistono tanti tipi di processori e la tipologia cambia la logica di programmazione. Si parla spesso di ARM, X86 e per le console anche di PowerPC, ma cosa cambia effettivamente tra essi? Gli elementi che fanno 1+1 sono sempre gli stessi per tutti i processori, il problema è come arrivare a fare 1+1. Dove mettere i dati, come pescarli e muoverli all’interno dei numerosi transistor è ciò che differenzia le architetture. Ci sono in generale due modi per classificare le architetture. Una guarda a che tipo di istruzioni essa esegue e l’altra guarda all’ordine di esecuzione.

Per le istruzioni si distinguono due famiglie: la CISC e la RISC, acronimi inglesi che vogliono dire Complex Instruction Set Computing e Reduced Instruction Set Computing, con X86 facente parte della prima ed ARM della seconda. I processori costruiti per istruzioni CISC hanno un numero molto elevato di transistor e di memorie interne che servono a spostare i dati di continuo per permettere al programmatore di poter chiedere di fare un calcolo complesso con una singola riga di codice, con una sola istruzione. I RISC invece hanno istruzioni molto più vicine alla macchina e questo si traduce nel dover andare a dire cosa fare usando tante micro operazioni, scrivendo quindi più codice. L’aspetto positivo è che dovendo saper fare meno cose, l’architettura è più efficiente. Per questo ARM ha avuto molto successo in ambito mobile. Ora, in linea teorica un discorso del genere vede i processori RISC ottenere performance migliori in quanto possono ottimizzare meglio i singoli processi, mentre con i CISC non posso andare a fondo, anche se l’ottimizzazione richiede più tempo per un programmatore.

in-order-vs-out-of-order

Un esempio grafico della differenza di efficienza tra In Order e Out of Order

Un altro fattore di differenza tra le CPU è l’ordine di esecuzione, che viene distinto in Out of Order e In order. Questo concetto è molto semplice da metabolizzare. L’In Order esegue le operazioni nell’ordine nel quale sono state inviate. In un’esecuzione Out of Order, il processore da solo si rende conto che alcune operazioni sono indipendenti o che sono più lente o veloci e cambia l’ordine di esecuzione al volo per compiere il lavoro nel modo più efficiente. Nel primo caso c’è la possibilità di incontrare stalli perché diversi processi veloci dovranno stare in attesa di altri lenti e questo può portare ritardi. Nel secondo questo problema non c’è, ma il processore deve essere più complesso e più energivoro per funzionare in questo modo.

Tutta bella teoria, ma in pratica? Le differenze tra le architetture che gestiscono la logica sono la causa dei problemi del porting, perché occorre ripensare a come gestire il flusso di dati e la logica del motore di gioco. La grafica è un problema secondario e per certi versi meno importante. Xbox 360 e  Playstation 3 hanno processori RISC ed In Order, a frequenze molto elevate così da sopperire a possibili stalli e la loro velocità permette di eseguire la logica di gioco ad alta velocità. La famiglia Gamecube/Wii/Wii U invece ha sempre fatto uso di processori RISC ma Out of Order, quindi più efficienti a parità di frequenza. Passare dal Nintendo Wii U al Nintendo Switch, che monterà con tutta probabilità un ARM, non è un salto così drammatico per Nintendo, perché è vero che cambiano tutte le istruzioni, ma la logica di programmazione, come dover pensare per superare i problemi nella costruzione di un motore grafico, non cambia molto, passando da un RISC OoO ad un altro RISC OoO. Completamente diverso, invece, il salto da Playstation 3 a Playstation 4, dove cambiano sia logica di istruzione che logica di esecuzione.

final-fantasy-xv-uso-processore

La versione finale di FFXV ha più elementi su schermo della prima demo e performance migliori, grazie allo sfruttamento della CPU

È più facile vedere gli effetti di un “grosso” processore in titoli complessi, con tanti elementi. Nintendo ne ha pochi, quindi è difficile prenderli come esempio. È più facile chiamare in causa un gioco AAA come Assassin’s Creed Unity: nuovo motore di gioco, nuove piattaforme, Parigi riprodotta nei minimi dettagli, folla dinamica e dettagliata, e un’IA di navigazione di massa e non solo individuale che, stando ad alcune dichiarazioni, richiedevano troppe draw call dal processore, con conseguente crollo del framerate. La folla metteva sotto duro stress il processore ma meno su Xbox One che su PS4, merito di quei 175Mhz in più per core. Con il gioco successivo, Syndicate, Ubisoft ha creato una Londra forse meno popolata rispetto alla gigantesca folla parigina di Unity. Il gioco ha performance migliori, ma si è dovuti scendere a compromessi, a dover forse attenuare una visione.

Dovremmo sognare ed immaginare queste possibilità quando “vogliamo” un processore più performante da una nuova console. Mondi più complessi, più vivi, distanze visive maggiori, schermi con più “roba”, per farla breve. Io sono un appassionato di giochi strategici, e adoro gli scontri di massa tra tantissime unità e certe cose sono possibili in modo grandioso solo se sotto la scocca c’è un processore adeguato, in grado di stare dietro a tutte le singole unità con i loro movimenti, i loro effetti, la loro logica, la loro fisica. Volete più Pikmin su schermo, con intelligenza più dinamica e maggiore interazione con l’ambiente? Meglio avere una CPU potente sotto la scocca.

  • SGABANG

    Wow. Bellissimo articolo. Interessante e ben scritto. Aspetto con ansia i prossimi episodi.

  • Hyper L

    Argomento molto molto interessante. Perché è vero che oggi spesso molti si esaltano all’idea di avere qualche hertz in più, CPU/GPU leggermente migliori, e così via, non pensando davvero a ciò che è importante, ossia i giochi. Ma è vero anche che il discorso opposto, che evita completamente questo argomento e pensa che siano importanti solo i giochi è comunque incompleto imho.
    Nel senso, è verissimo che alla fine ciò che per noi è importante è il gioco, però è anche vero che avere sotto la scocca componenti più performanti può migliorare la nostra esperienza. Insomma, prendete solo il meglio da entrambe le linee di pensiero.
    Ricordando che i giochi sono in fondo ciò che conta di più, discutere sui componenti e analizzare il funzionamento delle nostre console rimane comunque molto interessante

  • Mauro

    Un articolo di questi ogni settimana e da parte mia hai caffè gratis a vita.

  • BlueUser

    Non credo potessi usare un esempio migliore del salto di Mario.
    È inoltre una delle poche volte che vedo spiegata l’architettura in modo universalmente comprensibile.
    Complimenti.

  • Carlo Ercole Burei

    Complimenti per l’articolo: tecnico ma spiegato in maniera davvero comprensibile. Davvero interessante! In attesa dei prossimi…

  • Fede

    Bravo Cap. Educa il popolo ignorante.

  • Bell’articolo! Non sapevo scrivessi per NintendOn lol

    Comunque mi permetto di fare il rompiscatole e fare una precisazione sul discorso RISC/CISC: Non è vero che il RISC permette una maggior ottimizzazione, è un discorso diverso da quello che si può fare a livello software quando si parla ad esempio di linguaggi di programmazione ad oggetti come il Java paragonati a linguaggi più semplici come il C. In quei casi, stiamo usando “istruzioni complesse” che poi quando il codice viene compilato vengono mappate su più istruzioni e quindi abbiamo meno controllo sull’effettivo flusso del codice a livello macchina.

    La differenza tra RISC e CISC (a livello hardware, quindi) sta invece nel fatto che i processori CISC hanno proprio più istruzioni macchina disponibili, a differenza dei RISC, e possono quindi fare in un ciclo di clock cose che magari in un processore RISC ne richiedevano 2 o 3, dando quindi a chi le sa sfruttare una maggiore ottimizzazione rispetto a un RISC! Il modello CISC è nato infatti proprio per colmare in parte il divario che c’era tra i linguaggi di programmazione ad alto livello e ciò che effettivamente avveniva sul processore.

    Lo svantaggio è che un processore CISC consumerà un sacco di più e necessiterà quindi di maggiori sistemi di raffreddamento, maggiore energia… ed è per questo che in ambito mobile, dove tutto deve occupare il meno spazio possibile ed essere più efficiente a livello di consumi hanno fatto un gran successo architetture RISC come la ARM. Ovviamente lo Switch avrà per forza di cose qualcosa del genere, essendo in fin dei conti un tablet, mentre su Xbox One e PS4 si è passati ad x86-64 perché alla fine se hai la possibilità di stare collegato a una presa di corrente e di avere un case che deve stare fermo lì, e quindi se occupa un po’ di più per via di ventole più grosse non è un dramma, l’architettura CISC può essere un buon investimento.

    • Quando le architetture nacquero, a parità di frequenza di clock, le RISC erano più veloci delle CISC, proprio per la minor lunghezza della pipeline delle RISC e del minor numero di cicli per istruzione rispetto ad una CISC. Molte delle istruzioni più complesse di un CISC impiegavano più cicli ad essere eseguiti rispetto a quelle dei RISC.
      Questo in genere era visto in questo modo: la lunghezza massima delle istruzioni di un RISC era minore e molto più costante e pertanto ogni tipo di operazione veniva eseguita in lassi di tempo uguali o comparabili. un Cisc invece ha bisogno di un decompilatore e di stallare la pipeline mentre cerca di capire che diavolo gli ho chiesto di fare, per poi andare finalmente ad eseguire l’istruzione. Tutti passaggi che il RISC salta in toto e questi devono essere fattorizzati nel ciclo di lavoro. Non è assolutamente detto che una singola istruzione in CISC sia più veloce di 2-3 in RISC, anzi è più probabile il contrario. Questo intendevo con “ottimizzazione”. Avendo la capacità di dare solo comandi precisi e non globali, posso permettermi di saltare molto del grasso. Posso avere un’architettura dritta al punto e non una con tanto contorno che userò poco o che mi rallenti.
      Il classico esempio che si fa è questo:
      moltiplicare due numeri in memoria.
      Su un CISC opero con questo comando macchina
      Mult 2:3, 5:2 che equivale ad un comando in C di a=a*b
      Su un RISC la macchina deve fare
      Load A, 2:3
      load B 5:2
      Prod A, B
      Store 2:3, A

      4 istruzioni contro una. In questo bisogna fattorizzare quanto effettivamente ci vuole per eseguire le singole istruzioni. Le 4 del RISC risultano essere di velocità uguale se non superiore a quella del CISC, proprio perché più dirette e semplici.

      L’architettura RISC è nata proprio negli anni ’80 (10 anni dopo la CISC) per cercare di eliminare il grasso delle CISC. Quindi l’opposto di come sembri dire tu (che la cisc è nata per eliminare il gap come le la risc fosse pre esistente, no è il contrario. Dopo che nacque la cisc ci si accorse che era troppo grassa ed andava snellita)

      Il consenso dagli inizio degli anni 90 fino a poco prima degli anni 2000 era proprio quello che le architetture CISC avevano bisogno di un bel po’ di ottimizzazione e riscrittura delle microarchitetture e del microcodice per colmare il gap di performance rispetto alle RISC. Infatti tutta la ricerca Intel ed AMD nel settore si è sempre basata sul togliere il grasso dalla loro architettura CISC.
      Con il tempo infatti la maggiore differenziazione a livello prestazionale non è più stata l’ISA, ma la microarchitettura in questione. Gli x86 di Intel hanno avuto cache sempre più grandi e intere branch predittive (e tipo all’interno integrano delle strutture “mini risc”, ma non complichiamoci la vita) che sono riuscite a smaltire quanto più grasso possibile ed il confronto ai giorni nostri per quel che riguarda il general computing trascende l’ISA, ma è meglio guardare prodotto singolo per prodotto singolo. Il diffondersi dell’x86 come dominante fu più una questione politica che altro.
      Qui uno studio http://research.cs.wisc.edu/vertical/papers/2013/hpca13-isa-power-struggles.pdf proprio su come una volta l’ISA dava differenza (con il CISC storicamente più lento e con più grasso da smaltire) ad oggi dove conta relativamente poco rispetto al passato, anche perché oramai RISC e CISC sono usati un po’ impropriamente.

      Credo che sia molto istruttivo andare a raccattare tutti gli studi degli anni ’80-’90 che illustrano meglio il divario dell’epoca in un periodo dove i costi e la miniaturizzazione erano ben diversi.

      • Ok, hai ragione sul fatto che la RISC è più veloce in certi scenari per via della possibilità di mettere in pipelining le varie istruzioni, ma bisogna anche contare il fatto che avendo data cache e instruction cache separate la CISC può in alcuni scenari, in particolare gli accessi a memoria, parallelizzare alcune operazioni e risultare quindi più veloce.

        E riguardo il fatto che da come ho detto io sembrava che fosse nata prima la RISC… non è ovviamente vero, ma di fatto prima dell’introduzione del modello CISC i processori usavano operazioni più “base”, con una filosofia più vicina a quella del modello RISC. Poi ovviamente come spesso capita, si guarda al passato per innovare, e sono tornati a cercare la semplificazione.

        L’x86 più che per ragioni politiche, continua ad essere utilizzato per praticità e compatibilità con il passato, intel aveva pure fatto un processore a 64 bit con un’architettura molto più pulita e semplice dell’x86, ma di fatto non ebbe successo perché nessuno voleva che tutto a un tratto tutto il suo software divenisse completamente inutilizzabile.

        Detto ciò, senza che estendiamo troppo i discorsi tecnici (che come giustamente dici non sono argomento di questo sito), vorrei concludere dicendo che non esiste un’architettura “migliore”, ma soltanto quella migliore per un certo problema. Quindi è ingiusto dire che il modello RISC è migliore del CISC, ma effettivamente hai ragione se dici che per il tipo di operazioni che devono fare i videogiochi probabilmente il RISC è molto più conveniente. Anche se, d’altro canto, montare l’x86 rende più facile adattare da PC, e hai detto poco. Chissà se in un mondo dei videogiochi (escludendo il mobile) ormai completamente x86, non avere tale architettura sarà un problema per lo Switch (che a mio parere, ha bisogno di tante terze parti per fare veramente successo). Vedremo.

        • No, assolutamente, non esiste l’architetture migliore in assoluto, ma migliore per lo scopo.
          Conta poi che per le architetture console se ci si fa caso, si tende a scegliere la cosa con meno fronzoli possibile a meno di non impazzire.
          Sony con il CELL voleva imporsi con la supertecnologia giapponese senza capire bene il mercato e “gli altri” (spiegato molto bene in un’intervista di Tretton su IGN), la microsoft con l’x86 della prima XBOX perché “tanto è come un PC”, ma gli altri sono sempre andati dritti al punto, con Nintendo che per 3 gen ha usato la stessa architettura in modo molto efficiente ed aggiungerei efficace.
          Poi il mondo PC ha vinto sempre più ed ha portato l’X86 a predominare.

          Lo Switch di sicuro avrà le sue difficoltà per un motivo semplice: di programmatori ARM non ce ne sono poi tantissimi nel campo dei videogiochi classici perché gli unici maghi degli ARM sono quelli che sono rimasti a sviluppare per DS o 3DS. Per loro la transizione su Switch sarà indolore, avranno solo un’infinità di risorse in più, per gli altri occorrerà assumere un po’ di gente per convertire i motori interni.
          Quelli generici (UE, Unity e via dicendo) non avranno il problema perché sono già rigirati su tutto ed hanno specialisti un po’ per tutto.

logo-bianco

NINTENDON EVENTI

Per la tua pubblicità su NINTENDON.IT

Regolamento Forum - Contatti - Nicer Design

Privacy Policy

Informativa estesa sui Cookie

©2017 NintendOn Tutti i diritti riservati. Tutti i marchi appartengono ai rispettivi proprietari.

Log in with your credentials

or    

Forgot your details?

Create Account