Sebbene le GPU siano gli acceleratori hardware più diffusi nell’ambito del calcolo ad alte prestazioni (High Performance Computing, HPC), recentemente, in molti progetti tra cui Brainwave, EuroEXA, Xilinx Adaptive Compute Clusters, è stato sperimentato anche l’utilizzo di FPGA, in particolare per accelerare algoritmi di inferenza per Machine Learning (ML) ed implementare reti di comunicazione a bassa latenza.
Green Computing: tutte le sfide per costruire supercalcolatori a ridotto impatto energetico
Visto l’interesse crescente nel velocizzare questa classe di algoritmi, così come la cruciale necessità in ambito HPC di ridurre le latenze di comunicazione tra nodi di calcolo ed accelerare l’accesso ai dati memorizzati su disco, possiamo immaginare che in futuro l’uso di questo tipo di acceleratori possa diventare più comune.
Cosa è una FPGA e a che serve
Una FPGA (Field Programmable Gate Array), è un dispositivo hardware formato da un circuito integrato le cui funzionalità logiche di elaborazione sono programmabili e modificabili tramite opportuni linguaggi di descrizione dell’hardware.
Questi circuiti integrati contengono infatti dei “blocchi” di hardware generico di diverso tipo (e.g. LUTs; FFs; DSPs; Block RAMs), riconfigurabili sia nelle funzioni che nei collegamenti dei rispettivi input ed output. La possibilità di programmare le funzionalità delle FPGA permette quindi di implementare a livello hardware esattamente le operazioni necessarie per una specifica applicazione software.
Ad esempio, data una applicazione che esegue solo somme e divisioni intere ad 11 bit, una FPGA può essere configurata per implementare esclusivamente unità di calcolo in grado di eseguire queste due operazioni, senza sprechi di risorse dovuti a unità progettate per essere generiche, ed in grado di eseguire anche altri tipi di operazioni.
Figura 1. Rappresentazione schematica delle principali componenti di una FPGA. Immagine di pubblico dominio, fonte: wikimedia.org
Le FPGA non sono ancora particolarmente diffuse come acceleratori in ambito HPC principalmente per due motivi:
- dal punto di vista delle prestazioni computazionali, sono storicamente considerate poco performanti per i calcoli in virgola mobile, non avendo tipicamente delle unità floating-point dedicate;
- per la loro programmazione hanno storicamente richiesto linguaggi specifici, normalmente non utilizzati dagli sviluppatori in ambito HPC.
Recentemente però, queste limitazioni si stanno ridimensionando. L’introduzione di un crescente numero di blocchi DSPs (Digital Signal Processors), sempre più complessi, ha permesso alle FPGA di raggiungere prestazioni computazionali simili a quelle delle CPU. Allo stesso tempo i compilatori/sintetizzatori più recenti permettono di programmare le FPGA anche con linguaggi ad alto livello, molto simili a quelli comunemente utilizzati nel mondo HPC.
Queste caratteristiche stanno rendendo le FPGA sempre più interessanti anche in questo ambito, dove possono essere utilizzate come acceleratori all’interno di sistemi tradizionali, con l’obiettivo di mitigare diversi fattori limitanti delle prestazioni delle applicazioni, quali:
- la potenza computazionale;
- la banda con la memoria;
- le comunicazioni di rete;
- l’accesso I/O allo storage.
L’impatto delle FPGA sulla potenza computazionale
Le FPGA odierne hanno una potenza computazionale in termini di operazioni in virgola mobile nell’ordine del TFLOP/s, come le moderne CPUs: da questo punto di vista, potrebbero non sembrare adatte a essere utilizzate come acceleratori.
D’altro canto, una FPGA, per la sua natura riconfigurabile, se è in grado di eseguire un certo numero di FLOP per secondo in virgola mobile a doppia precisione, può essere configurata per eseguire un numero molto maggiore di operazioni per secondo, se queste sono operazioni “più semplici”. Per esempio, operazioni con una precisione numerica più bassa (e.g. single- o half-precision), o ancora meglio se operazioni a virgola fissa, o intere, magari con un ridotto numero di bit.
Anche CPU e GPU permettono un numero più alto di operazioni al secondo, riducendo la precisione delle operazioni floating-point, ma il tipo di operazioni possibili è predefinito e tipicamente non c’è un vantaggio nell’uso della virgola fissa. Le FPGA invece, permettono di implementare le operazioni necessarie ad una determinata applicazione, usando un numero di bit arbitrario. In genere, più sono semplici le operazioni, maggiore sarà il numero delle unità hardware in grado di eseguirle, implementabili dentro la medesima FPGA. Ne deriva un incremento delle prestazioni in termini di operazioni al secondo che possono essere portate a termine.
Figura 2. Plot di Roofline misurato dal benchmark FER [1] su un acceleratore Xilinx Alveo U250 basato su FPGA, da cui si evidenzia la performance di picco in termini di operazioni al secondo per diverse precisioni numeriche.
È proprio per questa caratteristica che le FPGA hanno cominciato ad essere utilizzate in alcuni centri di calcolo, principalmente per accelerare gli algoritmi di inferenza nell’ambito del Machine Learning (ML).
Molti di questi algoritmi infatti, possono ottenere i medesimi risultati pur utilizzando operazioni con precisioni che possono essere notevolmente ridotte rispetto alle comuni operazioni floating-point a 64 e 32 bit. Le moderne CPU e GPU, per andare incontro a queste necessità stanno infatti a loro volta introducendo istruzioni apposite, a precisione ridotta (e.g. interi a 8 bit) per applicazioni di ML, ma le FPGA rimangono molto più flessibili ed adattabili alle necessità specifiche delle diverse applicazioni.
Venendo incontro all’aumento dei carichi di lavoro nell’ambito del ML, possiamo quindi immaginare che in futuro gli acceleratori basati su FPGA potrebbero diventare più comuni nei sistemi HPC. In questo contesto, possiamo quindi immaginare che applicazioni HPC tradizionali, in cui spesso la doppia precisione viene utilizzata anche se non realmente necessaria, potrebbero venire ottimizzate riducendo la precisione delle operazioni, ove possibile, per sfruttare gli acceleratori basati su FPGA.
Le FPGA permettono infatti di realizzare processori ad hoc, con un arbitrario livello di parallelismo nelle unità di calcolo, avendo come uniche limitazioni: il numero ed il tipo di “blocchi” a disposizione, e le risorse di interconnessione per collegarli tra loro.
Le prestazioni delle FPGA oggi in commercio, pur non sembrando competitive in termini di FLOP/s di picco con altri tipi di acceleratori, possono però esserlo se le applicazioni sono in grado di sfruttare operazioni a precisione ridotta, a virgola fissa, o intere. Inoltre, la possibilità offerta dalle FPGA di implementare in hardware esclusivamente le operazioni necessarie per l’applicazione di interesse, si traduce spesso in un vantaggio anche in termini di efficienza energetica, dovuto anche alle basse frequenze di clock rispetto a quelle di altri processori.
FPGA: come incide sulla banda con la memoria
Gli acceleratori basati su FPGA sono tipicamente dotati di una memoria dedicata esterna al chip, come per gli acceleratori basati su GPU. Questa memoria può essere una normale memoria DDR, ma anche una memoria HBM (High Bandwidth Memory): in questo secondo caso, si è in grado di raggiungere delle bande nello stesso ordine di grandezza dei comuni acceleratori basati su GPU.
Inoltre, all’interno delle FPGA stesse, si trovano dei “blocchi” di memoria on-chip (i.e. BlockRAM, o UltraRAM) riconfigurabili, che permettono di raggiungere le stesse dimensioni e bande delle memorie cache presenti su CPU e GPU. Al contrario però di queste ultime, organizzate in cache line con un’architettura predefinita, le RAM interne delle FPGA permettono di implementare memorie con caratteristiche arbitrarie, per esempio in termini di larghezza del bus, o in termini di ottimizzazioni per diversi pattern di accesso; avendo come unico limite il numero di blocchi disponibili e utilizzabili.
Varie applicazioni HPC necessitano di eseguire accessi sparsi alla memoria, basti pensare a tutte quelle basate su stencil. Questa necessità però contrasta con quella di effettuare accessi contigui (in gergo tecnico, coalesced) alla memoria esterna per ottenere una banda vicina a quella di picco. Allo stesso modo, tipicamente, anche le caratteristiche della gerarchia delle memorie cache prevedono che accedere ad un unico elemento costi, in termini di tempo, quanto accedere a tutti gli elementi di una cache line; e conseguentemente effettuare accessi sparsi impedisce di raggiungere la banda massima teorica.
In questo contesto, le FPGA possono essere utilizzate per accelerare diverse applicazioni HPC. Per esempio, una volta effettuati accessi contigui alla memoria esterna per portare i dati sulle memorie on-chip, queste ultime possono essere configurate in hardware, dentro l’FPGA stessa, per permettere l’accesso a locazioni sparse, garantendo la possibilità di eseguire lo stencil necessario all’applicazione di interesse, potenzialmente in un singolo colpo di clock.
Le comunicazioni di rete con l’FPGA
Una delle sfide per le piattaforme di calcolo ad alte prestazioni basate su acceleratori (FPGA, ma anche GPU) è sostenere la potenza di calcolo concentrata nel dispositivo con un sufficiente flusso di dati: la strozzatura per le prestazioni, spesso, è proprio nella velocità di accesso ai dati da processare, piuttosto che nel calcolo in sé.
Ciò è tanto più vero in sistemi di calcolo di larga scala, basati su molteplici nodi distintamente dedicati al calcolo ed alla memorizzazione dei dati. In tali sistemi, i nodi sono tipicamente interconnessi da reti specificamente pensate per l’HPC, come InfiniBand, Ethernet o Intel Omni-Path.
L’utilizzo efficiente di tali sistemi di interconnessione è oggetto di studio in molti ambiti, che vanno da applicazioni di Machine Learning su larga scala fino ad esperimenti di fisica delle particelle, come quelli condotti presso il Large Hadron Collider (LHC) al CERN, e l’elaborazione di grandi moli di dati da parte di applicazioni di astrofisica.
In questi, così come in molti altri domini applicativi, sono spesso ricercate soluzioni efficienti, che coniughino la potenza di calcolo fornita da acceleratori come le FPGA con l’accesso efficiente ai dati, spesso con approcci ad hoc dipendenti dall’architettura dell’applicazione ed in particolare dalle sorgenti di dati.
Molte di queste soluzioni sono orientate a sfruttare specifiche caratteristiche delle tecnologie di interconnessione, che possono rivestire un ruolo decisivo in applicazioni in cui l’accesso ai dati risulta il fattore limitante. Ad esempio, il protocollo InfiniBand è stato sviluppato in modo da supportare direttamente un meccanismo noto come remote direct memory access (RDMA), che consente il trasferimento autonomo di intere regioni di memoria tra nodi.
L’RDMA è gestito autonomamente dall’adattatore di rete ed è in grado di operare direttamente nello spazio di memoria delle applicazioni utente, senza che il processore ed il sistema operativo del nodo siano coinvolti nelle operazioni, migliorando quindi latenze di accesso e tassi di trasferimento. Attualmente, oltre che su InfiniBand, RDMA è disponibile su Ethernet (RDMA over Converged Ethernet, RoCE), iWARP ed Omni-Path.
Un aspetto interessante di RDMA è la capacità di sfruttare il cosiddetto peer-to-peer a livello di interconnessione interna al nodo, tipicamente basata su bus PCIexpress. Tale caratteristica permette ad un adattatore di rete di trasferire porzioni di memoria dall’esterno direttamente alla memoria di un acceleratore, ad esempio una scheda FPGA, o di far comunicare dispositivi di storage ed acceleratori.
Un’ulteriore opportunità viene dalla realizzazione di interconnessioni dirette tra dispositivi di accelerazione. Le GPU Nvidia per il calcolo ad alte prestazioni offrono un simile meccanismo attraverso il protocollo di comunicazione proprietario chiamato NVLink, che permette di creare cluster di diverse GPU in comunicazione diretta all’interno di un singolo nodo di calcolo. Su questo fronte, è interessante notare che le schede di accelerazione basate su FPGA offrono la possibilità di progettare interconnessioni dirette, simili ad NVLink, ma progettate ad hoc. In effetti, tali schede offrono spesso uno o più connettori per cavi in fibra ottica, attualmente in grado di raggiungere bande nell’ordine dei 100Gb/s, direttamente utilizzabili dai componenti hardware realizzati su FPGA.
In altri termini, come già mostrato dalla comunità tecnico-scientifica in diversi lavori, è possibile implementare un adattatore di rete “custom” sull’FPGA, tarato sulle specifiche esigenze dell’applicazione e dell’interconnessione dedicata tra acceleratori, che lo sviluppatore o il sistemista intendono realizzare.
Si tratta come sottolineato di un’ulteriore opportunità, peculiare delle FPGA, che può dimostrarsi vantaggiosa per alcuni casi d’uso, avendo di contro lo svantaggio di sottrarre risorse all’applicazione (utilizzate per l’interfacciamento alla rete, invece che per l’accelerazione in sé) e di complicare l’integrazione con tecnologie di interconnessione standard, come invece consentito dall’uso di RDMA e peer-to-peer su PCIexpress.
FPGA e l’accesso allo storage
Applicazioni quali l’intelligenza artificiale (AI), Big Data analytics, content delivery networks (CDN), database, machine learning, richiedono una perfetta integrazione delle unità di memorizzazione dell’informazione (storage) con elementi di calcolo.
Nelle tradizionali architetture di Von Neumann, lo spostamento dei dati dai diversi livelli di storage (main memory e mass memory) verso le CPU o gli acceleratori come GPU, DPU e FPGA pone alcune importanti problematiche riguardo all’efficienza energetica e le prestazioni.
Lo storage di massa, in particolare, è fondamentale nei diversi stadi della catena di operazioni (preparazione dei dati, etichettatura, allenamento dei modelli e inferenza) su cui si basa la Big Data analysis, per cui il miglioramento delle prestazioni di lettura/scrittura dei dati diventa di vitale importanza.
Tutto ciò però deve avvenire senza impattare su altre metriche non-funzionali dello storage quali il consumo di potenza/energia e l’affidabilità. Lo stato dell’arte dei dispositivi e sistemi di memorizzazione di massa è rappresentato oggi dai dischi a stato solido (SSD), che basano il loro principio di funzionamento nell’integrazione di moduli di memoria NAND Flash (sia planari che 3D).
Nei tradizionali nodi di calcolo HPC, si ha una richiesta sempre maggiore di densità di memorizzazione basata su SSD a discapito di una disparità marcata fra potenza di calcolo e potenza di movimento dei dati. In questo contesto nasce il concetto di Computational Storage (CS).
Il CS rappresenta un paradigma architetturale in cui si possono implementare funzioni storage-oriented chiamate appunto CS Functions (CSF) direttamente su acceleratori che consentono una riduzione del movimento dei dati ed un conseguente off-load delle CPU dedicate al calcolo.
Alcune funzioni possono essere, ad esempio, la compressione dei dati, le deduplicazione, il data pre-processing. Il CS consente un aumento dell’efficienza infrastrutturale attraverso l’integrazione delle risorse di computazione o direttamente nello storage (in appositi dispositivi dedicati chiamati CS Devices-CSD che integrano FPGA e SSD sullo stesso chip come la tecnologia SmartSSD di Samsung/AMD-Xilinx) o tra le CPU host e gli SSD usano CS Processors dedicati (CSP).
Figura 3. Esempio di una architettura CS basata su una FPGA (CSP) che accelera una funzione di storage specifica e un SSD interconnessi tramite bus PCIe. La freccia rossa indica il flusso dei dati che coinvolge solo la Root Complex del bus, lasciando libere le risorse (CPU e DRAM) del sistema host. L’idea si basa sul concetto discusso in [3].
Recentemente, le GPU Nvidia hanno adottato il paradigma CS attraverso una serie di tecnologie proprietarie, pur non garantendo lo stesso grado di flessibilità di operazione (i.e., precisione aritmetica) ed efficienza energetica delle FPGA.
Dal punto di vista implementativo, il CS si fonda sull’esistenza di un protocollo di comunicazione condiviso tra SSD, host CPU e acceleratori GPU/FPGA, nello specifico il protocollo PCIe.
Gli SSD, in particolare, utilizzano un sottoinsieme della specifica PCIe chiamato NVMe. Tale protocollo consente di raggiungere performance molto elevate senza penalizzare troppo le figure di merito dell’intero sistema. Il CS consente non solo di accelerare specifiche funzioni di processamento dei dati scaricando l’occupazione di risorse dell’host CPU, ma ha anche l’obiettivo di accelerare le prestazioni di archiviazione senza incidere drasticamente sul consumo di energia dell’SSD.
Queste due metriche hanno mostrato uno stretto legame con l’affidabilità di archiviazione, quindi il controllo di quest’ultima proprietà attraverso motori di calcolo dedicati è obbligatorio. Un esempio è il monitoraggio proattivo dello stato di vita dello storage medium (i.e., NAND Flash) negli SSDs eseguito da un apposito controller che modifica le modalità di accesso di memoria in maniera opportuna.
Conclusioni
Sebbene siano al momento una tecnologia di nicchia per l’HPC, le FPGA hanno mostrato significative potenzialità che lasciano presagire un ruolo più centrale nelle future applicazioni ad alte prestazioni, in particolare quelle che necessitano di una specializzazione spinta delle risorse di calcolo e/o di un attento bilanciamento di potenza di calcolo e consumo energetico.
_______________________________________________________________________________
Bibliografia
[1] E. Calore, and S. F. Schifano, “FER: a benchmark for the Roofline analysis of FPGA based HPC accelerators”, IEEE Access, vol. 10, 2022. doi: 10.1109/ACCESS.2022.3203566.
[2] A. Cilardo, “Evaluation of HPC Acceleration and Interconnect Technologies for High-Throughput Data Acquisition” Sensors, no. 22: 7759, 2021. doi: 10.3390/s21227759
[3] C. Zambelli, R. Bertaggia, L. Zuolo, R. Micheloni and P. Olivo, “Enabling Computational Storage Through FPGA Neural Network Accelerator for Enterprise SSD,” in IEEE Transactions on Circuits and Systems II: Express Briefs, vol. 66, no. 10, pp. 1738-1742, Oct. 2019, doi: 10.1109/TCSII.2019.2929288.