Perché MPI è considerato più difficile della memoria condivisa ed Erlang è considerato più semplice, quando entrambi trasmettono messaggi?

StackOverflow https://stackoverflow.com/questions/185444

Domanda

Oggigiorno c'è molto interesse in Erlang come lingua per scrivere programmi paralleli su multicore. Ho sentito gente affermare che il modello di passaggio dei messaggi di Erlang è più facile da programmare rispetto ai modelli dominanti di memoria condivisa come i thread.

Al contrario, nella comunità informatica ad alte prestazioni il modello di programmazione parallela dominante è stato MPI, che implementa anche un modello di passaggio di messaggi. Ma nel mondo HPC, questo modello di trasmissione di messaggi è generalmente considerato molto difficile da programmare e le persone sostengono che i modelli di memoria condivisa come OpenMP o UPC sono più facili da programmare.

Qualcuno sa perché c'è una tale differenza nella percezione del passaggio di messaggi rispetto alla memoria condivisa nei mondi IT e HPC? È a causa di alcune differenze fondamentali nel modo in cui Erlang e MPI implementano il passaggio di messaggi che rende il passaggio di messaggi in stile Erlang molto più semplice di MPI? O c'è qualche altra ragione?

È stato utile?

Soluzione

Sono d'accordo con tutte le risposte precedenti, ma penso che un punto chiave che non sia stato chiarito completamente sia che uno dei motivi per cui MPI potrebbe essere considerato difficile ed Erlang facile è la corrispondenza del modello con il dominio.

Erlang si basa su un concetto di memoria locale, passaggio di messaggi asincroni e stato condiviso risolto utilizzando una qualche forma di database globale a cui tutti i thread possono accedere. È progettato per applicazioni che non spostano molti dati in giro e che non dovrebbero esplodere in nodi separati da 100k che necessitano di coordinamento.

L'MPI si basa sulla memoria locale e sul passaggio dei messaggi ed è destinato a problemi in cui lo spostamento dei dati è una parte fondamentale del dominio. L'elaborazione ad alte prestazioni si basa principalmente sul prendere il set di dati per un problema e suddividerlo in una serie di risorse di calcolo. E questo è un lavoro piuttosto duro in un sistema di passaggio di messaggi poiché i dati devono essere esplicitamente distribuiti tenendo presente il bilanciamento. In sostanza, MPI può essere visto come un'ammissione rudimentale che la memoria condivisa non scala. E si rivolge a calcoli ad alte prestazioni distribuiti su oltre 100.000 processori.

Erlang non sta cercando di ottenere le massime prestazioni possibili, piuttosto di scomporre un problema naturalmente parallelo nei suoi thread naturali. È stato progettato pensando a un tipo di attività di programmazione completamente diverso rispetto a MPI.

Quindi Erlang è meglio confrontato con pthreads e altre soluzioni di thread eterogenei piuttosto locali, piuttosto che MPI che è realmente mirato a un set di problemi molto diverso (e in qualche misura intrinsecamente più difficile).

Altri suggerimenti

Il parallelismo in Erlang è ancora piuttosto difficile da implementare. Con ciò voglio dire che devi ancora capire come dividere il tuo problema, ma ci sono alcune cose minori che alleviano questa difficoltà rispetto ad alcune librerie MPI in C o C ++.

In primo luogo, poiché il passaggio di messaggi di Erlang è una caratteristica del linguaggio di prima classe, lo zucchero sintattico lo rende più facile.

Inoltre, le librerie di Erlang sono tutte costruite attorno al passaggio del messaggio di Erlang. Questa struttura di supporto ti aiuta a dare impulso a terreni a processamento parallelo. Dai un'occhiata ai componenti di OTP come gen_server, gen_fsm, gen_event. Queste sono strutture molto facili da usare che possono aiutare il tuo programma a diventare parallelo.

Penso che sia più la solidità della libreria standard disponibile che differenzia il messaggio di erlang passando da altre implementazioni MPI, non proprio alcuna caratteristica specifica del linguaggio stesso.

Di solito la concorrenza in HPC significa lavorare su grandi quantità di dati. Questo tipo di parallelismo è chiamato parallelismo dei dati ed è davvero più facile da implementare usando un approccio di memoria condivisa come OpenMP , poiché il sistema operativo si occupa di cose come la pianificazione e il posizionamento delle attività, che si dovrebbe implementare se si utilizza un paradigma di passaggio di messaggi.

Al contrario, Erlang è stato progettato per far fronte al parallelismo delle attività riscontrato nei sistemi telefonici, dove diversi pezzi di codice devono essere eseguiti contemporaneamente con solo una quantità limitata di comunicazione e forti requisiti di tolleranza agli errori e recupero.

