有了apue的基础,再看mpi程序多进程通信就稍微容易了一些,以下几个简单程序来自都志辉老师的那本MPI的书的第七章。

现在ubuntu上配置了一下mpich的环境:

http://www.cnblogs.com/liyanwei/archive/2010/04/26/1721142.html

注意,为了编译运行方便,在~/.bashrc文件中添加mpi的两个环境变量

设置完之后注意执行source ~/.bashrc命令

程序1 计时功能

主要用到的MPI_Wtime()这个函数

 #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "mpi.h" int main(int argc, char *argv[])
{
int err = ;
double t1, t2;
double tick;
int i; MPI_Init(&argc, &argv);
t1 = MPI_Wtime();
t2 = MPI_Wtime();
if (t2-t1>0.0 || t2-t1<0.0) {
err++;
fprintf(stderr, "two successive calls to MPI_Wtime gave strange results: (%f)(%f)\n", t1, t2);
} for( i=; i<; i++)
{
t1 = MPI_Wtime();
sleep();
t2 = MPI_Wtime();
if (t2-t1>=(-0.1) && t2-t1<=) {
break;
}
if (t2-t1>5.0) {
i = ;
}
}
if (i==) {
fprintf(stderr, "timer around sleep(1) did not give 1 second; gave %f\n", t2-t1);
err++;
}
tick = MPI_Wtick();
if (tick>1.0 || tick<0.0) {
err++;
fprintf(stderr, "MPI_Wtick gave a strange result:(%f)\n", tick);
}
MPI_Finalize();
}

执行结果如下(在程序中故意设定了触发问题):

程序2 进程间数据接力传送

这里主要是MPI_Send和MPI_Recv两个函数,发送和接受来自其他进程的消息

代码如下:

 #include <stdio.h>
#include "mpi.h" int main(int argc, char *argv[])
{
int rank, value, size;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank); /*当前进程在MPI_COMM_WORLD这个通信组下面 编号是多少*/
MPI_Comm_size(MPI_COMM_WORLD, &size); /*MPI_COMM_WORLD这个通信组下面 有多少个进程*/
do {
if (rank==) {
fprintf(stderr, "\nPlease give new value=");
scanf("%d",&value);
fprintf(stderr, "%d read <-<- (%d)\n",rank,value);
/*必须至少有两个进程的时候 才能进行数据传递*/
if (size>) {
MPI_Send(&value, , MPI_INT, rank+, , MPI_COMM_WORLD);
fprintf(stderr, "%d send (%d)->-> %d\n", rank,value,rank+);
}
}
else {
MPI_Recv(&value, , MPI_INT, rank-, , MPI_COMM_WORLD, &status);
fprintf(stderr, "%d receive(%d)<-<- %d\n",rank, value, rank-);
if (rank<size-) {
MPI_Send(&value, , MPI_INT, rank+, , MPI_COMM_WORLD);
fprintf(stderr, "%d send (%d)->-> %d\n", rank, value, rank+);
}
}
MPI_Barrier(MPI_COMM_WORLD);
}while(value>=);
MPI_Finalize();
}

执行结果如下:

这里注意运行时候,参数 -np 4的意思是设置开启4个进程

程序3 进程间互相发送数据

 #include <stdio.h>
