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).
Myślę, że to powinno działać. Czy na pewno przypinanie nie jest włączone? Sprawdź ustawienie 'I_MPI_PIN'. –
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ę. –