2013-02-09 89 views
1

在MPI中,有非阻塞呼叫,如MPI_IsendMPI_IrecvMPI非阻塞通信和pthreads的区别?

如果我在一个p2p项目上工作,服务器将听很多客户端。

一种方式做到这一点:

for(int i = 1; i < highest_rank; i++){ 
    MPI_Irecv(....,i,....statuses[i]); //listening to all slaves 
} 
while(true){ 
    for(int i = 1; i < highest_rank; i++){ 
     checkStatus(statuses[i]) 
     if true do somthing 
} 

另一种老办法,我能做到这一点是:

Server creating many POSIX threads, pass in a function, 
that function will call MPI_Recv and loop forever. 

理论上,哪一个会在服务器端执行得更快?如果还有另一种更好的方式来编写服务器,请让我知道。

回答

3

后一种解决方案对我来说看起来效率不高,因为管理MPI进程中的pthread会导致所有开销。

无论如何,我会重写你MPI代码:

for(int i = 1; i < highest_rank; i++){ 
    MPI_Irev(....,i,....requests[i]); //listening to all slaves 
} 
while(true){ 
    MPI_waitany(highest_rank, request[i], index, status); 
    //do something useful 

} 

更妙的是你可以使用MPI_ANY_SOURCE MPI_RECV作为消息来源的等级。看起来您的服务器除了服务请求外没有任何要做的事情,因此不需要使用异步recv。 代码如下:

while(true){ 
    MPI_Recv(... ,MPI_ANY_SOURCE, REQUEST_TAG,MPI_comm,status) 
    //retrieve client id from status and do something 
} 
+0

问:如果使用MPI_ANY_SOURCE,我能否知道哪个药膏向我发送了这个请求? – SDEZero 2013-02-10 01:40:16

+2

@LouisTan是的,检查这个主从模型是建立在该原理http://www.lam-mp​​i.org/tutorials/one-step/ezstart.php – pyCthon 2013-02-10 03:17:04

+0

@pyCthon伟大的教程,非常感谢! – SDEZero 2013-02-10 06:14:17

1

当调用MPI_Irecv,它是不是安全测试recv的缓冲后,才MPI_TEST *或* MPI_WAIT已调用并成功完成。在不进行这些调用的情况下直接测试缓冲区的行为取决于实现(并且范围从不那么糟糕到段错误)。

为每个远程等级设置一个MPI_Irecv 1:1映射可以工作。根据发送的数据量以及数据一旦收到的时间,这种方法可能会消耗不可接受的系统资源。使用MPI_Testany或MPI_Testall可能会在消息处理和CPU负载之间提供最佳平衡。如果在等待传入消息时没有需要完成的非MPI处理,MPI_Waitany或MPI_Waitall可能更可取。

如果存在未完成的MPI_Irecv调用,但应用程序已达到正常处理的结束时间,则对MPI_Cancel这些未完成调用是“必要的”。没有这样做可能会被MPI_Finalize作为错误捕获。

MPI_ANY_SOURCE上的单个MPI_Irecv(或仅MPI_Recv,取决于消息处理需要多么激进)也提供了一个合理的解决方案。如果接收到的数据量“很大”并且可以在处理后安全丢弃,这种方法也可能很有用。一次处理单个传入缓冲区可以减少所需的总体系统资源,但会以串行化处理为代价。

0

让我来评论一下你的想法,使用POSIX线程(或者其他可能的线程机制)。使MPI从在同一时间多个线程调用要求MPI实现初始化与线程支持的MPI_THREAD_MULTIPLE的最高水平:

int provided; 

MPI_Init_thread(&argv, &argc, MPI_THREAD_MULTIPLE, &provided); 
if (provided != MPI_THREAD_MULTIPLE) 
{ 
    printf("Error: MPI does not provide full thread support!\n"); 
    MPI_Abort(MPI_COMM_WORLD, 1); 
} 

虽然选项以支持在不同的线程并发调用在MPI标准介绍很久以前,仍然有MPI实现难以提供完全可用的多线程支持。MPI至少在理论上是写便携式应用程序,但在这种情况下,现实生活与理论的差别很大。例如,当在MPI_THREAD_MULTIPLE级别初始化时,最广泛使用的开源MPI实施之一 - 开放MPI - 仍然不支持本地InfiniBand通信(InfiniBand是目前大多数HPC群集中使用的速度非常快的低延迟架构),因此开关以不同的速度运行,速度通常要慢得多,而且通过普通以太网或IP-over-InfiniBand传输TCP/IP等更高延迟。还有一些超级计算机供应商,其MPI实现根本不支持MPI_THREAD_MULTIPLE,通常是因为硬件的工作方式。

此外,MPI_Recv是一个阻塞调用,这会导致正确的线程取消(如果需要)的问题。你必须确保所有线程以某种方式逃离死循环,例如通过让每个员工用适当的标签或其他协议发送终止消息。