MPI是一个跨语言的通讯协议,用于并发编程。MPI标准定义了一组具有可移植性的编程接口。

安装环境

MPICH 是开源的消息传递接口(MPI)标准的实现。

下载地址

# 解压文件
tar -xzvf mpich-3.2.1.tar.gz
cd mpich-3.2.1
# /usr/local/Cellar/mpich 改为你要安装 MPICH 的路径
./configure –-prefix=/usr/local/Cellar/mpich |& tee c.log
make |& tee m.log
make install |& tee mi.log
# 将你安装 MPICH 的路径添加到 PATH
export PATH=/usr/local/Cellar/mpich:$PATH;

编程例子

1. 简单 MPI 编程之进程识别

#include <mpi.h> // mpi 头文件
#include <stdio.h> int main(int argc, char **argv) {
int numprocs, myid;
MPI_Init (&argc, &argv); // 初始化 MPI 执行环境
MPI_Comm_size (MPI_COMM_WORLD, &numprocs); // 获取有多少个进程属于 MPI_COMM_WORLD 通信域
MPI_Comm_rank (MPI_COMM_WORLD, &myid); // 获取当前进程的 id if (myid == 0) {
// 进程号为0的进程执行的操作...
} else {
// 其它进程执行的操作...
}
// 所有进程都执行的操作... MPI_Finalize(); // 结束 MPI 执行环境
return 0;
}

2. MPI 简单通信

#include <mpi.h> // mpi 头文件
#include <stdio.h> int main(int argc, char **argv) {
int data[100], myid;
MPI_Init (&argc, &argv);
MPI_Comm_rank (MPI_COMM_WORLD, &myid); if (myid == 0)
MPI_Send(data, 100, MPI_INT, 1, 0, MPI_COMM_WORLD);
else if (myid == 1)
MPI_Recv(data, 100, MPI_INT, 0, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE); MPI_Finalize(); // 结束 MPI 执行环境
return 0;
}

其中,MPI_SEND(buf, count, datatype, dest, tag, comm) 是发送消息的 API,

buf 是消息缓存区。

count是消息大小。

datatype是数据类型。

dest是目的进程在指定的进程域 comm 的进程号。

tag是用户定义的消息的类型。

MPI_RECV(buf, count, datatype, source, tag, comm, status) 是(阻塞)接收消息的 API。

source 是来源进程在指定的进程域 commMPI_ANY_SOURCE 的进程号。

tag 可以是 MPI_ANY_TAG

status 用来接收更多信息,可以用 MPI_STATUS_IGNORE 如果我们不需要更多信息。

编译运行程序

封装的编译器:

  • 对于 C 程序:mpicc test.c -o test
  • 对于 C++ 程序:mpicxx test.cpp -o test
  • 对于 Fortran 77 程序:mpif77 test.f -o test
  • 对于 Fortran 90 程序:mpif90 test.f90 -o test

你也可以链接其它库:mpicc test.c -o test -lm

运行:

启动 16 个进程:mpiexec -n 16 ./test

如果-n 指定的进程数超过了系统的CPU(核)数,就会报错如下:

There are not enough slots available in the system to satisfy the 16 slots

that were requested by the application:

./test

Either request fewer slots for your application, or make more slots available

for use.

进阶一些:

// 非阻塞发送。非阻塞接收为 MPI_Irecv,具体说明可以用 man 命令查询.
int MPI_Isend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag,
MPI_Comm comm, MPI_Request *request) // 检测非阻塞通信是否完成。阻塞等待为 MPI_Wait,可以等待全部(MPI_Waitall)、等待一些(MPI_Waitsome,MPI_Waitany)
nt MPI_Test( MPI_Request *request, int *flag, MPI_Status *status ); // 数据归约:通过计算收集到的多个数据得到一个数据。
int MPI_Reduce (void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)

