In quali paradigmi di programmazione dovrei investire se voglio che il mio codice venga eseguito su macchine petascale in futuro?


36

Da un sondaggio sulla top500 risulta abbastanza chiaro che il settore tende a un aumento esponenziale dei core di elaborazione . I più grandi supercomputer utilizzano tutti MPI per la comunicazione tra nodi, anche se non sembra esserci una chiara tendenza al parallelismo su nodo, con l'approccio più semplice (ma non necessariamente il più efficiente) per mappare un singolo processo MPI su ciascun core, automatico parallelizzazione dal compilatore, OpenMP, pthreads, CUDA, Cilk e OpenCL.

Faccio parte di un gruppo di scienziati che mantengono e sviluppano un codice che ha il potenziale per essere utilizzato su alcuni dei più grandi supercomputer al mondo. Supponendo un tempo limitato per gli sviluppatori, come posso fare a prova di futuro per poter sfruttare le prestazioni della macchina più potente del mondo? Quali ipotesi dovrei fare sull'architettura di interconnessione dei processi? Quali paradigmi soffriranno quando entriamo nell'era manycore? Le lingue di Partitioned Global Address Space saranno disponibili "in produzione" su macchine petascale?


5
Non vedo questa domanda correttamente portata. Dalla faq, "Le tue domande dovrebbero essere ragionevolmente mirate. Se riesci a immaginare un intero libro che risponda alla tua domanda, stai chiedendo troppo." In effetti ogni conferenza di SuperComputing a cui ho partecipato ha più pannelli su questo argomento e ci sono decine di centinaia di libri dedicati a diversi paradigmi di programmazione
aterrel,


5
Sfera di cristallo non disponibile, foglie di tè si sono schiantate.
dmckee,

Risposte:


34

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


2
Bene, ma come potresti ignorare la vettorializzazione, qual è il singolo fattore più grande per le prestazioni sul nodo?
Matt Knepley,

Molto vero (lo considero davvero parte del nodo di calcolo speciale, ho appena discusso a lungo con il Dr. Bandwidth su come i venditori suggeriscono effettivamente alle persone di spegnere le unità vettoriali per i codici seriali), sto anche ignorando i sistemi di memoria, e io / o. Immagino che lo aggiungerò ora.
Aterrel,

I co-array in Fortran sono approssimativamente equivalenti a UPC?
Ondřej Čertík,

Per quanto ne so, sono gli stessi concetti, ma non ho usato ampiamente nessuna delle due librerie.
Aterrel,

Nel senso che CAF e UPC sono entrambi PGAS, sì. E nemmeno una biblioteca, tra l'altro. Ci sono molte informazioni su Internet per rispondere a questa domanda in modo più dettagliato.
Jeff,

8

Cominciamo discutendo una strategia per il codice intranode (elaborazione che non tocca l'interconnessione), poiché penso che MPI sia una buona scelta per il codice internodo. Penso che sia insensato parlare di nodi con meno di 100 core, quindi almeno una GPU o MIC corrente.

È un dato di fatto che i pthread da soli non possono ottenere le massime prestazioni su qualsiasi chip moderno, perché è necessario sfruttare l'unità vettoriale (vero dal primo Cray). Su Intel e AMD puoi usare i intrinseci, ma questi non sono portatili, e secondo me goffi. CUDA e OpenCL hanno la vettorializzazione integrata nella libreria e facilitano il raggiungimento delle massime prestazioni. Tutto il nuovo hardware di cui sono a conoscenza ha questo requisito vettoriale, quindi qualsiasi soluzione dovrebbe tenerne conto. Per me, CUDA / OpenCL è l'attuale strada da percorrere.

Successivamente, tutte queste macchine saranno NUMA, che è più difficile da programmare, ma penso che la strategia del kernel funzioni. Suddividi lavoro e dati in piccole unità. Questi saranno probabilmente programmati automaticamente, come accade attualmente in CUDA e OpenCL, ma è possibile specificare le dipendenze. Per problemi che si adattano al paradigma dello streaming, questo chunking può anche essere fatto automaticamente. Intel TBB lo fa, ma preferisco l'approccio di libreria di livello superiore esemplificato da Thrust e Cusp , che può scegliere come target CUDA o (presto) TBB.


Penso anche che l'approccio di CUDA / OpenCL abbia un futuro brillante ... ma quale prevarrà, CUDA o OpenCL? Il recente fiasco di AMD danneggerà OpenCL?
PhDP

2
Alla fine ci sarà uno standard aperto che tutti usano. Probabilmente sarà OpenCL 2.0. Per ora, CUDA è un po 'avanti, ma posso facilmente tradurre il 95% del mio codice.
Matt Knepley,

7

Proverò una risposta più breve di alcuni dei miei stimati colleghi su questo thread ;-)

