【问题标题】:MPI & pthreads: nodes with different numbers of coresMPI & pthreads:不同核数的节点
【发布时间】:2014-11-03 12:40:12
【问题描述】:

简介

我想编写一个混合 MPI/pthreads 代码。我的目标是在每个节点上启动一个 MPI 进程,并将这些进程中的每一个拆分为多个线程,这些线程将真正完成这项工作,但通信只发生在单独的 MPI 进程之间。

有很多教程描述了这种情况,称为混合编程,但它们通常假设同构集群。但是,我使用的是异构节点:它们具有不同的处理器和不同数量的内核,即节点是 4/8/12/16 内核机器的组合。

我知道在这个集群上运行 MPI 进程会使我的代码减慢到使用的最慢 CPU 的速度;我接受这个事实。有了这个,我想回答我的问题。

有没有一种方法可以启动 N 个 MPI 进程(每个节点一个 MPI 进程)并让每个进程都知道该节点有多少物理内核可用?

我可以访问的 MPI 实现是 OpenMPI。这些节点混合了 Intel 和 AMD CPU。我想过使用一个机器文件,每个节点都指定为一个插槽,然后在本地计算出内核数。但是,there seem to be problems with doing that。我肯定不是第一个遇到这个问题的人,但是以某种方式搜索网络并没有为我指明正确的方向。除了给自己找一个同构的集群之外,有没有解决这个问题的标准方法?

【问题讨论】:

  • 你当然可以这样做,尽管除非你的任务接近于令人尴尬的并行(在这种情况下 MPI+Pthreads 是多余的),由此产生的负载平衡噩梦可能意味着你的加速将非常有限。获得线程数的最简单和最便携的方法可能是使用 OpenMP 支持进行编译,即使您打算使用 Pthreads,也只需调用 omp_get_num_procs()

标签: multithreading pthreads mpi


【解决方案1】:

使用 Open MPI 只为每个节点启动一个进程非常简单:

mpiexec -pernode ./mympiprogram

-pernode 参数等效于-npernode 1,它指示 ORTE 启动器为主机列表中存在的每个节点启动一个进程。这种方法的优点是无论实际主机列表如何提供,它都可以工作,即,当它来自与某些资源管理器(例如 Torque/PBS、SGE、LSF、SLURM 等)的紧密耦合和手动提供时都可以工作主机。即使主机列表包含具有多个插槽的节点,它也可以工作。

了解内核数量有点棘手,而且非常特定于操作系统。但是 Open MPI 附带了 hwloc library,它提供了一个抽象 API 来查询系统组件,包括内核数量:

hwloc_topology_t topology;

/* Allocate and initialize topology object. */
hwloc_topology_init(&topology);

/* Perform the topology detection. */
hwloc_topology_load(topology);

/* Get the number of cores */
unsigned nbcores = hwloc_get_nbobjs_by_type(topology, HWLOC_OBJ_CORE);

/* Destroy topology object. */
hwloc_topology_destroy(topology);

如果您想让工作中的每个 MPI 进程都可以使用集群中的核心数量,您需要一个简单的MPI_Allgather

/* Obtain the number or MPI processes in the job */
int nranks;
MPI_Comm_size(MPI_COMM_WORLD, &nranks);

unsigned cores[nranks];
MPI_Allgather(&nbcores, 1, MPI_UNSIGNED,
              cores, 1, MPI_UNSIGNED, MPI_COMM_WORLD);

【讨论】:

    猜你喜欢
    • 2018-04-20
    • 2018-02-25
    • 2012-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    相关资源
    最近更新 更多