【笔记】OpenMPI基本使用1

介绍

在 90 年代之前,对不同的计算架构写并发程序是一件困难而且复杂的事情。当时,虽然很多软件库可以帮助写并发程序,但是并没有一个大家都接受的标准。

在当时,大多数的并发程序出现在科学研究领域。其中最广为接受的模型就是消息传递模型。那么,什么是消息传递模型呢?它其实是指程序通过在进程间传递消息(消息可以理解成带有一些信息和数据的一个数据结构)来完成某些任务。在实践中,将并发程序用这个模型实现十分容易。举例来说,主进程(manager process)可以通过对从进程(worker process)发送一个描述工作的消息来把这个工作分配给它。实际上,几乎所有的并行程序都可以使用消息传递模型来描述。

由于当时很多软件库都用到了消息传递模型,但是在定义上却有一些差异,这些库的作者以及其他一些人为了解决这个问题就在1992 Supercomputing 大会上定义了一个消息传递接口的标准,也就是 MPI。这个标准接口使得程序员写的并发程序可以在所有主流的并发框架中运行,并且允许使用一些流行库的特性和模型。

到 1994 年的时候,一个完整的接口标准已经被定义好了(MPI-1)。MPI 其实就是一个接口的定义,然后需要程序员去根据不同的架构去实现这个接口。但很幸运的是仅仅一年之后,一个完整的 MPI 实现就出现了,之后 MPI 就被大量地使用在消息传递应用程序中,并且一直是写这类程序的标准(de-facto)。

设计

通讯器定义了一组能够互相发消息的进程。在这组进程中,每个进程会被分配一个序号,称作秩(rank),进程间显性地通过指定 rank 来进行通信。

通信的基础建立在不同进程间发送和接收操作。一个进程可以通过指定另一个进程的 rank 以及一个独一无二的消息标签(tag)来发送消息给另一个进程。接受者可以只接收特定标签标记的消息(或者也可以完全不管标签来接收任何消息),然后依次处理接收到的数据。类似这样的涉及一个发送者以及一个接受者的通信被称作点对点(point-to-point)通信。

当然在很多情况下,某个进程可能需要跟所有其他进程通信。比如主进程想发一个广播给所有的从进程。在这种情况下,手动去写一个个进程点对点的信息传递就显得很笨拙,并且这样也会导致网络利用率低下。MPI 有专门的接口来帮我们处理这类所有进程间的集体性(collective)通信。

安装

安装过程详见openmpi入门1-安装与测试,这里只简单介绍一下

到openmpi官网下载openmpi,也可以使用wget下载:

wget https://download.open-mpi.org/release/open-mpi/v4.0/openmpi-4.0.4.tar.gz

下载完成之后进行解压:

tar -zxvf openmpi-4.0.4.tar.gz

进入openmpi-4.0.4文件夹检查配置文件

cd openmpi-4.0.4
./configure

编译安装

sudo make all install

配置openmpi环境变量

vim /etc/profile# 在这个文件末尾添加如下两行
export PATH=/usr/local/path:$PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
source /etc/profile

进入到examples文件夹中,执行make编译一下测试代码,进行测试

mpirun -np 4 hello_c

正常输出结果则说明安装完成

如果出现 enough slots available in the system 报错可传送至最后一节查看解决方法

Hello World

#include <mpi.h>
#include <stdio.h>int main(int argc, char** argv) {// Initialize the MPI environmentMPI_Init(NULL, NULL);// Get the number of processesint world_size;MPI_Comm_size(MPI_COMM_WORLD, &world_size);// Get the rank of the processint world_rank;MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);// Get the name of the processorchar processor_name[MPI_MAX_PROCESSOR_NAME];int name_len;MPI_Get_processor_name(processor_name, &name_len);// Print off a hello world messageprintf("Hello world from processor %s, rank %d out of %d processors\n",processor_name, world_rank, world_size);// Finalize the MPI environment.MPI_Finalize();
}
EXECS=mpi_hello_world
MPICC?=mpiccall: ${EXECS}mpi_hello_world: mpi_hello_world.c${MPICC} -o mpi_hello_world mpi_hello_world.cclean:rm ${EXECS}

