MPI编程(3)—点对点通信(阻塞式MPI_Send/MPI_Recv和非阻塞式MPI_Isend/MPI_Irecv)
1.MPI的两种点对点通信方式
MPI的点对点通信包括阻塞式和非阻塞式:
- 阻塞式通信调用 MPI_Send/MPI_Recv
MPI_Send不会返回,调用MPI_Send发送数据的进程会被阻塞,直到缓存为空
MPI_Recv不会返回,调用 MPI_Recv接收数据的进程会被阻塞,直到缓存被填充
- 非阻塞式通信调用 MPI_Isend/MPI_Irecv
调用MPI_Isend或MPI_Irecv会马上返回
非阻塞式操作允许进行重叠的计算和通信
2. MPI_Send/MPI_Recv
- 代码示例
MPI_Send/MPI_Recv的代码示例如下,
int rank, data[101];MPI_Init(0, 0);MPI_Comm_rank(MPI_COMM_WORLD, &rank);if (rank == 0){for (int i = 0; i < 101; ++i){data[i] = i + 1;}//发送消息MPI_Send(data, 101, MPI_INT, 1, 0, MPI_COMM_WORLD);printf("process %d send 101 个int\n", rank);}else if (rank == 1){MPI_Status status;//接收消息MPI_Recv(data, 101, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);int count;//获取消息个数MPI_Get_count(&status, MPI_INT, &count);printf("process %d recv %d 个int\n", rank, count);}MPI_Finalize();
- 注意避免死锁
阻塞式通信虽然简单,但一定要注意避免两个进程之间相互发送消息时,可能出现死锁现象
int rank, data[101];MPI_Init(0, 0);MPI_Comm_rank(MPI_COMM_WORLD, &rank);if (rank == 0){for (int i = 0; i < 101; ++i){data[i] = i + 1;}//发送消息MPI_Send(data, 101, MPI_INT, 1, 0, MPI_COMM_WORLD);printf("process %d send 101 个int\n", rank);MPI_Status status;//接收消息MPI_Recv(data, 101, MPI_INT, 1, 0, MPI_COMM_WORLD, &status);int count;//获取消息个数MPI_Get_count(&status, MPI_INT, &count);printf("process %d recv %d 个int\n", rank, count);}else if (rank == 1){for (int i = 0; i < 101; ++i){data[i] = 101 - i;}//发送消息MPI_Send(data, 101, MPI_INT, 0, 0, MPI_COMM_WORLD);printf("process %d send 101 个int\n", rank);MPI_Status status;//接收消息MPI_Recv(data, 101, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);int count;//获取消息个数MPI_Get_count(&status, MPI_INT, &count);printf("process %d recv %d 个int\n", rank, count);}MPI_Finalize();
3. MPI_Isend/MPI_Irecv
- 代码示例
MPI_Isend/MPI_Irecv的代码示例如下,
int rank;MPI_Init(0, 0);MPI_Comm_rank(MPI_COMM_WORLD, &rank);if (rank == 0) {int data = 100;MPI_Request request;//异步发送数据MPI_Isend(&data, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &request);printf("process %d send data, do other work\n", rank);//在多个request上等待MPI_Wait(&request, MPI_STATUSES_IGNORE);printf("process %d wait over\n", rank);}else {int data = 0;MPI_Request request;//异步接收数据MPI_Irecv(&data, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &request);printf("process %d receive data,data is %d, do other work\n", rank, data);//在多个request上等待MPI_Status status;MPI_Wait(&request, &status);printf("process %d wait over, data is %d\n", rank, data);}MPI_Finalize();
执行结果如下,可以看出,只有当MPI_Wait返回后,MPI_Irecv的buf才真正接收到数据。
- 非阻塞发送注意事项
非阻塞MPI_Isend调用后不要马上修改发送buf,否则可能真正的发送的是buf中的新内容,请看如下示例.
*buf =3;
MPI_Isend(buf, 1, MPI_INT …)
*buf = 4; //不能确定接收者接收到3还是4,或者其他啥内容
MPI_Wait(…);
而阻塞MPI_Send调用就不会出现该问题
*buf =3;
MPI_Send(buf, 1, MPI_INT …)
*buf = 4; //虽然发送接口调用后buf被修改,但保证接收者会接收到3
- 叠加的计算和通信
通过非阻塞接口,可以进行连续不断的数据计算和通信,示例如下:
int rank, data[100];MPI_Init(0, 0);MPI_Comm_rank(MPI_COMM_WORLD, &rank);if (rank == 0) {MPI_Request request[100];//连续异步发送数据for (int i=0; i< 100; i++) {data[i] = i + 1;//异步发送数据, 不用等待对方接收,就进行下一个数据的计算和发送MPI_Isend(&data[i], 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &request[i]);printf("process %d send data[%d]\n", rank, i);}//在多个request上等待MPI_Waitall(100, request, MPI_STATUSES_IGNORE);}else {for (int i = 0; i < 100; i++){//同步接收数据MPI_Recv(&data[i], 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);printf("process %d receive data[%d]\n", rank, i);} }MPI_Finalize();
MPI编程(3)—点对点通信(阻塞式MPI_Send/MPI_Recv和非阻塞式MPI_Isend/MPI_Irecv)相关推荐
- 同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO
IO的方式通常分为几种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. 一.BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSock ...
- AIO,BIO,NIO:同步阻塞式IO,同步非阻塞IO,异步非阻塞IO
BIO,同步阻塞式IO,简单理解:一个连接一个线程 NIO,同步非阻塞IO,简单理解:一个请求一个线程 AIO,异步非阻塞IO,简单理解:一个有效请求一个线程 IO:阻塞IO BIO:同步阻塞IO.服 ...
- Java并发编程实战系列15之原子遍历与非阻塞同步机制(Atomic Variables and Non-blocking Synchronization)...
近年来,在并发算法领域的大多数研究都侧重于非阻塞算法,这种算法用底层的原子机器指令来代替锁来确保数据在并发访问中的一致性,非阻塞算法被广泛应用于OS和JVM中实现线程/进程调度机制和GC以及锁,并发数 ...
- 五种I/O 模式——阻塞(默认IO模式),非阻塞(常用语管道),I/O多路复用(IO多路复用的应用场景),信号I/O,异步I/O
From: http://blog.163.com/xychenbaihu@yeah/blog/static/13222965520112163171778/ 五种I/O 模式: [1] ...
- linux 管道非阻塞,linux – 管道上的非阻塞读取
可以在管道上进行非阻塞I / O吗? fcntl无法设置O_NONBLOCK. Linux编程接口的页面918包括一个表'从管道读取n个字节或FIFO(p)'的语义.此表列出了管道和FIFO的行为,其 ...
- pythontcp服务器如何关闭阻塞_python实现单线程多任务非阻塞TCP服务端
本文实例为大家分享了python实现单线程多任务非阻塞TCP服务端的具体代码,供大家参考,具体内容如下 # coding:utf-8 from socket import * # 1.创建服务器soc ...
- 磁条卡,接触式IC卡,非接触式IC卡的优缺点
磁条卡的特点: 磁条卡由于其结构简单,存储容量小,安全保密性差,读写设备复杂且维护费用高,作为七.八十年代技术水平的产品已风光不再,即将面临淘汰. 智能IC卡与磁条卡相比有哪些优势? 接触式IC卡与磁 ...
- 微分算法 非侵入式负荷识别_非侵入式负荷监测的识别方法和关键技术
原标题:非侵入式负荷监测的识别方法和关键技术 在智能电网时代,必须突破目前用户家用电表只能读取用电总量,不能深入分析用户内部负荷成分,获取负荷信息有限的这一瓶颈,以完善用电信息采集系统和智能用电系统. ...
- 非侵入式负荷matlab程序,非侵入式负荷分解之BLUED数据集
非侵入式负荷分解之BLUED数据集 非侵入式负荷分解之BLUED数据集 BLUED数据集包含大约8天之内来自单个美国家庭的高频(12 kHz)家庭级数据.该数据集还包含一个事件列表,该列表涉及家庭中每 ...
- java非侵入式接口实现_No-intrusive, 非侵入式接口设计
Go语言的Interface很大不同于C#,Java这种OOP语言的,其强大之处之一在于非侵入式设计. 基础复杂性是守恒的,需要解决的基本问题始终是需要解决的:最终的复杂性,却取决于基础复杂性彼此间的 ...
最新文章
- PHP学习笔记-PHP语言基础3
- PHP 读取Excel数据
- bzoj1297 [SCOI2009]迷路(矩阵优化)
- 【FI学习笔记】客户发票收款清账
- 针对SSL/TLS的拒绝服务攻击以及使用ettercap进行DNS欺骗
- 我没学过计算机,是怎么接了四个私活还挣了两个 iPad 的?分享一下!
- linux下卸载 dev sd*下硬盘,Linux 磁盘管理(示例代码)
- C#开发笔记之01-为什么开源框架会大量的使用protected virtual?
- 面试题 17.09. 第 k 个数
- MMF与WAV格式的铃声制作全过程
- A股各概念板块龙头股大全
- java excel换行_java poi出excel换行问题
- 利用机器学习进行恶意代码分类
- 利用JAVA的BFS爬虫爬出豆瓣读书的评论和标签
- 融金所-孙明达:中国普惠金融覆盖率已属较高水平
- 北京商标纠纷诉讼侵犯注册商标专有权的行为都有什么?
- tiff文件读取若干问题
- 【BIM入门实战】Revit安装失败的常见问题及解决办法汇总
- 质检员根据检索报告中A类文献
- What's New in Dundas Chart 6.1