asc18超算mpi学习总结2

1. 四种通信模式

标准通信 Send Recv 系统操作缓冲区

缓存通信 Bsend 用户自定义缓冲区,必须由程序员申请空间对即将发送的数据存入缓冲区。

同步通信 Ssend 相应的接受必须开始之后才返回结束。

就绪通信 Rsend 相应的接收必须启动之后才开始发送数据。

2. 非阻塞通信MPI

阻塞通信 send recv只有当sendrecv 函数成功返回之后,才执行下面的代码,

非阻塞通信 可以不用等待两者结束就可以先执行下面代码。判断结束: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发送a1,0发送b1

          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()   初始化通信。

你可能感兴趣的:(asc竞赛)