OpenMP 和 MPI 混合程序
Posted
技术标签:
【中文标题】OpenMP 和 MPI 混合程序【英文标题】:OpenMP and MPI hybrid program 【发布时间】:2012-10-20 02:51:00 【问题描述】:我有一台有 8 个处理器的机器。我想在我的代码上交替使用 OpenMP 和 MPI:
OpenMP 阶段:
排名 1-7 在 MPI_Barrier 上等待 rank 0 将所有 8 个处理器与 OpenMP 一起使用MPI 阶段:
rank 0 达到障碍,所有 rank 各使用一个处理器到目前为止,我已经完成了:
将 I_MPI_WAIT_MODE 设置为 1,以便 1-7 级在屏障上时不使用 CPU。 将 omp_set_num_threads(8) 设置为 0 级,以便启动 8 个 OpenMP 线程。这一切都奏效了。 Rank 0 确实启动了 8 个线程,但都仅限于一个处理器。在 OpenMP 阶段,我得到 0 级的 8 个线程在一个处理器上运行,而所有其他处理器都处于空闲状态。
如何告诉 MPI 允许 0 级处理器使用其他处理器?我正在使用 Intel MPI,但如果需要,可以切换到 OpenMPI 或 MPICH。
【问题讨论】:
我认为这应该可行。你确定没有启用固定?检查I_MPI_PIN
设置。
您肯定启用了进程固定。诀窍是,如果您禁用它,您的 MPI 进程将不再受核心约束,并且 MPI 部分的性能会降低。您可以通过编程更改 CPU 掩码 - 保存它,允许 OpenMP 阶段的所有处理器,恢复掩码。
【参考方案1】:
以下代码显示了一个示例,说明如何在 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 个逻辑处理器)。
【讨论】:
【参考方案2】:感谢大家的cmets和答案。你没事。都是关于“PIN”选项的。
为了解决我的问题,我只需要:
I_MPI_WAIT_MODE=1
I_MPI_PIN_DOMAIN=omp
就这么简单。现在所有处理器都可用于所有等级。
选项
I_MPI_DEBUG=4
显示每个等级获得的处理器。
【讨论】:
您所做的是有效地禁用进程固定 - 固定到所有可用 CPU 的进程根本没有固定。以上是关于OpenMP 和 MPI 混合程序的主要内容,如果未能解决你的问题,请参考以下文章