我们可以编辑makefile文件来运行此Demo,注意makefile文件复制过程中的 Tab

make
mpirun --oversubscribe -np 4 mpi_hello_world

OpenMPI程序基本结构

结合上述Hello World,我们不难发现 OpenMPI程序的基本结构

首先添加 MPI 头文件#include <mpi.h>. 然后使用以下命令进行 MPI 初始化:

MPI_Init(int* argc,char*** argv)

MPI_Init 的过程中,所有 MPI 的全局变量或者内部变量都会被创建。举例来说,一个通讯器 communicator 会根据所有可用的进程被创建出来(进程是我们通过 mpi 运行时的参数指定的),然后每个进程会被分配独一无二的秩 rank。当前来说,MPI_Init 接受的两个参数是没有用处的,不过参数的位置保留着,可能以后会需要用到。

MPI_Init 之后,有两个主要的函数被调用,这两个函数是几乎所有 MPI 程序都会用到的。

MPI_Comm_size(MPI_Comm communicator,int* size)

MPI_Comm_size返回通信器的大小。在示例中,MPI_COMM_WORLD(由 MPI 为我们构建)包含其所有进程,因此该调用应返回进程数。

MPI_Comm_rank(MPI_Comm communicator,int* rank)

MPI_Comm_rank返回通信器中进程的rank。通信器内的每个进程都被分配了一个从零开始的递增等级。进程的rank主要用于发送和接收消息时的识别。

程序的最终调用是MPI_Finalize用于清理 MPI 环境。

我们亦可以通过一些配置实现多机的分布式并行计算,这里先不再介绍。

发送与接收

MPI 的发送和接收方法是按以下方式进行的:

开始的时候,A 进程决定要发送一些消息给 B 进程。A进程就会把需要发送给B进程的所有数据打包好,放到一个缓存里面。因为所有数据会被打包到一个大的信息里面,因此缓存常常会被叫做信封(envelopes),就像我们把好多信纸打包到一个信封里,然后再寄去邮局。数据打包进缓存之后,通信设备(通常是网络)就需要负责把信息传递到正确的地方。这个正确的地方也就是根据特定 rank 确定的那个进程。

尽管数据已经被送达到 B 了,但是进程 B 依然需要确认它想要接收 A 的数据。一旦它进行了确定,数据就被传输成功了。进程 A 会接收到数据传递成功的信息,然后去干其他的事情。

有时候 A 需要传递很多不同的消息给 B。为了让 B 能比较方便地区分不同的消息,MPI 发送者和接受者额外指定一些信息ID (即标签 tags)。当 B 只要求接收某种特定标签的信息的时候,其他的不是这个标签的信息会先被缓存起来,等到 B 需要的时候才会给 B。

MPI_Send(void* data,int count,MPI_Datatype datatype,int destination,int tag,MPI_Comm communicator)
MPI_Recv(void* data,int count,MPI_Datatype datatype,int source,int tag,MPI_Comm communicator,MPI_Status* status)

第一个参数是数据缓冲区。第二个和第三个参数分别描述了数据的数量和类型。MPI_Send会精确地发送 count 指定的数量个元素,MPI_Recv会最多接受 count 个元素接。第四个和第五个参数指定发送方/接受方进程的rank以及信息的标签。第六个参数指定通信器,MPI_Recv 方法特有的最后一个参数提供了接受到的信息的状态。

相关例子与测试:https://github.com/mpitutorial/mpitutorial/tree/gh-pages/tutorials/mpi-send-and-receive/code

报错:enough slots available in the system

原因:在虚拟机中运行经常会出现报错enough slots available in the system,这是由于Open MPI 会估算我们的CPU承载能力,用一定算法计算出进程的上限。

解决:一般来说,我们加上--oversubscribe超出上限个数运行即可(但要注意可能会有未定义行为)