Il mio messaggio a tutti i miei studenti è sempre che il tempo degli sviluppatori è più prezioso del tempo della CPU. Ciò significa che se hai tempo per convertire il 100% del codice con un'efficienza dell'80% per funzionare su grandi macchine - usando un approccio di alto livello - allora stai meglio di quando usi un basso livello che richiede tempo approccio che ti dà il 100% di efficienza sul 20% del tuo codice. Di conseguenza, sono un grande fan delle librerie di alto livello. I miei preferiti in quest'area sono i threading building block (TBB) poiché mi permettono di esaminare gli algoritmi nei loop più esterni e ad alto livello. Può anche fare tutto ciò che potresti voler fare con pthreads senza la crudeltà di dover gestire le funzioni del sistema operativo, ecc. Non sono un fan degli approcci che guardano ai cicli più interni perché è il livello sbagliato per sfruttare le risorse parallele intranode - - quindi nessun OpenMP,

Non posso parlare con autorità di OpenCL, CUDA, ecc.


4

Le risposte precedentemente pubblicate sono eccellenti, ma si sono concentrate principalmente sull'architettura del nodo, che penso rifletta il fatto che MPI è generalmente considerato sufficiente come i modelli di programmazione internodale nella maggior parte dei casi e che è il parallelismo intranode in cui lottiamo.

Ecco i miei tentativi di rispondere a due domande a cui non è stata ancora data risposta o risposta in modo relativamente limitato:

Quali ipotesi dovrei fare sull'architettura di interconnessione dei processi?

Prenderò in considerazione tre proprietà delle reti:

  1. latenza,
  2. larghezza di banda e
  3. concorrenza.

La latenza è inversamente proporzionale alla frequenza. Sappiamo che il ridimensionamento di frequenza è ristagnato. Quindi, si può concludere che è improbabile che la latenza diminuisca significativamente in futuro. La latenza invio-recv MPI su Blue Gene / Q è di circa 2 us, che corrisponde a 3200 cicli. Più della metà di tale latenza è software, ma buona parte è richiesta dallo standard MPI; un'accordatura approfondita potrebbe ridurre la latenza vicino a 1 noi, in particolare se si può affermare che i caratteri jolly MPI non verranno utilizzati.

In ogni caso, la latenza hardware per l'iniezione di pacchetti sui sistemi Blue Gene e Cray è di circa 1 us. Semmai, aumentare la concorrenza a livello di nodo rende difficile mantenere questo numero così basso, ma sono ottimista sul fatto che i progettisti hardware troveranno il modo di mantenere la latenza sotto i 5 per il prossimo futuro.

La larghezza di banda della rete è banalmente aumentata aumentando il numero di collegamenti di rete. Questa è solo una parte della storia, comunque. Uno mette 1000 collegamenti in uscita su un nodo e non può usarli se i processori non possono guidare la rete a tutta la larghezza di banda. Ad esempio, alcuni colli di bottiglia del supercomputer nel bus (ad esempio HyperTransport) anziché nella rete, in termini di larghezza di banda di iniezione.

Non ci sono limiti fondamentali alla larghezza di banda della rete, solo quelli pratici. La larghezza di banda costa denaro e potenza. I progettisti di sistemi dovranno tener conto dei compromessi tra larghezza di banda di rete e altre parti della macchina durante lo sviluppo di sistemi futuri. Molti codici non sono limitati dalla larghezza di banda della rete, quindi sembra improbabile che vedremo macchine con una larghezza di banda notevolmente maggiore per connessione in futuro. Tuttavia, la larghezza di banda per nodo dovrebbe aumentare in modo proporzionale alla potenza di calcolo, pertanto è necessario disporre di più connessioni per nodo per ridimensionare.

