2012-10-30 16 views
8

Ho una macchina con 8 processori. Voglio alternare con OpenMP e MPI sul mio codice come questo: faseOpenMP e programma ibrido MPI

OpenMP:

  • ranghi 1-7 di attesa su una MPI_Barrier
  • rango 0 utilizza tutti 8 processori con OpenMP
  • fase

MPI:

  • rango 0 raggiunge barriera e tutti i ranghi utilizzare un processore ogni

Finora, ho fatto:

  • set I_MPI_WAIT_MODE 1 in modo che si colloca 1-7 non utilizzare la CPU durante il funzionamento la barriera.
  • imposta omp_set_num_threads (8) sul grado 0 in modo che avvii 8 thread OpenMP.

Ha funzionato tutto. Il grado 0 ha lanciato 8 thread, ma tutti sono limitati a un processore. Nella fase OpenMP ottengo 8 thread dalla posizione 0 in esecuzione su un processore e tutti gli altri processori sono inattivi.

Come dire a MPI di consentire al grado 0 di utilizzare gli altri processori? Sto usando Intel MPI, ma potrei passare a OpenMPI o MPICH se necessario.

+1

Penso che questo dovrebbe funzionare. Sei sicuro che il blocco non è abilitato? Controlla l'impostazione 'I_MPI_PIN'. –

+1

Sicuramente è abilitato il blocco dei processi. Il trucco è che se lo disabiliti, i tuoi processi MPI non sarebbero più legati al core e le prestazioni della parte MPI diminuirebbero. È possibile modificare la maschera della CPU in modo programmato: salvarla, consentire tutti i processori per la fase OpenMP, ripristinare la maschera. –

risposta

0

Grazie a tutti per i commenti e le risposte. Sei a posto. Si tratta dell'opzione "PIN".

per risolvere il mio problema, ho dovuto:

I_MPI_WAIT_MODE = 1

I_MPI_PIN_DOMAIN = OMP

Semplice come quello. Ora tutti i processori sono disponibili a tutti i livelli.

L'opzione

I_MPI_DEBUG = 4

mostra quali processori ciascun rango ottiene.

+1

Ciò che è stato fatto è disattivare in modo efficace il blocco dei processi: un processo bloccato su tutte le CPU disponibili non è affatto bloccato. –

13

Il seguente codice mostra un esempio su come salvare la maschera di affinità CPU prima della parte OpenMP, modificarla per consentire tutte le CPU per la durata dell'area parallela e quindi ripristinare la maschera di affinità CPU precedente. Il codice è specifico per Linux e non ha senso se non si abilita il blocco dei processi dalla libreria MPI - attivato passando da --bind-to-core a mpiexec in Open MPI; disattivato impostando I_MPI_PIN in disable in Intel MPI (l'impostazione predefinita su 4.x è di bloccare i processi).

#define _GNU_SOURCE 

#include <sched.h> 

... 

cpu_set_t *oldmask, *mask; 
size_t size; 
int nrcpus = 256; // 256 cores should be more than enough 
int i; 

// Save the old affinity mask 
oldmask = CPU_ALLOC(nrcpus); 
size = CPU_ALLOC_SIZE(nrcpus); 
CPU_ZERO_S(size, oldmask); 
if (sched_getaffinity(0, size, oldmask) == -1) { error } 

// Temporary allow running on all processors 
mask = CPU_ALLOC(nrcpus); 
for (i = 0; i < nrcpus; i++) 
    CPU_SET_S(i, size, mask); 
if (sched_setaffinity(0, size, mask) == -1) { error } 

#pragma omp parallel 
{ 
} 

CPU_FREE(mask); 

// Restore the saved affinity mask 
if (sched_setaffinity(0, size, oldmask) == -1) { error } 

CPU_FREE(oldmask); 

... 

È anche possibile modificare gli argomenti pinning del OpenMP run-time. Per GCC/libgomp l'affinità è controllata dalla variabile di ambiente GOMP_CPU_AFFINITY, mentre per i compilatori Intel è KMP_AFFINITY. È comunque possibile utilizzare il codice sopra se il runtime OpenMP interseca la maschera di affinità fornita con quella del processo.

Solo per ragioni di completezza - risparmio, impostazione e ripristinare la maschera di affinità su Windows:

#include <windows.h> 

... 

HANDLE hCurrentProc, hDupCurrentProc; 
DWORD_PTR dwpSysAffinityMask, dwpProcAffinityMask; 

// Obtain a usable handle of the current process 
hCurrentProc = GetCurrentProcess(); 
DuplicateHandle(hCurrentProc, hCurrentProc, hCurrentProc, 
       &hDupCurrentProc, 0, FALSE, DUPLICATE_SAME_ACCESS); 

// Get the old affinity mask 
GetProcessAffinityMask(hDupCurrentProc, 
         &dwpProcAffinityMask, &dwpSysAffinityMask); 

// Temporary allow running on all CPUs in the system affinity mask 
SetProcessAffinityMask(hDupCurrentProc, &dwpSysAffinityMask); 

#pragma omp parallel 
{ 
} 

// Restore the old affinity mask 
SetProcessAffinityMask(hDupCurrentProc, &dwpProcAffinityMask); 

CloseHandle(hDupCurrentProc); 

... 

dovrebbe funzionare con un singolo gruppo processore (fino a 64 processori logici).