Questo modello è simile a quello per cui la maggior parte delle persone usa PThreads. Si adatta ad applicazioni come i server Web, in cui ogni richiesta può essere gestita da un thread diverso, mentre le applicazioni HPC fanno praticamente la stessa cosa su enormi quantità di dati che devono anche essere scambiati tra lavoratori.

Penso che abbia qualcosa a che fare con la mentalità quando stai programmando con MPI e quando stai programmando con Erlang. Ad esempio, MPI non è integrato nella lingua mentre Erlang ha il supporto integrato per il passaggio dei messaggi. Un'altra possibile ragione è la disconnessione tra mera invio / ricezione di messaggi e soluzioni di partizionamento in unità di esecuzione simultanee.

Con Erlang sei costretto a pensare in una cornice di programmazione funzionale in cui i dati si comprimono effettivamente dalla chiamata di funzione alla chiamata di funzione - e la ricezione è un atto attivo che assomiglia a un normale costrutto nel linguaggio. Questo ti dà una connessione più stretta tra il calcolo che stai effettivamente eseguendo e l'atto di inviare / ricevere messaggi.

Con MPI, d'altra parte, sei costretto a pensare semplicemente al passaggio del messaggio, ma non alla decomposizione del lavoro. Questo schema di pensiero richiede in qualche modo un cambio di contesto tra la scrittura della soluzione e l'infrastruttura di messaggistica nel codice.

La discussione può continuare ma l'opinione comune è che se il costrutto per il passaggio dei messaggi è effettivamente incorporato nel linguaggio di programmazione e nel paradigma che stai usando, di solito è un modo migliore per esprimere la soluzione rispetto a qualcos'altro che è "virato su" o esiste come componente aggiuntivo di una lingua (sotto forma di libreria o estensione).

  

Qualcuno sa perché c'è una tale differenza nella percezione del passaggio di messaggi rispetto alla memoria condivisa nei mondi IT e HPC? È a causa di alcune differenze fondamentali nel modo in cui Erlang e MPI implementano il passaggio di messaggi che rende il passaggio di messaggi in stile Erlang molto più semplice di MPI? O c'è qualche altro motivo?

Il motivo è semplicemente il parallelismo contro la concorrenza. Erlang è allevato per la programmazione concorrente. HPC si basa sulla programmazione parallela. Questi sono obiettivi correlati ma diversi.

La programmazione concorrente è notevolmente complicata da un flusso di controllo fortemente non deterministico e la latenza è spesso un obiettivo importante. L'uso da parte di Erlang di strutture di dati immutabili semplifica notevolmente la programmazione concorrente.

La programmazione parallela ha un flusso di controllo molto più semplice e l'obiettivo è tutto il throughput totale massimo e non la latenza. L'uso efficiente della cache è molto più importante qui, il che rende sia Erlang che le strutture di dati immutabili in gran parte inadatte. La mutazione della memoria condivisa è trattabile e sostanzialmente migliore in questo contesto. In effetti, la coerenza della cache fornisce messaggi con accelerazione hardware per te.

Infine, oltre a queste differenze tecniche, esiste anche una questione politica. I ragazzi di Erlang stanno cercando di cavalcare l'hype multicore fingendo che Erlang sia rilevante per il multicore quando non lo è. In particolare, stanno propagandando una grande scalabilità, quindi è essenziale considerare anche le prestazioni assolute. Erlang passa facilmente da scarse prestazioni assolute su un core a scarse prestazioni assolute su un numero qualsiasi di core. Come puoi immaginare, ciò non impressiona la comunità HPC (ma è adeguata per un sacco di codice fortemente concorrente).

Riguardo a MPI vs OpenMP / UPC: MPI ti costringe a tagliare il problema in piccoli pezzi e assumersi la responsabilità di spostare i dati. Con OpenMP / UPC, "tutti i dati sono presenti", devi solo dereferenziare un puntatore. Il vantaggio di MPI è che i cluster di CPU 32-512 sono molto più economici delle macchine singole 32-512 CPU. Inoltre, con MPI la spesa è anticipata, quando si progetta l'algoritmo. OpenMP / UPC può nascondere le latenze che otterrai in fase di esecuzione, se il tuo sistema utilizza NUMA (e tutti i grandi sistemi lo fanno) - il tuo programma non si ridimensionerà e ci vorrà del tempo per capire perché.

Questo articolo in realtà lo spiega bene, Erlang è il migliore quando inviamo piccoli frammenti di dati in giro e MPI fa molto meglio su cose più complesse. Anche il modello Erlang è facile da capire :-)

Erlang Versus MPI - Risultati finali e codice sorgente

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top