2012-10-30 23 views
8

Mam maszynę z 8 procesorami. Chcę przełączać przy użyciu OpenMP i MPI w moim kodu: fazyProgram hybrydowy OpenMP i MPI

OpenMP:

  • szeregach 1-7 czekać na MPI_Barrier
  • PageRank 0 wykorzystuje wszystkie procesory 8 z OpenMP

MPI etap:

  • Ranking 0 osiągnie barierę i wszystkie szeregi wykorzystywać jeden procesor każdy

tej pory zrobiłem:

  • zestaw I_MPI_WAIT_MODE 1 tak, że zajmuje 1-7 nie używać procesora podczas bariera.
  • ustaw omp_set_num_threads (8) na pozycji 0, aby uruchomić 8 wątków OpenMP.

Wszystko zadziałało. Pozycja 0 uruchomiła 8 wątków, ale wszystkie są ograniczone do jednego procesora. W fazie OpenMP otrzymuję 8 wątków z poziomu 0 działających na jednym procesorze i wszystkie inne procesory są bezczynne.

W jaki sposób mogę powiedzieć MPI, aby umożliwić 0 innym procesorom? Używam Intel MPI, ale w razie potrzeby mogę przełączyć się na OpenMPI lub MPICH.

+1

Myślę, że to powinno działać. Czy na pewno przypinanie nie jest włączone? Sprawdź ustawienie 'I_MPI_PIN'. –

+1

Zdecydowanie masz włączone przypinanie procesów. Sztuczka polega na tym, że jeśli ją wyłączysz, twoje procesy MPI nie będą już związane z rdzeniem, a wydajność części MPI będzie się zmniejszać. Możesz zmienić programowo maskę procesora - zapisz ją, pozwól wszystkim procesorom na fazę OpenMP, przywróć maskę. –

Odpowiedz

0

Dziękuję wszystkim za uwagi i odpowiedzi. Wszystko w porządku. Chodzi o opcję "PIN".

Aby rozwiązać mój problem, po prostu musiałem:

I_MPI_WAIT_MODE = 1

I_MPI_PIN_DOMAIN = omp

proste. Teraz wszystkie procesory są dostępne dla wszystkich rang.

Opcja

I_MPI_DEBUG = 4

pokazy, które procesory każdy stopień wystąpią.

+1

To co zrobiłeś, to skutecznie wyłączyć przypinanie procesów - proces przypięty do wszystkich dostępnych procesorów nie jest w ogóle przypięty. –

13

Poniższy kod przedstawia przykład zapisywania maski koligacji procesora przed częścią OpenMP, zmień ją, aby umożliwić wszystkim procesorom na czas trwania regionu równoległego, a następnie przywrócić poprzednią maskę koligacji procesora. Kod jest specyficzny dla systemu Linux i nie ma sensu, jeśli nie włączono przypinania procesu przez bibliotekę MPI - aktywowane przez przekazanie --bind-to-core lub --bind-to-socket do mpiexec w Open MPI; dezaktywowane przez ustawienie I_MPI_PIN na disable w Intel MPI (domyślnie na 4.x jest przypinanie procesów).

#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); 

... 

Można również dostrajać przypinanie argumenty okresie czasu OpenMP. Dla GCC/libgomp powinowactwo jest kontrolowane przez zmienną środowiskową GOMP_CPU_AFFINITY, natomiast dla kompilatorów Intel jest to KMP_AFFINITY. Nadal możesz użyć powyższego kodu, jeśli czas działania OpenMP przecina podaną maskę koligacji z maską procesu.

Tylko dla kompletności wywodu - oszczędność, ustawienie i przywracającej maskę powinowactwa na oknach:

#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); 

... 

powinny pracować z jednym procesorem grupy (do 64 procesorów logicznych).