我有8个处理器的机器。 我想用OpenMP和MPI对我这样的代码交替:
OpenMP的阶段:
- 排名在MPI_Barrier 1-7等待
- 等级0使用的所有8个处理器使用OpenMP
杂志阶段:
到目前为止,我已经做了:
- 设置I_MPI_WAIT_MODE 1,使居1-7不使用CPU,而在屏障。
- 设定等级0 OMP_SET_NUM_THREADS(8),使得它发射8个OpenMP的线程。
它的所有工作。 等级0没有推出8个线程,但都仅限于一个处理器。 关于OpenMP阶段我得到一个处理器上运行,从等级0 8个线程和所有其他处理器处于空闲状态。
我如何告诉MPI允许等级0使用其它处理器? 我使用英特尔MPI,但如果需要,可以切换到的openmpi或MPICH。
下面的代码说明了如何OpenMP的部分之前保存CPU亲和力掩码,改变它,以允许并行区域的持续时间的所有CPU,然后恢复以前的CPU亲和力掩模的例子。 该代码是Linux特有的,它是没有意义的,如果你不能够通过MPI库的过程中钉扎-通过将激活 --bind-to-core
或--bind-to-socket
到mpiexec
开放MPI; 通过设置停用 I_MPI_PIN
到disable
在英特尔MPI(上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个逻辑处理器)。
感谢所有的意见和解答。 你都没事。 这是所有关于“PIN”选项。
为了解决我的问题,我必须:
I_MPI_WAIT_MODE = 1
I_MPI_PIN_DOMAIN = OMP
就那么简单。 现在,所有的处理器都可以对所有的行列。
选项
I_MPI_DEBUG = 4
显示了处理器每个等级获得。