Prospettiva storica
È davvero impossibile dire come saranno i nuovi paradigmi in futuro, ad esempio una buona prospettiva storica che suggerisco di leggere Rise and Fall of HPF di Ken Kennedy . Kennedy fornisce un resoconto di due modelli emergenti, MPI rispetto a un compilatore intelligente, e illustra in dettaglio come MPI avesse la giusta quantità di early adopters e flessibilità per dominare. Alla fine HPF ha risolto i suoi problemi ma era troppo tardi.
In molti modi, diversi paradigmi, come PGAS e OpenMP, stanno seguendo lo stesso trend HPF. I primi codici non sono stati abbastanza flessibili da usare bene e hanno lasciato molte prestazioni sul tavolo. Ma la promessa di non dover scrivere ogni iota dell'algoritmo parallelo è un obiettivo interessante. Quindi la ricerca di nuovi modelli è sempre perseguita.
Chiare tendenze nell'hardware
Ora il successo di MPI è stato spesso citato come strettamente legato al modo in cui modella l'hardware su cui gira. All'incirca ogni nodo ha un numero limitato di processi e il passaggio dei messaggi a un punto locale locale o tramite operazioni collettive coordinate è facilmente eseguibile nello spazio del cluster. Per questo motivo , non mi fido di nessuno che dia un paradigma che non segue da vicino le nuove tendenze hardware, in realtà ero convinto di questa opinione dal lavoro di Vivak Sarakar .
In linea con ciò, ecco tre tendenze che stanno chiaramente facendo progressi nelle nuove architetture. E vorrei essere chiaro, ora ci sono dodici diverse architetture commercializzate in HPC. Questo da meno di 5 anni fa con solo x86, quindi i prossimi giorni vedranno molte opportunità di usare l'hardware in modi diversi e interessanti
- Chip per usi speciali: pensa a grandi unità vettoriali come acceleratori (vista promossa da Bill Dally di Nvidia)
- Chip a bassa potenza: cluster basati su ARM (per adattarsi ai budget di potenza)
- Tiling of Chips: pensa alla piastrellatura dei chip con diverse specifiche (lavoro di Avant Argwal )
Modelli attuali
Il modello attuale ha in realtà 3 livelli di profondità. Mentre ci sono molti codici che usano bene due di questi livelli, non molti sono emersi usando tutti e tre. Credo che per arrivare all'exascale sia necessario investire nel determinare se il codice può essere eseguito a tutti e tre i livelli. Questo è probabilmente il percorso più sicuro per seguire bene le tendenze attuali.
Consentitemi di ripetere i modelli e come dovranno cambiare in base alle nuove visualizzazioni hardware previste.
distribuito
I giocatori a livello distribuito ricadono in gran parte nelle lingue MPI e PGAS. MPI è un chiaro vincitore in questo momento, ma i linguaggi PGAS come UPC e Chapel stanno facendo progressi nello spazio. Una buona indicazione è la sfida HPC Benchmark. I linguaggi PGAS stanno dando implementazioni molto eleganti dei parametri di riferimento.
Il punto più interessante qui è che mentre questo modello attualmente funziona solo a livello di nodo, sarà un modello importante all'interno di un nodo per architetture piastrellate. Un'indicazione è il chip Intel SCC, che fondamentalmente ha funzionato come un sistema distribuito. Il team SCC ha creato la propria implementazione MPI e molti team hanno avuto successo nel portare le librerie della comunità su questa architettura.
Ma ad essere sincero PGAS ha davvero una buona storia per entrare in questo spazio. Vuoi davvero programmare l'internodo MPI e poi fare lo stesso trucco intranode? Un grosso problema con queste architetture piastrellate è che avranno diverse velocità di clock sui chip e grandi differenze nella larghezza di banda rispetto alla memoria, quindi i codici performanti devono tenerne conto.
Memoria condivisa su nodo
Qui vediamo MPI spesso essere "abbastanza buono", ma PThreads (e librerie derivanti da PThreads come Intel Parallel Building Blocks) e OpenMP sono ancora usati spesso. L'idea comune è che ci sarà un tempo in cui ci sono abbastanza thread di memoria condivisa che il modello di socket MPI si romperà per RPC o è necessario un processo più leggero in esecuzione sul core. Già puoi vedere le indicazioni dei sistemi IBM Bluegene che hanno problemi con la memoria condivisa MPI.
Come commenta Matt, il più grande aumento delle prestazioni per i codici ad alta intensità di calcolo è la vettorializzazione del codice seriale. Mentre molte persone credono che ciò sia vero negli acceleratori, è anche fondamentale per le macchine on-node. Credo che Westmere abbia 4 FPU di larghezza, quindi si può ottenere solo un quarto dei flop senza vettorializzazione.
Mentre non vedo l'attuale OpenMP entrare in questo spazio, c'è un posto per chip a bassa potenza o piastrelle per usare più fili leggeri. OpenMP ha difficoltà a descrivere come funziona il flusso di dati e man mano che vengono utilizzati più thread, vedo solo questa tendenza diventare più esagerata, basta guardare esempi di cosa si deve fare per ottenere il prefetching corretto con OpenMP.
Sia OpenMP che PThreads a un livello sufficientemente ampio possono trarre vantaggio dalla vettorializzazione necessaria per ottenere una buona percentuale di picco, ma per farlo è necessario abbattere gli algoritmi in modo tale che la vettorizzazione sia naturale.
Coprocessore
Alla fine è emersa l'emergenza del coprocessore (GPU, MIC, acceleratori di celle). Sta diventando chiaro che nessun percorso verso l'exascale sarà completo senza di loro. A SC11, ogni concorrente del premio Bell li ha usati in modo molto efficace per raggiungere i petaflop bassi. Mentre CUDA e OpenCL hanno dominato il mercato attuale, spero che i compilatori OpenACC e PGAS entrino nello spazio.
Ora per arrivare all'exascale, una proposta è quella di accoppiare i chip a bassa potenza a molti coprocessori. Questo eliminerà abbastanza bene lo strato intermedio dello stack corrente e utilizzerà codici che gestiscono i problemi di decisione sul chip principale e trasferiscono il lavoro ai coprocessori. Ciò significa che affinché il codice funzioni in modo abbastanza efficace una persona deve ripensare gli algoritmi in termini di kernel (o codelet), ovvero frammenti paralleli a livello di istruzione senza rami. Per quanto ne so, una soluzione a questa evoluzione è piuttosto aperta.
In che modo ciò influisce sullo sviluppatore dell'app
Ora per arrivare alla tua domanda. Se vuoi proteggerti dalle complessità imminenti delle macchine exascale, dovresti fare alcune cose:
- Sviluppa i tuoi algoritmi per adattarli ad almeno tre livelli di gerarchia parallela.
- Progetta i tuoi algoritmi in termini di kernel che possono essere spostati tra l'erarchia.
- Rilassa la tua necessità di eventuali processi sequenziali, tutti questi effetti avverranno in modo asincrono perché l'esecuzione sincrona non è proprio possibile.
Se vuoi esibirti oggi, MPI + CUDA / OpenCL è abbastanza buono ma UPC ci sta arrivando, quindi non è una cattiva idea impiegare qualche giorno e impararlo. OpenMP ti avvia, ma causa problemi una volta che il codice deve essere sottoposto a refactoring. PThreads richiede di riscrivere completamente il codice nel suo stile. Il che rende MPI + CUDA / OpenCL il miglior modello attuale.
Ciò che non è discusso qui
Mentre tutto questo parlare di exascale è bello, qualcosa di non discusso qui è far entrare e uscire i dati dalle macchine. Mentre ci sono stati molti progressi nei sistemi di memoria, non li vediamo nel cluster di prodotti (semplicemente troppo dannatamente costoso). Ora che il computing ad alta intensità di dati sta diventando un grande obiettivo di tutte le conferenze di super computing, è inevitabile che si verifichi un movimento più ampio nello spazio ad alta larghezza di banda di memoria.
Questo porta all'altra tendenza che potrebbe accadere (se fossero coinvolte le giuste agenzie di finanziamento). Le macchine diventeranno sempre più specializzate per il tipo di elaborazione richiesta. Vediamo già macchine "ad alta intensità di dati" finanziate da NSF, ma queste macchine sono su una pista diversa rispetto all'Exascale Grand Challenge del 2019.
Questo è diventato più lungo del previsto, chiedere riferimenti dove è necessario nei commenti