La terza proprietà delle reti che viene spesso trascurata nei modelli formali è il numero di messaggi che possono essere inviati una sola volta. Avere una rete con 1 ns di latenza e / o 1 TB / s di larghezza di banda che può inviare solo 1 messaggio alla volta sarebbe del tutto inutile per la maggior parte degli usi. È importante essere in grado di inviare contemporaneamente molti messaggi da molti thread e che la rete non si blocchi durante la contesa. I sistemi Cray e Blue Gene ora raggiungono oltre 1 MMPS (milioni di messaggi al secondo). Non ricordo i numeri esatti, ma entrambi sono in grado di raggiungere una frazione significativa della larghezza di banda di picco con piccoli messaggi. Una rete ideale potrebbe essere in grado di raggiungere il picco della larghezza di banda con messaggi di qualsiasi dimensione, ma ciò è impossibile in pratica a causa dell'intestazione del pacchetto e delle relative spese generali di contabilità. Tuttavia,

Questa è una risposta incompleta e imperfetta. Altri sono invitati a cercare di migliorarlo o suggerire cose che dovrei migliorare.

Le lingue di Partitioned Global Address Space saranno disponibili "in produzione" su macchine petascale?

I sistemi Cray XE, XK e XC dispongono di un compilatore UPC e CAF di qualità produttiva. I sistemi Blue Gene possono essere forniti con XLUPC e XLCAF ma nessuno lo richiede, quindi non viene consegnato. PERCS ha compilatori XLUPC e XLCAF di livello produttivo ma nessuna installazione su larga scala accessibile alla comunità scientifica.

Coarrays fa parte di Fortran 2008, sebbene le implementazioni in Intel e GNU Fortran non siano ancora di alta qualità. Si ritiene che l'implementazione Intel funzioni ma sia anche piuttosto lenta (su PGAS12 c'è un documento).

Per quanto riguarda il modello di programmazione PGAS (poiché i modelli di programmazione - non i linguaggi di programmazione - sono l'argomento della domanda originale), la libreria Global Arrays è un'approssimazione ragionevole della qualità della produzione in molti casi. Come runtime, non è robusto come MPI, ma MPI è piuttosto unico in termini di qualità delle implementazioni. L'implementazione ARMCI-MPI di ARMCI rende gli array globali molto più stabili, anche se in alcuni casi più lenti.

È relativamente facile implementare costrutti in stile PGAS in un modo di produzione di qualità usando MPI-3 RMA. Se qualcuno pubblica una nuova domanda a riguardo, sarei felice di risponderti.


4
Puoi pubblicare la domanda sull'implementazione dei costrutti in stile PGAS in MPI-3 da solo (e rispondere da solo), purché sia ​​un vero problema che hai affrontato in passato (che suppongo sia). Consentiamo agli utenti di rispondere ai propri post.
Geoff Oxberry,

1
Questa è una delle domande più frequenti su Scicomp, sono felice di avere qui la risposta di Jeff. EDIT: Capisco cosa intendi lì @GeoffOxberry - sì, dovrebbe pubblicare la sua domanda e rispondere ad essa :)
Aron Ahmadia

Ok, proverò a mettere da parte un po 'di tempo per scrivere una domanda e una risposta "Qual è la connessione tra PGAS e MPI-3 RMA" nella prossima settimana o due.
Jeff,

3

Quantità davvero enormi di core aprono anche una prospettiva banale ma sorprendentemente utile - solo per usarlo per eseguire molte iterazioni dell'intera simulazione.

Una parte significativa della ricerca computazionale al giorno d'oggi si riduce alla scansione di uno spazio di parametri, allo screening di un ampio pool di condizioni iniziali o al calcolo di una distribuzione di alcuni risultati in un modo di ricampionamento; tutti questi compiti sono imbarazzantemente paralleli, quindi a prova di Amdahl.


2

