我正在编写一个多线程的OpenMPI应用程序,使用来自多个线程的MPI_Isend和MPI_Irecv在InfiniBand RDMA上的排名之间每秒交换数百条消息。
转移大约为400-800KByte,每个等级产生大约9 Gbps的输入和输出,完全在FDR的容量范围内。简单的MPI基准测试也表现出良好的性能。
通过在专用线程中使用MPI_Testsome轮询所有活动传输来检查传输的完成。
我实现的传输速率取决于消息速率,但更重要的是取决于MPI_Testsome的轮询频率。也就是说,如果我每隔10毫秒轮询一次,请求的结束时间比我每1毫秒轮询一次。
我希望如果我轮换10ms而不是每1ms,我最多会在9ms之后被告知已完成的请求。我不希望传输本身通过减少对MPI_Testsome的调用来延迟完成,从而减慢总传输速率。我希望MPI_Testsome完全被动。
这里的任何人都知道为什么会出现这种情况?
答案 0 :(得分:9)
观察到的行为是由于在Open MPI中实现操作进程的方式。无论是同步还是异步完成发送或接收,都会导致一系列内部操作排队。进度基本上是那些排队操作的处理。您可以在库构建时选择两种模式:一种具有异步进程线程,另一种不具有默认值。
在启用异步进程线程的情况下编译库时,后台线程会小心并处理队列。这允许后台传输与用户代码并行开始,但增加了延迟。在没有异步进展的情况下,操作更快但是只有当用户代码调用MPI库时才能进行,例如,在MPI_Wait
或MPI_Test
和家人中。 MPI_Test
函数系列的实现方式是尽可能快地返回。这意味着图书馆必须平衡在通话中进行操作之间的权衡,从而减慢速度,或快速返回,这意味着每次通话都会减少操作。
一些Open MPI开发人员,特别是Jeff Squyres,时不时地访问Stack Overflow。他可能会提供更多细节。
此行为并非特定于Open MPI。除非经过大量硬件辅助,否则MPI通常采用相同的方法实现。