【C语言】【MPI】MPI编程入门详解

MPI简介

说到并行计算,我们有一个不可绕开的话题——MPI编程。MPI是一个跨语言的通讯协议,用于编写并行计算机。支持点对点和广播。MPI是一个信息传递应用程序接口,包括协议和和语义说明,他们指明其如何在各种实现中发挥其特性。MPI的目标是高性能,大规模性,和可移植性。MPI在今天仍为高性能计算的主要模型。与OpenMP并行程序不同,MPI是一种基于信息传递的并行编程技术。消息传递接口是一种编程接口标准,而不是一种具体的编程语言。简而言之,MPI标准定义了一组具有可移植性的编程接口。
笔者在上一篇文章《如何在win10+vs2013上配置MPI并行编程环境》中详细介绍了如何在win10环境下配置MPI环境,还没有配置编程环境的小伙伴建议查看这边文章,以便于以后的学习(毕竟并行机不是你想拥有就能拥有的)。

MPI基本函数

MPI调用借口的总数虽然庞大, 但根据实际编写MPI的经验, 常用的MPI调用的个数确什么有限。 下面是6个最基本的MPI函数。

1.  MPI_Init(…);
2.  MPI_Comm_size(…);
3.  MPI_Comm_rank(…);
4.  MPI_Send(…);
5.  MPI_Recv(…);
6.  MPI_Finalize();

我们在此通过一个简单的例子来说明这6个MPI函数的基本用处。

函数介绍

1. int MPI_Init (int* argc ,char** argv[] )

该函数通常应该是第一个被调用的MPI函数用于并行环境初始化,其后面的代码到 MPI_Finalize()函数之前的代码在每个进程中都会被执行一次。

  • –  除MPI_Initialized()外, 其余所有的MPI函数应该在其后被调用。
  • –  MPI系统将通过argc,argv得到命令行参数(也就是说main函数必须带参数,否则会出错)。

2. int MPI_Finalize (void)

  • –  退出MPI系统, 所有进程正常退出都必须调用。 表明并行代码的结束,结束除主进程外其它进程。
  • –  串行代码仍可在主进程(rank = 0)上运行, 但不能再有MPI函数(包括MPI_Init())。

3. int MPI_Comm_size (MPI_Comm comm ,int* size )

  • –  获得进程个数 size。
  • –  指定一个通信子,也指定了一组共享该空间的进程, 这些进程组成该通信子的group(组)。
  • –  获得通信子comm中规定的group包含的进程的数量。

4. int MPI_Comm_rank (MPI_Comm comm ,int* rank)

  • –  得到本进程在通信空间中的rank值,即在组中的逻辑编号(该 rank值为0到p-1间的整数,相当于进程的ID。)

5. int MPI_Send( void *buff, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)

  • –void *buff:你要发送的变量。
  • –int count:你发送的消息的个数(注意:不是长度,例如你要发送一个int整数,这里就填写1,如要是发送“hello”字符串,这里就填写6(C语言中字符串未有一个结束符,需要多一位))。
  • –MPI_Datatype datatype:你要发送的数据类型,这里需要用MPI定义的数据类型,可在网上找到,在此不再罗列。
  • –int dest:目的地进程号,你要发送给哪个进程,就填写目的进程的进程号。
  • –int tag:消息标签,接收方需要有相同的消息标签才能接收该消息。
  • –MPI_Comm comm:通讯域。表示你要向哪个组发送消息。

