我有一台配有8个处理器的机器。我想在我的代码上使用OpenMP和MPI替代:
OpenMP阶段:
MPI阶段:
到目前为止,我已经完成了:
这一切都奏效了。排名0确实启动了8个线程,但所有线程都限制在一个处理器上。在OpenMP阶段,我从一个处理器上运行的等级0中获得8个线程,而所有其他处理器都处于空闲状态。
如何告诉MPI允许等级0使用其他处理器?我正在使用英特尔MPI,但如果需要,可以切换到OpenMPI或MPICH。
答案 0 :(得分:13)
以下代码显示了如何在OpenMP部分之前保存CPU关联掩码的示例,将其更改为在并行区域的持续时间内允许所有CPU,然后还原以前的CPU关联掩码。代码是特定于Linux的,如果您没有通过将--bind-to-core
或--bind-to-socket
传递给mpiexec
来启用MPI库的进程固定 - 已激活,则没有任何意义开放MPI;通过在英特尔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个逻辑处理器)。
答案 1 :(得分:0)
感谢大家的评论和回答。你没事。这完全取决于“PIN”选项。
要解决我的问题,我只需要:
I_MPI_WAIT_MODE = 1
I_MPI_PIN_DOMAIN = OMP
这很简单。现在所有处理器都适用于所有级别。
选项
I_MPI_DEBUG = 4
显示每个等级获得的处理器。