C++ MPI是否删除或延迟消息?

C++ MPI是否删除或延迟消息?,c++,mpi,openmpi,C++,Mpi,Openmpi,我问了同样的问题,但我认为时间太长了,所以我将以更短的方式再试一次: 我在一个主/从设备上使用了一个最新的OpenMPi,在一个岩石集群上有一个C++程序。从机执行一项任务,然后使用阻塞的MPI_发送/MPI_RECV调用(通过Boost MPI)向主机报告数据,该调用将数据写入数据库。当前,主服务器的速度明显慢于从服务器。我在程序上遇到了麻烦,因为大约有一半的奴隶被困在第一个任务中,从不报告他们的数据;使用strace/ltrace,他们似乎被困在MPI_SEND的轮询中,并且他们的消息从未被

我问了同样的问题,但我认为时间太长了,所以我将以更短的方式再试一次:

我在一个主/从设备上使用了一个最新的OpenMPi,在一个岩石集群上有一个C++程序。从机执行一项任务,然后使用阻塞的MPI_发送/MPI_RECV调用(通过Boost MPI)向主机报告数据,该调用将数据写入数据库。当前,主服务器的速度明显慢于从服务器。我在程序上遇到了麻烦,因为大约有一半的奴隶被困在第一个任务中,从不报告他们的数据;使用strace/ltrace,他们似乎被困在MPI_SEND的轮询中,并且他们的消息从未被接收到

我编写了一个程序来测试这一理论(再次完整列出),我可以通过使用睡眠来操纵从机和主机的速度,从而导致类似的问题-从机通信速度显著降低,因此它们执行的任务比它们应该做的要少。当速度(主)>速度(从)时,一切正常。当speed(master)
知道为什么会这样吗?

据我所知,这是主节点while循环中recv的结果

 ...
 while (1) {
 // Receive results from slave.
      stat = world.recv(MPI_ANY_SOURCE,MPI_ANY_TAG);
 ...
当有来自一个从节点的消息时,主节点在while循环中的代码完成之前无法获取任何消息(这需要一段时间,因为存在睡眠),因为主节点不是并行运行的。因此,在第一个从机完成消息发送之前,所有其他从机无法开始发送消息。然后,下一个从机可以开始发送消息,但所有其他从机将停止,直到执行while循环中的代码

这导致了您看到的行为,即从机通信非常缓慢。要避免此问题,您需要实现点对点通信非阻塞或使用全局通信

更新1:

让我们假设主人分发了他的数据。现在他等到奴隶们回来报到。当第一个从机返回报告时,他将首先发送他的REPORTTAG,然后发送他的DONETAG。现在主人会给他一份新工作,如果

 currentTask < numtasks
现在停止所有作业,即使不是所有从属服务器都已报告其数据并已完成多个任务

当不同节点的网络连接高度不同时,此问题最为常见。原因是,发送和接收不会在呼叫后处理,而是在其中两个功能能够进行某种握手时进行通信

作为解决方案,我建议:

  • 确保在杀死所有作业之前完成所有从属作业
  • 使用聚集和分散而不是消息,然后在每个任务后同步所有从机
  • 如果消息不太大,则使用缓冲或非缓冲发送和接收操作。确保主机上没有内存溢出
  • 从主/从更改为更并行的工作模式,例如将所有任务划分为两个节点,然后将任务从这些节点进一步划分为下两个节点,依此类推。最后,以这种方式将任务发送回。此解决方案还可能具有以下优点:通信成本仅为O(logn)而不是O(n)

希望这有帮助。

在这里查看MPI\u Send/Recv的语义:基于此。。。可能是我使用的MPI源错误吗?由于Recv匹配,从某些从属服务器发送的消息(可能以特定于实现/设置的方式)是否会被超越。。。更新的消息?可能是@KenWhite的重复是的,对不起,那是我故意重复的。他们都是我的问题;我只是觉得第一篇文章中铺天盖地的细节可能会吓跑可能的答案,所以我想我还是再试一次。@Winawer:我意识到,-“接近重复”会自动添加“可能”。)你应该编辑你的原始问题以澄清/改进它,而不是发布一个单独的重复问题。但是如果所有消息都是按顺序接收的,只是因为它们等待主服务器,所以接收速度很慢,我预计这项工作需要很长时间,但每个从服务器执行相同数量的任务…对吗?如果是,为什么不是呢?如果没有,我的想法有什么问题?只是一些奴隶放慢了速度,而不是所有的奴隶。在完整的代码中,一些从机会完全卡住,无论等待多长时间,它们的消息都不会被接收。可能问题在于while循环中的最后一个{问题。在这里,您尝试向从机发送新工作:world.send(stat.source(),TASKTAG);world.send(stat.source(),TASKDATATAG,randnum);它实际上似乎是您在这里描述的内容的一个变体,尽管问题似乎是MPI_ANY_SOURCE。当我将任何_SOURCE更改为一个循环,循环通过从机顺序收集结果时,问题消失了,代码按照我的预期工作。但是,除非有人有什么精彩的东西要添加,否则我将接受你的答案,因为它让我朝着正确的方向思考。谢谢!如果你使用任何MPI_源,你也会在发送新任务之前同步从属任务。
 currentTask >= numtasks