### FUNZIONAMENTO DELLE GPU: UNA MANCANZA DI TRASPARENZA
Per imparare come funziona una CPU, dall’architettura ai segnali di controllo, non si contano le risorse disponibili online. Nel caso delle GPU, invece, il panorama è completamente diverso. La documentazione per imparare a programmare le GPU non manca di certo ma non c’è quasi nulla sul funzionamento delle unità di elaborazione Grafica a livello Hardware. Perché? Perché il mercato è estremamente agguerrito e i dettagli tecnici a basso livello per tutte le moderne architetture rimangono proprietari.
### COME CREARE UNA GPU CON IL PROGETTO TINY-GPU
Costruita utilizzando meno di 15 file di Verilog completamente documentati, la GPU tiny-gpu è un’unità ridotta all’osso che comunque può contare su di una descrizione accurata dell’architettura e dell’ISA (Instruction Set Architecture), del codice implementato con successo per eseguire operazioni di addizione e moltiplicazione tra matrici su una GPU, dell’esecuzione dei kernel – ossia delle porzioni di codice eseguite sulla GPU in parallelo su diversi thread o core. È inoltre possibile tracciare l’esecuzione dei kernel, osservando quali istruzioni sono eseguite, in che ordine e con quali dati. L’execution tracing fornisce un dettagliato resoconto di come la GPU esegue il codice, consentendo agli sviluppatori di analizzare il comportamento di ciascun programma, identificare eventuali errori o inefficienze e ottimizzare le prestazioni.
### PRINCIPI DI FUNZIONAMENTO DELLA TINY-GPU
tiny-gpu è una implementazione minimale di una GPU ottimizzata: i produttori si concentrano da un lato su GPU general-purpose (GPGPU), dall’altro su acceleratori per il machine learning come le TPU Google. Gli autori del progetto tiny-gpu evidenziano i principi generali di queste architetture, piuttosto che sui dettagli dell’hardware specifico. L’idea è quella di concentrarsi sugli elementi fondamentali che sono cruciali per tutti i moderni acceleratori hardware. Il progetto tiny-gpu prende per mano il lettore guidandolo alla scoperta di temi come l’architettura della GPU, la parallelizzazione (com’è implementato il modello SIMD, Single Instruction, Multiple Data, nell’hardware?) e la memoria (la GPU deve svolgere le sue attività rispettando i vincoli legati alla larghezza di banda della memoria).
### UNA VISIONE DELL’ARCHITETTURA DI TINY-GPU
Verilog è un linguaggio di descrizione dell’hardware (HDL, Hardware Description Language) utilizzato principalmente per la progettazione e la simulazione di circuiti digitali. È ampiamente utilizzato nell’industria dell’elettronica digitale per progettare e verificare hardware, come circuiti integrati, sistemi a logica programmabile (FPGA) e ASIC (Application-Specific Integrated Circuit). Nel caso di tiny-gpu con meno di 15 file Verilog si realizza una GPU pienamente funzionante in grado di eseguire un singolo kernel alla volta. La GPU in sé è composta da un registro di controllo del dispositivo, un dispatcher, un numero variabile di core di calcolo, un controller di memoria per la memoria dati e la memoria del programma, della cache.
### IL RUOLO DELLO SCHEDULER
Ogni core di tiny-gpu utilizza un singolo scheduler incaricato di gestire l’esecuzione dei thread. Lo scheduler esegue le istruzioni di un singolo blocco fino al completamento prima di passare a un nuovo blocco, ed esegue le istruzioni per tutti i thread in modo sincrono e sequenziale. Negli scheduler più avanzati, sono utilizzate tecniche come il pipelining al fine di massimizzare l’utilizzo delle risorse. Il principale vincolo con cui lo scheduler deve lavorare è la latenza associata al caricamento e alla memorizzazione dei dati dalla memoria globale. Mentre la maggior parte delle istruzioni può essere eseguita in modo sincrono, queste operazioni di caricamento/archiviazione sono asincrone, il che significa che il resto dell’esecuzione delle istruzioni deve essere costruito intorno a questi lunghi tempi di attesa.
### LA ISA DI TINY-GPU
Il progetto tiny-gpu implementa una semplice ISA di 11 istruzioni progettate per consentire l’uso di kernel semplici in grado di effettuare l’addizione e la moltiplicazione di matrici. Citiamo le istruzioni sulle quali si basa questa GPU minimale: n- BRnzp: Istruzione di salto per passare a un’altra riga in memoria del programma se il contenuto del registro NZP corrisponde alla condizione nzp nell’istruzione. n- CMP: Confronta il valore di due registri e memorizza il risultato nel registro NZP da utilizzare per una successiva istruzione BRnzp. n- ADD, SUB, MUL, DIV: Operazioni aritmetiche di base per consentire elaborazioni tensoriali. Un tensore è un concetto matematico generale che generalizza vettori e matrici a più dimensioni. I tensori sono spesso utilizzati per rappresentare dati multidimensionali, come ad esempio Immagini, Video, dati sensoriali o matrici di dati in applicazioni di apprendimento automatico e di Intelligenza Artificiale. n- LDR: Carica dati dalla memoria globale. n- STR: Memorizza dati nella memoria globale. n- CONST: Carica una costante in un registro. n- RET: Segnala che il thread corrente ha raggiunto la fine dell’esecuzione.
### CONCLUSIONI: TINY-GPU E LA SUA IMPORTANZA
Nel complesso, tiny-gpu rappresenta solo “un assaggio” del funzionamento di una GPU. Molti aspetti critici delle moderne unità, come il supporto per le istruzioni di intelligenza artificiale, la predizione del ramo più avanzata e l’implementazione della cache, mancano ancora all’appello nell’implementazione aperta appena condivisa pubblicamente. Tuttavia, tiny-gpu mostra i principi fondamentali che consentono l’esecuzione parallela di kernel su una GPU e si rivela quindi un progetto preziosissimo per tutti coloro che vogliono capire davvero come funzionano le GPU partendo dal livello più basso. Le GPU sono complesse ma un’iniziativa come tiny-gpu fornisce basi solide da cui partire per comprendere la logica e l’architettura che rende così potenti questi dispositivi hardware.