6. int MPI_Recv( void *buff, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)

  • –void *buff:你接收到的消息要保存到哪个变量里。
  • –int count:你接收消息的消息的个数(注意:不是长度,例如你要发送一个int整数,这里就填写1,如要是发送“hello”字符串,这里就填写6(C语言中字符串未有一个结束符,需要多一位))。它是接收数据长度的上界. 具体接收到的数据长度可通过调用MPI_Get_count 函数得到。
  • –MPI_Datatype datatype:你要接收的数据类型,这里需要用MPI定义的数据类型,可在网上找到,在此不再罗列。
  • –int dest:接收端进程号,你要需要哪个进程接收消息就填写接收进程的进程号。
  • –int tag:消息标签,需要与发送方的tag值相同的消息标签才能接收该消息。
  • –MPI_Comm comm:通讯域。
  • –MPI_Status *status:消息状态。接收函数返回时,将在这个参数指示的变量中存放实际接收消息的状态信息,包括消息的源进程标识,消息标签,包含的数据项个数等。

示例

基本函数都已经介绍完,现在我们来用一个示例来加强对这些基本函数的理解。

#include <stdio.h>
#include <string.h>
#include "mpi.h"
void main(int argc, char* argv[])
{int numprocs, myid, source;MPI_Status status;char message[100];MPI_Init(&argc, &argv);MPI_Comm_rank(MPI_COMM_WORLD, &myid);MPI_Comm_size(MPI_COMM_WORLD, &numprocs);if (myid != 0) {  //非0号进程发送消息strcpy(message, "Hello World!");MPI_Send(message, strlen(message) + 1, MPI_CHAR, 0, 99,MPI_COMM_WORLD);}else {   // myid == 0,即0号进程接收消息for (source = 1; source < numprocs; source++) {MPI_Recv(message, 100, MPI_CHAR, source, 99,MPI_COMM_WORLD, &status);printf("接收到第%d号进程发送的消息:%s\n", source, message);}}MPI_Finalize();
} /* end main */

运行结果如下图所示

可以看到,当笔者开启四线程运行时,1-3号进程发送消息,0号进程接收到消息并打印;当笔者开启八线程运行时,1-7号进程发送消息,0号进程接收到消息并打印。

本文使用的是标准阻塞接收发送的方式。消息传递是MPI的特性,也是我们学习的难点。这我们学习MPI必须掌握的。

消息发送与接收函数的参数的一些重要说明。

1.MPI标识一条消息的信息包含四个域:

–  源:发送进程隐式确定,进程rank值唯一标识.
–  目的:Send函数参数确定.
–  Tag:Send函数参数确定, (0,UB) 232-1.
–  通信子:缺省MPI_COMM_WORLD
•  Group:有限/N, 有序/Rank [0,1,2,…N-1]
•  Contex:Super_tag,用于标识该通讯空间.

2. buffer的使用

buffer必须至少可以容纳count个由datatype指明类型的数据. 如果接收buf太小, 将导致溢出、 出错

3. 消息匹配

–  参数匹配source,tag,comm/dest,tag,comm.
–  Source == MPI_ANY_SOURCE: 接收任意处理器来的数据(任意消息来源).
–  Tag == MPI_ANY_TAG: 匹配任意tag值的消息(任意tag消息).

4. 在阻塞式消息传送中不允许Source == dest,否则会导致死锁.

5. 消息传送被限制在同一个通信域内。

6. 在send函数中必须指定唯一的接收者。

参考链接:
https://www.jianshu.com/p/2fd31665e816

【C语言】【MPI】MPI编程入门详解相关推荐

  1. C# Windows 窗体编程入门详解

    C# Windows 窗体编程入门详解 基于Web的B/S架构应用程序近年来确实非常流行,B/S易于部署.易于维护的特点使Web应用程序开发得到了前所未有的发展.但是,Web应用程序的缺点是,它们有时 ...

  2. python编程入门详解_python编程入门知识练习

    python 入门基础知识练习 1编写第一个程序,目前使用的都是python 3 # print('hello world!') 2.查看当前python编辑器的版本号 # python -v 3.使 ...

  3. C语言之#define用法入门详解

    一.#define的基本语法 在C语言中,常量是使用频率很高的一个量.常量是指在程序运行过程中,其值不能被改变的量.常量常使用#define来定义. 使用#define定义的常量也称为符号常量,可以提 ...

  4. python语言编程基础-Python语言入门详解!快速学成Python!

    原标题:Python语言入门详解!快速学成Python! 很多技能是被职场所需要的,但很可惜... 这些技能在大学中并学习不到. 大学和职场现实存在的横沟对大部分同学来说难以跨越或碰得头破血流... ...

  5. python语言入门m-Python语言入门详解!快速学成Python!

    今日主题 "Python语言入门详解" 近两年来,Python语言借着数据科学和人工智能的"东风"成为了最流行的编程语言--街头巷尾人们口口相传.同时,Pyth ...

  6. python语言入门详解-python初级教程:入门详解

    python初级教程:入门详解 Crifan Li 目录 前言 .................................................................... ...

  7. python语言入门-Python语言入门详解!快速学成Python!

    原标题:Python语言入门详解!快速学成Python! 很多技能是被职场所需要的,但很可惜... 这些技能在大学中并学习不到. 大学和职场现实存在的横沟对大部分同学来说难以跨越或碰得头破血流... ...

  8. [论文阅读] (01) 拿什么来拯救我的拖延症?初学者如何提升编程兴趣及LATEX入门详解

    又是在凌晨三点赶作业,又是在Deadline前去熬夜,一次次无眠,一次次抱怨.为什么三年前.两年前.一年前,甚至是昨天,我都下定决心"从现在开始读顶会论文",却又悄悄选择逃避:为什 ...

  9. 说明使用tc编程的一般步骤 c语言,TC编程手册详解-完整版.doc

    TC编程手册详解-完整版 TC编程手册详解-完整版 本文是TC的第一部分,主要介绍一些TC相关的基础知识,并着重针对循环.变量等TC基本概念中的易混的淆部分加以辨析,即是一份编程初学者的指南,也可算作 ...

  10. FFmpeg入门详解之119:FFmpeg的SDK编程回顾总结并操练

    3.FFmpeg的SDK编程回顾总结并操练 参考课程:"FFmpeg4.3--系列5--SDK二次开发详解与实战" FFmpeg主要框架 FFmpeg骨架:"八大金刚&q ...

最新文章

  1. 最棒 Spring Boot 干货总结(超详细,建议收藏)
  2. 每日一皮:程序员的生存状态 ...
  3. Ubuntu下安装OpenGL/Glut库
  4. C C++中关于全局变量静态变量,extern,static,const的区别与总结
  5. MFC与Matlab编程总结 (以《Matlab与C/C++混合编程技术(第三版)》-刘维 第五章 生成DLL为例)
  6. 荒岛求生游戏显示服务器不行,《荒岛求生》黑屏解决方法
  7. struts2标签处理下拉列表
  8. [转]Extundelete--数据恢复软件
  9. bootstrap学习笔记(5)
  10. Linux 冯诺依曼体系结构
  11. 使用 Django 的日志模块,同时发送错误邮件到163邮箱
  12. 解放前端工程师——手把手教你开发自己的自定义列表和自定义表单系列之三表格
  13. RLS实现求解最小二乘确定性正则方程
  14. Output Shape和Param参数解释
  15. 命令行下转换amr为mp3
  16. 2022年最新遥感类期刊JCR影响因子及分区
  17. [Python笔记_2]循环、字符串、列表、函数、异常处理
  18. 机器人快跑!伯克利和CMU联合开发两足机器人,两条细腿,一马平川
  19. windows编程经典书籍
  20. Android - WebView接入H5客服照片/视频上传

热门文章

  1. C语言学习教程免费分享
  2. 路由器显示DNS服务器异常,路由器dns异常怎么办
  3. 用正则表达式验证联系电话(及区号)
  4. TINA仿真系列之555定时器
  5. 一个简单的log2(x)的快速计算方法
  6. 雷达测速仪的原理及激光测速枪的应用
  7. 数字舵机c语言编程,舵机入门
  8. 1218 正方形还是圆形
  9. python webp图片转化格式
  10. PCIe总线的参考时钟与同步时钟的差异