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

标签 c++ mpi boost-mpi

我使用 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

我怀疑我在组拆分/或缩减方面做错了,但通过多次试验无法弄清楚。我该如何更改才能使其正常工作?谢谢。

最佳答案

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

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

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

您可以通过创建 res 的拷贝轻松解决此问题。

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

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

关于C++ MPI,使用多个节点,首先在节点级别减少,然后减少到头节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56841278/

相关文章:

c - 与 off_t 等效的 MPI 数据类型是什么?

c++ - 如果 recv 和 send 匹配,mpi 请求是否完成

c++ - 如何找到一个号码的日志?

c++ - 使用rdtsc计算系统时间

Python 调用使用 MPI 的 (fortran) 库

c - 非常奇怪的 MPI 行为

python - Qt C++项目中如何调用python matplotlib?

c++ - 如何使用箭头浏览QtVirtualKeyboard

c++ - 如何使用 boost MPI 出现死锁情况(我使用 MPICH 编译器)?

boost - 尝试构建 Boost MPI,但未创建 lib 文件。这是怎么回事?