初识并发编程 MPI的更多相关文章

  1. 学习笔记:java并发编程学习之初识Concurrent

    一.初识Concurrent 第一次看见concurrent的使用是在同事写的一个抽取系统代码里,当时这部分代码没有完成,有许多的问题,另一个同事接手了这部分代码的功能开发,由于他没有多线程开发的经验 ...

  2. 《Go并发编程实战》读书笔记-初识Go语言

    <Go并发编程实战>读书笔记-初识Go语言 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在讲解怎样用Go语言之前,我们先介绍Go语言的特性,基础概念和标准命令. 一. ...

  3. Python并发编程之初识异步IO框架:asyncio 上篇(九)

    大家好,并发编程 进入第九篇. 通过前两节的铺垫(关于协程的使用),今天我们终于可以来介绍我们整个系列的重点 -- asyncio. asyncio是Python 3.4版本引入的标准库,直接内置了对 ...

  4. C#并发编程之初识并行编程

    写在前面 之前微信公众号里有一位叫sara的朋友建议我写一下Parallel的相关内容,因为手中商城的重构工作量较大,一时之间无法抽出时间.近日,这套系统已有阶段性成果,所以准备写一下Parallel ...

  5. Python3 与 C# 并发编程之~ 线程篇

      2.线程篇¶ 在线预览:https://github.lesschina.com/python/base/concurrency/3.并发编程-线程篇.html 示例代码:https://gith ...

  6. Go并发编程实战 (郝林 著)

    第1章 初识Go语言 1.1 语言特性 1.2 安装和设置 1.3 工程构造 1.3.1 工作区 1.3.2 GOPATH 1.3.3 源码文件 package main import ( " ...

  7. Go并发编程实战 第2版 PDF (中文版带书签)

    Go并发编程实战 第2版 目录 第1章 初识Go语言 1 1.1 语言特性 1 1.2 安装和设置 2 1.3 工程结构 3 1.3.1 工作区 3 1.3.2 GOPATH 4 1.3.3 源码文件 ...

  8. 【漫画】JAVA并发编程 如何解决原子性问题

    原创声明:本文转载自公众号[胖滚猪学编程],转载务必注明出处! 在并发编程BUG源头文章中,我们初识了并发编程的三个bug源头:可见性.原子性.有序性.在如何解决可见性和原子性文章中我们大致了解了可见 ...

  9. day38 Pyhton 并发编程

    # 网络编程 # arp协议 : # 1.这是一个通过ip找mac地址的协议 # 2.由于有了socket,用户在使用网络的时候,只需要关心对方用户的ip地址就可以了 # 3.如果用户即将和这个ip进 ...

随机推荐

  1. Android LayoutInflater 类分析

    作为一名Android开发者,写页面是最普通不过的事情了,在编写页面的时候,系统给提供了两种形式,一种形式是通过XML的方式进行编写,还有一种形式是通过Java代码直接编写   我们知道Android ...

  2. Android人脸识别App(带web上传注册信息)

    人脸识别+本机Web后端人脸sdk采用虹软sdk,本机web采用AndServer:上传姓名+人脸图片即可实现注册源码地址:https://github.com/joetang1989/ArcFace ...

  3. C/C++ -- 插入排序算法

    索引: 目录索引 参看代码 GitHub: Sort.cpp 代码简要分析说明: 1.for(int i=1;i<nSize;i++) 这个外层的for循环, [0][1],[1][2],[2] ...

  4. [20190415]关于shared latch(共享栓锁).txt

    [20190415]关于shared latch(共享栓锁).txt http://andreynikolaev.wordpress.com/2010/11/17/shared-latch-behav ...

  5. SQL Server 索引碎片产生原理重建索引和重新组织索引

    数据库存储本身是无序的,建立了聚集索引,会按照聚集索引物理顺序存入硬盘.既键值的逻辑顺序决定了表中相应行的物理顺序 多数情况下,数据库读取频率远高于写入频率,索引的存在 为了读取速度牺牲写入速度 页 ...

  6. 【原】Java学习笔记025 - 内部类

    package cn.temptation; public class Sample01 { public static void main(String[] args) { // 内部类(嵌套类): ...

  7. 安装和使用 memcached

    memcached 和 Grails,第 1 部分:安装和使用 memcached 学习 memcached 命令并评估缓存性能 本文是系列文章的第 1 部分,主要介绍 memcached 和 Gra ...

  8. c++11の条件变量

    一.条件变量的引入 std::condition_variable 解决了死锁并且控制的资源的访问顺序二避免不必要的等待.当互斥操作不够用而引入的.比如,线程可能需要等待某个条件为真才能继续执行,而一 ...

  9. web框架开发-Django模型层(2)-多表操作

    很重要,都是精华 多表关系模型 一对一 一旦确定表关系是一对一,在两张表中的任意一张表中建立关联字段+Unique 一对多 一旦确定表关系是一对多,创建关联字段在多的表中 多对多 一旦确定表关系是多对 ...

  10. SQL 和 NoSQL 的区别

    一.概念 SQL (Structured Query Language) 数据库,指关系型数据库.主要代表:SQL Server,Oracle,MySQL(开源),PostgreSQL(开源). No ...