10

Ho un po 'di domande relative alla ricerca.cosa significa configurare MPI per la memoria condivisa?

Attualmente ho terminato l'implementazione del lavoro di struttura scheletro struttura basato su MPI (in particolare utilizzando openmpi 6.3). il lavoro del telaio dovrebbe essere usato su una singola macchina. ora, mi sto confrontando con altre implementazioni scheletro precedenti (come scandium, fast-flow, ..)

Una cosa che ho notato è che la prestazione della mia implementazione non è buono come le altre implementazioni. Penso che questo sia dovuto al fatto che la mia implementazione è basata su MPI (quindi una comunicazione su due lati che richiede la corrispondenza tra invio e ricezione) mentre le altre implementazioni con cui sto confrontando si basano sulla memoria condivisa. (... ma ancora non ho una buona spiegazione per ragionare, ed è parte della mia domanda)

Ci sono alcune grandi differenze nei tempi di completamento delle due categorie.

Oggi sto anche introdotto per la configurazione di open-MPI per la memoria condivisa qui =>openmpi-sm

e ci vengo arriva la mia domanda.

1st cosa significa configurare MPI per la memoria condivisa? Intendo mentre i processi MPI vivono nella loro memoria virtuale; che cosa è veramente la bandiera come nel seguente comando? (Ho pensato che in MPI ogni comunicazione passasse esplicitamente un messaggio, nessuna memoria è condivisa tra i processi).

shell$ mpirun --mca btl self,sm,tcp -np 16 ./a.out 

secondo perché è la performance del MPI è molto peggio con rispetto ad altre implementazioni scheletro sviluppato per la memoria condivisa? Almeno lo sto eseguendo anche su una singola macchina multi-core. (Suppongo che sia perché l'altra implementazione ha usato la programmazione parallela dei thread, ma non ho una spiegazione convincente per quello).

qualsiasi suggerimento o ulteriore discussione è molto gradito.

Per favore fatemi sapere se devo chiarire ulteriormente la mia domanda.

grazie per il vostro tempo!

risposta

11

Open MPI è molto modulare. Ha un proprio modello di componente chiamato Modular Component Architecture (MCA). Da qui viene il nome del parametro --mca, che viene utilizzato per fornire i valori di runtime ai parametri MCA, esportati dai diversi componenti nell'MCA.

Ogni volta che due processi in un determinato comunicatore vogliono parlare tra loro, MCA trova componenti adatti, in grado di trasmettere messaggi da un processo all'altro. Se entrambi i processi risiedono sullo stesso nodo, Open MPI di solito preleva il componente BTL della memoria condivisa, noto come sm. Se entrambi i processi risiedono su nodi diversi, Open MPI percorre le interfacce di rete disponibili e sceglie quella più veloce che può connettersi all'altro nodo. Mette alcune preferenze su reti veloci come InfiniBand (tramite il componente BTL openib), ma se il tuo cluster non ha InfiniBand, TCP/IP viene usato come fallback se il componente tcp BTL è nell'elenco dei BTL consentiti.

Per impostazione predefinita, non è necessario fare qualcosa di speciale per abilitare la comunicazione con memoria condivisa. Basta avviare il programma con mpiexec -np 16 ./a.out. Quello a cui si è collegati è la parte di memoria condivisa delle FAQ Open MPI che fornisce suggerimenti su quali parametri del BTL sm potrebbero essere modificati per ottenere prestazioni migliori. La mia esperienza con Open MPI mostra che i parametri predefiniti sono quasi ottimali e funzionano molto bene, anche su hardware esotici come i sistemi multilivello NUMA. Si noti che l'implementazione della comunicazione della memoria condivisa predefinita copia i dati due volte, una volta dal buffer di invio alla memoria condivisa e una volta dalla memoria condivisa al buffer di ricezione. Esiste una scorciatoia sotto forma di dispositivo del kernel KNEM, ma devi scaricarlo e compilarlo separatamente poiché non fa parte del kernel standard di Linux. Con il supporto di KNEM, Open MPI è in grado di eseguire trasferimenti "a zero copie" tra processi sullo stesso nodo - la copia viene eseguita dal dispositivo del kernel ed è una copia diretta dalla memoria del primo processo alla memoria del secondo processi. Questo migliora notevolmente il trasferimento di messaggi di grandi dimensioni tra processi che risiedono sullo stesso nodo.

Un'altra opzione è quella di dimenticare completamente MPI e utilizzare direttamente la memoria condivisa. È possibile utilizzare l'interfaccia di gestione della memoria POSIX (vedere here) per creare un blocco di memoria condiviso se tutti i processi operano direttamente su di esso. Se i dati sono archiviati nella memoria condivisa, potrebbe essere utile in quanto non verranno effettuate copie. Ma attenzione ai problemi NUMA sui moderni sistemi multi-socket, in cui ogni socket ha il proprio controller di memoria e l'accesso alla memoria da socket remoti sulla stessa scheda è più lento. Importante è anche il pinning/binding del processo: passare da --bind-to-socket a mpiexec per fare in modo che ogni processo MPI venga eseguito su un core CPU separato.

+1

FWIW, come di Linux 3.2, ci sono le sbrigie process_vm_readv/writev, che hanno approssimativamente lo stesso di KNEM. Vedi per es. http://man7.org/linux/man-pages/man2/process_vm_readv.2.html – janneb

+0

@janneb, grazie per averlo indicato, ma i kernel 3.x non sono molto popolari con la maggior parte dei sistemi di produzione HPC ora. Tuttavia, KNEM fornisce molto più di semplici trasferimenti di dati, ad es. operazioni asincrone, notifiche di completamento, ecc. –

+0

Questo è vero, ma anche in questo caso, nemmeno i kernel hanno la patch KNEM. – janneb