在 for 循环中处理复杂的发送 recv 消息
Dealing with complex send recv message within a for loop
我正在尝试将生物模型与boost::mpi
C++并行化。这是我的第一次尝试,我对提升图书馆完全陌生(我从Schaling的Boost C++ Libraries一书开始(。该模型由网格单元和生活在每个网格单元内的个体队列组成。这些类是嵌套的,因此Cohorts*
向量属于GridCell
。该模型运行了1000年,在每个时间步长中,都存在分散性,使得个体队列在网格单元之间随机移动。我想并行化 for 循环的内容,但不是循环本身,因为每个时间步长都取决于前一次的状态。
我使用world.send()
和world.recv()
将必要的信息从一个等级发送到另一个等级。 因为有时我与mpi::status
和world.iprobe()
一起使用的等级之间没有什么要发送的,以确保代码不会挂起等待从未发送的消息(我遵循了本教程(
我的代码的第一部分似乎工作正常,但是在继续执行for循环的下一步之前,我在确保已收到所有发送的消息时遇到了麻烦。事实上,我注意到一些等级在其他等级有时间发送他们的消息之前移动到以下时间步长(或者至少从输出中看起来的样子(
我不发布代码,因为它由几个类组成,而且很长。如果有兴趣,代码在github上。我在这里大致写了伪代码。我希望这足以理解这个问题。
int main()
{
// initialise the GridCells and Cohorts living in them
//depending on the number of cores requested split the
//grid cells that are processed by each core evenly, and
//store the relevant grid cells in a vector of GridCell*
// start to loop through each time step
for (int k = 0; k < (burnIn+simTime); k++)
{
// calculate the survival and reproduction probabilities
// for each Cohort and the dispersal probability
// the dispersing Cohorts are sorted based on the rank of
// the destination and stored in multiple vector<Cohort*>
// I send the vector<Cohort*> with
world.send(…)
// the receiving rank gets the vector of Cohorts with:
mpi::status statuses[world.size()];
for(int st = 0; st < world.size(); st++)
{
....
if( world.iprobe(st, tagrec) )
statuses[st] = world.recv(st, tagrec, toreceive[st]);
//world.iprobe ensures that the code doesn't hang when there
// are no dispersers
}
// do some extra calculations here
//wait that all processes are received, and then the time step ends.
//This is the bit where I am stuck.
//I've seen examples with wait_all for the non-blocking isend/irecv,
// but I don't think it is applicable in my case.
//The problem is that I noticed that some ranks proceed to the next
//time step before all the other ranks have sent their messages.
}
}
我编译
mpic++ -I/$HOME/boost_1_61_0/boost/mpi -std=c++11 -Llibdir -lboost_mpi -lboost_serialization -lboost_locale -o out
并使用mpirun -np 5 out
执行,但我希望以后能够在 HPC 集群上使用更多内核执行(模型将在全球范围内运行,单元数可能取决于用户选择的网格单元大小(。 安装的编译器是 g++ (Ubuntu 7.3.0-27ubuntu1~18.04( 7.3.0,开放 MPI:2.1.1
你没有要发送的任何内容这一事实是你的方案中的重要信息。您无法仅从没有消息的情况下推断出这一事实。没有消息仅意味着尚未发送任何内容。
简单地发送一个零大小的向量并跳过探测是最简单的方法。
否则,您可能不得不从根本上改变您的方法或实现非常复杂的推测执行/回滚机制。
另请注意,链接的教程以非常不同的方式使用 probe。
- boost::进程间消息队列引发错误
- 在线编译器中的分段C++没有打印消息
- C++错误消息*成员参考.**初学者*
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 如何通过参数抛出错误消息
- 从服务器传输到客户端的消息不会出现
- ROS2 动态消息模板
- C++秘密消息学校作业
- glad 导致 glfwSwapBuffers 返回错误消息
- C++入门 5 版:类消息和文件夹
- FindPackageHandleStandardArgs.cmake:137 的 CMake 错误(消息):找不到 Boost (缺少:正则表达式)(找到合适的版本"1.72.0",
- 在 for 循环中处理复杂的发送 recv 消息
- 包含消息长度的两个字节标头上的部分recv()呢?
- 带有 MSG_PEEK 的 recv() 显示完整消息,但正常返回'would block'
- 在之前不知道消息长度的情况下处理阻塞的 recv() 函数,并且不想使用 asy I/O
- 如何在 winsock 编程中从 recv() 获取确切的消息
- UDP套接字是否将接收到的数据划分为不同的消息,或者recv是否同时读取尽可能多的数据
- winsock,面向消息的网络,以及从recv中类型转换缓冲区