参考

A Comprehensive MPI Tutorial Resource

【笔记】OpenMPI基本使用1相关推荐

  1. 【DOTS学习笔记】DOTS简介

    目录 前言 DOTS是什么? 核心Package 游戏功能相关Package 谁需要关注DOTS? DOTS可以应用到哪些地方? 为什么需要DOTS 前言 本文是Metaverse大衍神君的<D ...

  2. LIGGGHTS笔记1——集群Centos安装编译,CFDEM耦合OpenFOAM

    1.什么是LIGGGHTS LIGGGHTS是一款开源DEM颗粒模拟软件,其基础是LAMMPS(一款分子动力学模拟软件).目前有两个版本,PUBLIC版本是为研究者们提供使用,而PREMIUM版本是提 ...

  3. 【读书笔记】知易行难,多实践

    前言: 其实,我不喜欢看书,只是喜欢找答案,想通过专业的解答来解决我生活的困惑.所以,我听了很多书,也看了很多书,但看完书,没有很多的实践,导致我并不很深入在很多时候. 分享读书笔记: <高效1 ...

  4. 【运维学习笔记】生命不息,搞事开始。。。

    001生命不息,搞事不止!!! 这段时间和hexesdesu搞了很多事情! 之前是机械硬盘和固态硬盘的测速,我就在那默默的看着他一个硬盘一个机械测来测去. 坐在他后面,每天都能看到这位萌萌的小男孩,各 ...

  5. SSAN 关系抽取 论文笔记

    20210621 https://zhuanlan.zhihu.com/p/353183322 [KG笔记]八.文档级(Document Level)关系抽取任务 共指id嵌入一样 但是实体嵌入的时候 ...

  6. pandas以前笔记

    # -*- coding: utf-8 -*- """ Created on Sat Jul 21 20:06:20 2018@author: heimi "& ...

  7. PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call

    您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...

  8. 容器云原生DevOps学习笔记——第三期:从零搭建CI/CD系统标准化交付流程

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  9. 容器云原生DevOps学习笔记——第二期:如何快速高质量的应用容器化迁移

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

最新文章

  1. Webservice入门教程_编写天气预报的webservice
  2. python flask服务_在python中Flask配置服务
  3. Ionic 用于构建惊人的移动应用程序的顶级开源框架
  4. c51单片机有几个终端语言,吃过大亏,才知道要从51单片机入手
  5. Apache ActiveMQ中的消息级别授权
  6. JSP的9个内置对象-application
  7. How to: Create and Initialize Trace Listeners
  8. tomcat服务器开启gzip功能的方法
  9. bool型数组python_Python bool()
  10. SynchronizedMap和ConcurrentHashMap 区别
  11. POJ 2289 Jamie's Contact Groups 【二分】+【多重匹配】(模板题)
  12. SVM(1)-概念与理解
  13. linux通过yum安装vim,linux/centos系统如何使用yum安装vi/vim?(转)
  14. [2018.07.24 T1] 真板题
  15. 2022最新短视频去水印解析API接口支持各大小程序
  16. java文件ftp下载,java ftp下载文件夹内所有文件,java 下载ftp文件夹下所有文件
  17. VSCode Setting Sync同步设置
  18. Groq:从头设计一个张量流式处理器架构
  19. 妇产科护理学名词解释
  20. Maya2022安装教程

热门文章

  1. MurmurHash 算法生成短链接
  2. 2008北京奥运会志愿者用语
  3. 基于 dlib 的人脸检测(68关键点)
  4. 什么是运维?什么是游戏运维?
  5. python日期转化成周数_python dataframe将周数转换为月
  6. multsim14 计时类应用设计--时钟、计时器、倒计时
  7. Android手机端无人机地面站2.0版本 2021-07-30
  8. CentOS上Docker的安装卸载及Docker简介
  9. 美国政府警告:西门子医疗扫描设备存在多处漏洞
  10. 找回git rebase --skip消失的代码