1. 四种通信模式
标准通信 Send Recv 系统操作缓冲区
缓存通信 Bsend 用户自定义缓冲区,必须由程序员申请空间对即将发送的数据存入缓冲区。
同步通信 Ssend 相应的接受必须开始之后才返回结束。
就绪通信 Rsend 相应的接收必须启动之后才开始发送数据。
2. 非阻塞通信MPI
阻塞通信 send recv只有当send或recv 函数成功返回之后,才执行下面的代码,
非阻塞通信 可以不用等待两者结束就可以先执行下面代码。判断结束:MPI_Wait()函数可以结束发送接收。
MPI_Isend MPI_Irecv 标准非阻塞发送接收,这里面多了一个request对象,此对象包含了非阻塞通信状况。Wait将此对象释放。
MPI_Test()any all some测试通信状态,返回,继续执行下面代码。
MPI_Wait MPI_Waitany MPI_Waitall MPI_Waitsome 结束通信,释放对象
MPI_Cancel() 取消通信,当通信已经发出,则继续通信,通信完成之后再取消。
MPI_Probe()检查消息到达与否。可以针对发送方的tag
MPI_Iprobe()
3. 阻塞与非阻塞语义约束
两者相同,发送顺序即接受顺序。
例如:0发送a给1,0发送b给1;
1有两个接受语句,第一个接受语句一定会接收到a,即使b先到,1也先接收a
4. 非阻塞实现jacobi迭代。
非阻塞可以将计算与通信同时进行,所以像阻塞通信那样要等待发送接收完毕才计算。
所以将jacobi中的通信代码和计算代码分开,
(1)计算迭代任务中下次需要通信的数据
(2)启动非阻塞通信,传递这些数据。
(3)计算剩余部分,这部分计算又和通信同时进行。
(4)完成阻塞通信。
将jacobi中边界值的计算放到前面,发送这些值到下一次的a的边界中,之后计算剩余部分。之后执行一次Wait将通信完成进行下一次迭代。这次代码中我用的是行分解。
顺序输出方法:不是主进程接收上一个进程的一个消息,之后打印,再发送一个消息给下一个进程,主进程打印发送消息给下一个进城,这样就可以顺序打印。
这中间有问题,代码中第一次迭代时,由于数组简单且已知恰好和初始值相等,计算边界值时直接计算,并没有去通信得到其他进程的真实值。完整实现我觉得应该在第一次迭代之前就将a所需得到的数据通信一次,给与真实的其他进程的值,这样计算准确。
5. 重复非阻塞通信。
当send recv 通信频繁时,比如jacobi中循环通信,每次都要将两个进程关联。
可以将通信初始化,之后需要时直接传数据,就像连接了一个管道,之后只需传送即可。消息完成之后将其状态转为非活动状态,用MPI_Start(){MPI_Startall}将对象激活。MPI_Wait()这时就不能将对象释放,只能显示的将request对象释放,MPI_Request_free()。
MPI_Recv_init() MPI_Send_init() 初始化通信。

1392

被折叠的 条评论
为什么被折叠?



