以下代碼顯示瞭如何在OpenMP部件之前保存CPU親和性掩碼的示例,將其更改爲允許並行區域持續時間內的所有CPU,然後恢復以前的CPU關聯掩碼。該代碼是Linux專用的,如果您未啓用MPI庫的進程鎖定 - ,則通過在Open MPI中傳遞--bind-to-core
或--bind-to-socket
至mpiexec
來激活是沒有意義的; 通過在Intel MPI中將I_MPI_PIN
設置爲disable
來取消激活(4.x上的默認設置爲引腳進程)。
#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);
...
您也可以調整的OpenMP的運行時的釘扎參數。對於GCC/libgomp
,親和力由GOMP_CPU_AFFINITY環境變量控制,而對於英特爾編譯器,則爲KMP_AFFINITY。如果OpenMP運行時將所提供的親和性掩碼與進程的親緣性掩碼相交,則仍然可以使用上面的代碼。
只是爲了完整起見 - 節省,設置和恢復在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);
...
應具有單個處理器的工作組(多達64個邏輯處理器)。
我認爲這應該只是工作。你確定固定沒有啓用?檢查'I_MPI_PIN'設置。 –
當然你已經啓用了進程鎖定。訣竅是,如果你禁用它,你的MPI過程將不再是核心約束,並且MPI部分的性能會下降。您可以通過編程方式更改CPU掩碼 - 保存它,允許OpenMP階段的所有處理器恢復掩碼。 –