Sospetto che anche le risposte più ponderate a questa domanda saranno obsolete tra cinque e dieci anni. Data l'incertezza dei futuri paradigmi di programmazione, potrebbe non valere la pena dedicare molto tempo alla pre-ottimizzazione della base di codice.


1
È troppo fatalistico: il futuro è qui, oggi. La domanda riguarda il petascale, che è dove siamo oggi. Se non pensi a come eseguire i 100.000 processori di oggi, non farai molti progressi con i 100.000.000 di core di domani.
Wolfgang Bangerth,

1

Stavo per pubblicare questa risposta a questa domanda , ma è stata chiusa come duplicata di questa, quindi ecco qui:

Questo può sembrare un po 'solomonico, ma nella mia esperienza, il futuro appartiene ad approcci ibridi in cui diversi nodi multi-core a memoria condivisa che eseguono kernel multi-thread sono collegati tramite un paradigma di memoria distribuita come MPI.

Vi sono, tuttavia, alcuni problemi e non coinvolgono affatto l'hardware. Prima di tutto, la maggior parte dei programmatori paralleli sono fortemente investiti in codici di tipo MPI e sono molto riluttanti a essere i primi a reimplementare parti, o tutti, della loro base di codice usando un nuovo paradigma. La mancanza di persone che usano approcci di memoria condivisa porta a progressi più lenti negli algoritmi per quell'area, che rendono qualsiasi investimento ancora più inutile.

Un secondo problema è che tutti associano il parallelismo della memoria condivisa con OpenMP . Mentre OpenMP è un modo semplice e veloce per risolvere piccoli e semplici problemi su un piccolo numero di processori, è un modello di programmazione assolutamente terribile per il vero parallelismo della memoria condivisa. Sebbene tutti, ad un certo punto, abbiamo appreso una serie di paradigmi di programmazione parallela semplici ed efficienti, ad esempio pool di thread o scheduler , questi non sono facili da implementare usando OpenMP e, francamente, questo non è il tipo di parallelismo che OpenMP attira i programmatori da usare.

In sintesi, la barriera per passare da una memoria puramente distribuita a un paradigma di memoria puramente / parzialmente condivisa è piuttosto elevata. Se si desidera utilizzare i thread in modo efficiente, è necessario dimenticare OpenMP e gestire i thread e la concorrenza da soli (ciao pthreads , arrivederci Fortran).

Ma perché passare a un approccio ibrido? Bene, sebbene MPI si ridimensioni a migliaia di core, il modello sottostante è uno di sincronia a blocchi e modelli di comunicazione statica. Questo è utile per alcuni problemi, ad es. Simulazioni di miliardi di particelle, ma non ottimale per problemi più difficili o più precisi. I paradigmi di memoria condivisa rendono molto più semplice il bilanciamento del carico dinamico e / o la comunicazione asincrona, ma fare ciò comporta un notevole sforzo di programmazione.


1
Concordo sul fatto che OpenMP sia un terribile paradigma e stia facendo un grosso disservizio alla comunità. Ma allo stesso tempo non è vero che l'alternativa è gestire da soli thread, pool di thread, code di lavoro, ecc. Ci sono in realtà ottime librerie che fanno esattamente questo per te. I blocchi di threading Intel sono i più notevoli. L'abbiamo usato per anni sotto il cofano.II e funziona abbastanza bene.
Wolfgang Bangerth,

Hmm, stavo cercando un'applicazione o una libreria robusta che utilizza TBB per verificare che la nostra implementazione BG funzioni. Ho trovato solo cise.ufl.edu/research/sparse/SPQR in precedenza. C'è qualche possibilità che tu provi a eseguire deal.II su BGP o BGQ usando wiki.alcf.anl.gov/parts/index.php/BlueTBB se fornisco l'allocazione?
Jeff,

@WolfgangBangerth: solo innescando un heads-up per te, poiché credo sia per questo che il commento di Jeff era destinato. Anche se non mi dispiacerebbe accedere a un BlueGene da solo;)
Pedro

@Jeff: sarei disposto a provarlo, ma probabilmente non sarò in grado di dedicare una terribile quantità di tempo. Sentiti libero di contattarmi offline. (@Pedro: grazie per il testa a testa!)
Wolfgang Bangerth,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.