#include <stdlib.h>
#include "mpi.h" void Hello(void); int main(int argc, char *argv[])
{
int me, option, namelen, size;
char process_name[MPI_MAX_PROCESSOR_NAME];
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &me);
MPI_Comm_size(MPI_COMM_WORLD, &size); if (size < ) {
fprintf(stderr, "system requires at least 2 processes");
MPI_Abort(MPI_COMM_WORLD, );
}
MPI_Get_processor_name(process_name, &namelen);
fprintf(stderr, "Process %d is alive on %s\n", me, process_name);
MPI_Barrier(MPI_COMM_WORLD);
Hello();
MPI_Finalize();
} void Hello()
{
int nproc, me;
int type = ;
int buffer[], node;
MPI_Status status;
MPI_Comm_rank(MPI_COMM_WORLD, &me);
MPI_Comm_size(MPI_COMM_WORLD, &nproc);
if (me==) {
printf("\nHello test from all to all\n");
fflush(stdout);
}
for(node = ; node < nproc; node++)
{
if (node != me) {
buffer[] = me;
buffer[] = node;
MPI_Send(buffer, , MPI_INT, node, type, MPI_COMM_WORLD);
MPI_Recv(buffer, , MPI_INT, node, type, MPI_COMM_WORLD, &status);
if (buffer[] != node || buffer[] != me) {
fprintf(stderr, "Hello: %d != %d or %d != %d\n", buffer[], node, buffer[], me);
printf("Mismatch on hello process ids; node = %d\n",node);
}
printf("Hello from %d to %d\n",me,node);
fflush(stdout);
}
}
}

执行结果如下:

程序4 多个进程向一个进程发送消息

 #include "mpi.h"
