来自未知来源的MPI异步广播 [英] MPI asynchronous broadcast from unknown source

查看:81
本文介绍了来自未知来源的MPI异步广播的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C项目,其中有n个处理器在进行某种树搜索.在程序的任何给定时间,这些进程中的任何一个都可能会找到感兴趣的内容,并希望将其异步发送到所有其他处理器.

I have a C-project that has n numbers of processors working on a kind of tree search. At any given time of the program, any of these processes may find something of interest and want to send this to all other processors asynchronously.

如何在其他进程中侦听新消息,而不必每次循环迭代都遍历所有可能的发件人?

How can I listen for new messages on the other processes without having to loop through all possible senders each loop iteration?

我还阅读了有关此问题的其他问题,例如,这个问题( MPI-异步广播/聚集),但是,到目前为止,我所看到的全部要么无法处理无法预测的发件人,要么无法遍历每个可能的发件人,这我并不十分喜欢.

I have read other questions about this, for example this one (MPI - Asynchronous Broadcast/Gather), however, all I've seen so far either doesn't handle unpredictable senders or loops through each possible sender, which I don't really fancy.

为澄清起见而

将找到的值发送到根目录并从那里进行分配是没有选择的.如果我没有祖兰的条件,祖兰的答案将行得通,因此对其他人来说可能会有帮助. 在我的情况下,可能(而且肯定会发生)不同级别的人找到他们需要多次分享的东西(这意味着种族条件也可能发生).

Sending the found value to a root rank and distributing it from there is out of the option. Zulan's answer would work, if I did not have that condition, so for others this might be of help. In my case it can (and most definitely will) happen that different ranks find something they need to share multiple times (which means that race conditions could also occur).

推荐答案

经过反复试验(和其他反馈),我发现性能最高的解决方案使用异步广播.

After a lot of trial and error (and other feedback) I found that the most performant solution uses asynchronous broadcasts.

我的第一种方法受Petru的回答启发,他使用多个非阻塞MPI_Isend()调用来分发数据,并且仅使用一个MPI_Irecv()调用(使用任何来源)来定期接收数据.事实证明这种方法非常慢,因为非阻塞MPI_ISend()调用必须由发送方在创建的每个MPI_Request句柄上使用MPI_Test()进行检查. 这样做的原因是,异步操作并不是真正意义上的异步,因为它们在后台运行,而是必须定期进行检查.

My first approach was inspired by Petru's answer using multiple non blocking MPI_Isend() calls to distribute data and only one single MPI_Irecv() call (with any source) to periodically receive data. This approach turned out to be quite slow, since the non blocking MPI_ISend() calls have to be checked by the sender with MPI_Test() on every single MPI_Request handle that is created. The reason for that is, that asynchronous operations aren't truly asynchronous in the sense that they work in the background, but rather have to be checked periodically.

在我的情况下,该问题还提出了可以(并且将)多次找到新解决方案的可能性,这导致了现有开放MPI_Request句柄的许多管理问题,否则必须等待或管理.

In my case the problem also presents the possibility that new solutions can (and will) be found multiple times, which resulted in a lot of management issues with existing, open MPI_Request handles, which had to be waited for or managed otherwise.

我的第二种方法是使用Zulan提出的中央沟通器.在没有太多消息的情况下,这种方法很快,但是在同时找到许多解决方案的情况下,根目录排名被阻塞,在特殊情况下,它的运行速度非常慢.最重要的是,根排名已经不再像其他排名那样快了(这是可以预料的),这导致我的程序总体上变慢了.

My second approach was using a central communicator as proposed by Zulan. This approach was very quick when there weren't many messages, but the root rank got clogged up when there were many found solutions at the same time, making it very slow in special cases. Most importantly the root rank was not as fast as the others anymore (which was to be expected), which resulted in an overall slower program in my case.

我的第三个也是最后一个方法是使用多个非阻塞MPI_Ibcast()调用,每个可能发送消息的等级都使用一个.例如,这意味着在具有3个不同等级的情况下,

My third and final approach was using multiple non blocking MPI_Ibcast() calls, one for every possible rank that could send a message. For example that would mean that in a case with 3 different ranks that

  • 等级0具有两个打开的MPI_Ibcast,其根为1和2
  • 等级1有两个打开的MPI_Ibcast,其根为0和2
  • 等级2具有两个开放的MPI_Ibcast,其根为0和1

当等级找到解决方案时,它将发布以自身为根的最后一个必要的MPI_Ibcast.乍一看,这似乎与方法一类似,但是,在这种情况下,发送方始终只需要监视一个请求句柄(来自最终MPI_Ibcast的请求句柄)并定期使用MPI_Test()对其进行检查.其他等级始终具有相同数量的公开广播(即,世界的大小减去1),可以将其存储在数组中并使用MPI_Testany()进行检查. 但是,这种方法的困难在于,每个开放广播都必须在其自己的通信器上进行操作,本质上需要与等级相同的通信器.

When a rank then finds a solution, it posts the last necessary MPI_Ibcast with itself as the root. At first this may seem similar to approach one, however, in this case the sender always only has to monitor a single request handle (the one from the final MPI_Ibcast) and check it periodically with MPI_Test(). The other ranks always have the same amount of open broadcasts (namely the world's size minus 1), which can be stored in an array and checked with MPI_Testany(). The difficulty with this approach is, however, that each open broadcast must operate on it's own communicator, essentially needing as many communicators as there are ranks.

因此,我的发现是,第二种方法有时是可以接受的,因此在没有太多消息的情况下,它是一种快速可行的选择.这是最容易处理和实施的.第三种方法是在较重的负载下更快,并且由于总是有已知数量的打开连接,因此使我的程序终止非常容易.它是最困难,最长的实现,并且比其他实现消耗了更多的内存. (我不知道其原因,但这似乎与广播的缓冲区管理以及可能的其他通信器有关.) 最后,我不能过分强调第一种方法一开始看起来很容易,但是不幸的是,当您真的想跟踪每个请求时,那么也很难管理并且很慢.

So, my findings are that the second approach is acceptable sometimes, making it a quick and viable option, when there are not a lot of messages. It was the easiest to handle and implement. The third approach was faster under heavier load and also made my program termination very easy, since there always is a known amount of open connections at all time. It was the hardest and longest to implement and used up a bit more memory than the other implementations. (I don't know the reason for this, but it seems to have something to do with the broadcast's buffer management and possibly the additional communicators.) Lastly I cannot stress enough that the first approach seems easy at first, however when you really want to keep track of every single request, then it is hard to manage and slow as well, unfortunately.

这篇关于来自未知来源的MPI异步广播的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