C++ MPI,使用多个节点,首先在节点级别减少,然后减少到头节点

C++ MPI, using multiple node, first reduce at node level, then reduce to the head node

我使用 12 个节点 windows HPC 集群(每个节点有 24 个核心)来 运行 一个 C++ MPI 程序(使用 Boost MPI)。一个 运行 使用 MPI reduce,一个注释掉 MPI reduce(仅用于速度测试)。 运行时间是01:17:23和01:03:49。在我看来,MPI reduce 需要花费大量时间。我认为可能值得尝试先在节点级别减少,然后减少到头节点以提高性能。

下面是一个简单的例子用于测试。假设有 4 个计算机节点,每个节点有 2 个核心。我想首先使用 mpi 来减少每个节点。之后,减少到头节点。我对mpi不太熟悉,下面的程序崩溃了。

#include <iostream>
#include <boost/mpi.hpp>
namespace mpi = boost::mpi;
using namespace std;

int main()
{
  mpi::environment env;
  mpi::communicator world;

  int i = world.rank();


  boost::mpi::communicator local = world.split(world.rank()/2); // total 8 cores, divide in 4 groups
  boost::mpi::communicator heads = world.split(world.rank()%4);

  int res = 0;

  boost::mpi::reduce(local, i, res, std::plus<int>(), 0);
  if(world.rank()%2==0)
  cout<<res<<endl;
  boost::mpi::reduce(heads, res, res, std::plus<int>(), 0);

  if(world.rank()==0)
      cout<<res<<endl;

  return 0;
}

输出难以辨认,像这样

Z
h
h
h
h
a
a
a
a
n
n
n
n
g
g
g
g
\
\
\
\
b
b
b
b
o
o
o
o
o
o
o
o
s
...
...
...

错误信息是

Test.exe ended prematurely and may have crashed. exit code 3

我怀疑我对组 split/or reduce 做错了,但无法用几个 trials.How 来解决这个问题,我是否需要更改以使其工作?谢谢

现金的原因是因为你在下面的行中两次将同一个变量传递给 MPI

boost::mpi::reduce(heads, res, res, std::plus<int>(), 0);

Boost.MPI 中没有详细记录,但 boost 通过引用获取这些内容并将相应的指针传递给 MPI。 MPI 通常禁止您将同一个缓冲区两次传递给同一个调用。准确地说,传递给 MPI 函数的输出缓冲区不得与此调用中传递的任何其他缓冲区混淆(重叠)。

您可以通过创建 res.

的副本轻松解决此问题

我还认为您可能想限制从具有 local.rank() == 0 的进程调用第二个 reduce。

同时重申评论 - 我怀疑你会从 re-implementing 减少中获得任何好处。尝试优化其瓶颈未完全理解的性能问题通常是一个坏主意。