#include <stdio.h> int main(int argc, char *argv[])
{
int rank, size, i, buf[];
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (rank==) {
/*主进程不断接收从各个进程发送过来的消息*/
for(i=; i<*(size-); i++)
{
MPI_Recv(buf, , MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
printf("Msg=%d from %d with tag %d\n",buf[], status.MPI_SOURCE, status.MPI_TAG);
}
}
else {
/*其他进程向主进程发送消息*/
for(i=; i<; i++)
{
buf[] = rank+i;
MPI_Send(buf, , MPI_INT, , i, MPI_COMM_WORLD);
}
}
MPI_Finalize();
}

执行结果如下:

上面几个程序的核心是MPI_Send和MPI_Recv,在上面的程序中来看,这两个函数都是阻塞函数。

因此,进程之间如果有消息的互相发送和接收,就可能会产生死锁现象。

这个书上P47~49有说明,但是由于涉及到MPI通讯模式的问题,因此留到后面再看。

这几个程序目的是为了数据mpi的编译运行环境以及一些基本函数,后面开始学习并行程序的设计方法。

【MPI学习1】简单MPI程序示例的更多相关文章

  1. 【MPI学习5】MPI并行程序设计模式:组通信MPI程序设计

    相关章节:第13章组通信MPI程序设计. MPI组通信与点到点通信的一个重要区别就是:组通信需要特定组内所有成员参与,而点对点通信只涉及到发送方和接收方. 由于需要组内所有成员参与,因此也是一种比较复 ...

  2. 【MPI学习4】MPI并行程序设计模式:非阻塞通信MPI程序设计

    这一章讲了MPI非阻塞通信的原理和一些函数接口,最后再用非阻塞通信方式实现Jacobi迭代,记录学习中的一些知识. (1)阻塞通信与非阻塞通信 阻塞通信调用时,整个程序只能执行通信相关的内容,而无法执 ...

  3. 【MPI学习3】MPI并行程序设计模式:不同通信模式MPI并行程序的设计

    学习了MPI四种通信模式 及其函数用法: (1)标准通信模式:MPI_SEND (2)缓存通信模式:MPI_BSEND (3)同步通信模式:MPI_SSEND (4)就绪通信模式:MPI_RSEND ...

  4. 【MPI学习2】MPI并行程序设计模式:对等模式 & 主从模式

    这里的内容主要是都志辉老师<高性能计算之并行编程技术——MPI并行程序设计> 书上有一些代码是FORTAN的,我在学习的过程中,将其都转换成C的代码,便于统一记录. 这章内容分为两个部分: ...

  5. 【MPI学习6】MPI并行程序设计模式:具有不连续数据发送的MPI程序设计

    基于都志辉老师<MPI并行程序设计模式>第14章内容. 前面接触到的MPI发送的数据类型都是连续型的数据.非连续类型的数据,MPI也可以发送,但是需要预先处理,大概有两类方法: (1)用户 ...

  6. 【MPI学习7】MPI并行程序设计模式:MPI的进程组和通信域

    基于都志辉老师MPI编程书中的第15章内容. 通信域是MPI的重要概念:MPI的通信在通信域的控制和维护下进行 → 所有MPI通信任务都直接或间接用到通信域这一参数 → 对通信域的重组和划分可以方便实 ...

  7. MPI 学习笔记

    目录 MPI学习笔记 MPI准备 概述 前置知识补充 环境部署 1.修改IP及主机名 2.关闭防火墙 3.实现免密码SSH登录 4.配置MPI运行环境 5.测试 程序的执行 编译语句 运行语句 MPI ...

  8. 一个简单的JSP程序示例

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"% ...

  9. Kubernetes学习笔记之安装minikube并运行个简单应用程序

    前言:本笔记仅记录学习记录,可能存在错误!!!使用的环境是Ubuntu Desktop 20.04,也有用Windows 10 操作的,根据的文档是minikube的文档教程,链接:https://m ...

  10. Windows调试学习笔记:(二)WinDBG调试.NET程序示例

    好不容易把环境打好了,一定要试试牛刀.我创建了一个极其简单的程序(如下).让我们期待会有好的结果吧,阿门! using System; using System.Collections.Generic ...

随机推荐

  1. Android调用Web服务

    现在大部分应用程序都把业务逻辑处理,数据调用等功能封装成了服务的形式,应用程序只需要调用这些web服务就好了,在这里就不赘述web服务的优点了.本文总结如何在android中调用Web服务,通过传递基 ...

  2. 【linux环境下】RabbitMq的安装和监控插件安装

    [注意安装过程中,提示某些命令not found,直接yum isntall一下就好了] 以下是我在CentOS release 6.4下亲测成功的. RabbitMq的安装:   RabbitMQ是 ...

  3. POI教程之第二讲:创建一个时间格式的单元格,处理不同内容格式的单元格,遍历工作簿的行和列并获取单元格内容,文本提取

    第二讲 1.创建一个时间格式的单元格 Workbook wb=new HSSFWorkbook(); // 定义一个新的工作簿 Sheet sheet=wb.createSheet("第一个 ...

  4. Moodle插件之Filters(过滤器)

    Moodle插件之Filters(过滤器) 过滤器是一种在输出之前自动转换内容的方法. 目的: 创建名为helloworld的过滤器,实现将预输出的“world”字符串替换成“hello world” ...

  5. jQuery事件绑定on、off 和one,取代bind, live, delegate

    jQuery最新版建议:最好用on来代替以前的bind, live, delegate,其中live是最不建议使用的. on和off的格式 on $(elements).on(events[, sel ...

  6. Socket常见错误

    一.简介 本文介绍 Socket 连接常见错误.   二.常见错误 1)ECONNABORTED 描述:"software caused connection abort",即&q ...

  7. D_S 循环队列的基本操作

    //  main.cpp #include <iostream> using namespace std; #include "Status.h" typedef in ...

  8. 生成大小为100的数组,从1到100,随机插入,不连续,也不重复[C#]

    生成大小为100的数组,从1到100,随机插入,不连续,也不重复. 实现思路 生成一个100位的集合listA,放1到100 创建一个空的集合listB,用来存放结果 创建一个变量c,临时存储生成的数 ...

  9. Tomcat 内存和线程配置优化

    1. tomcat 的线程配置参数详情如下: 修改conf/server.xml中的<Connector .../> 节点如下: <Connector port="8080 ...

  10. NOIP2008 普及组T4 立体图 解题报告-S.B.S.(施工未完成)

    题目描述 小渊是个聪明的孩子,他经常会给周围的小朋友们将写自己认为有趣的内容.最近,他准备给小朋友们讲解立体图,请你帮他画出立体图. 小渊有一块面积为m*n的矩形区域,上面有m*n个边长为1的格子,每 ...