文章目录
并行计算编程学习笔记
1.1 MPI介绍
MPI(消息传递接口Message Passing Interface)是一个跨语言的通讯协议,实现进程间的通讯,用于编写并行计算程序。MPI是一个协议,提供很多接口,而不是编程语言,需要通过在c/c++,fortran调用实现。
注:多线程是一种便捷的模型,其中每个线程都可以访问其它线程的存储空间。
因此,这种模型只能在共享存储系统之间移植。一般来讲,并行机不一定在各处理器之间共享存储,
当面向非共享存储系统开发并行程序时,程序的各部分之间通过来回传递消息的方式通信。
要使得消息传递方式可移植,就需要采用标准的消息传递库。
1.2 并行编程模型、线程和进程
在CPU上,只有一个当前进程在执行,而其他进程被阻塞(暂停或等待唤醒),并且等待CPU上执行。任务调度程序的作用就是把进程动态分配给CPU。而多核架构产生了允许并发的多线程编程范式。分配给进程的资源在不同线程之间的共享的,并且至少有一个线程应当具有主(main)调用函数
- 同一进程的线程共享相同的内存区域,因此即可以访问内存中的数据区域,也能够访问其中的代码区域,自然也可以很容易地访问同一进程的线程之间的数据。但在同时访问内存时也会产生一些困难,最坏的情况下,它会导致系统的崩溃。并行随机存取机模型(Parallel Random Access Machine,PRAM),在PRAM模型中,我们将在同时对本地内存进行读写操作可能发生的各种冲突。分为三类:互斥读互斥写(Exclusive Read Exclusive Write sub-model,EREW)、同时读互斥写(Concurrent Read Exclusive Write,CREW)和同时读同时写(Concurrent Read Concurrent Write,CRCW)
- 进程和线程时不同的,因为线程有自己的非重叠的内存区域。进程之间的通信必须谨慎执行,特别是使用MPI标准时。
1.3 C++ MPI编程的特点:
- 各个进程之间没有依赖。进程可以以任意时间进行
- 数据是分布式存储的。也就是说,每个进程有自己独立的数据备份。
- 进程之间可以很方便地通信,并且支持多种通信方案
1.4 MPI编程需要程序员解决的问题
- 进程间的通讯方案(点对点通信、聚合通信、数据类型和非阻塞式通信。)
- 数据如何分配(如何分布式的储存数据)
openMPI和openMP的区别
- openMP:线程级(并行粒度);共享存储;隐式(数据分配方式);可扩展性差;
意味着在单机多内核上运行 - openMPI:进程级;分布式存储;显式;可扩展性好。
意味着支持集群和多cpu计算机上运算
openMPI和mpich的区别
它们都是采用MPI标准,在并行计算中,实现节点间通信的开源软件。各自有各自的函数,指令和库。
并行计算和分布式计算的区别
- 并行计算借助 并行算法和并行编程语言 能够实现 进程级并行(如MPI)和线程级并行(如openMP)。 而分布式计算只是将任务分成小块到各个计算机分别计算各自执行。
- 粒度方面,并行计算中,处理器间的交互一般很频繁,往往具有细粒度和低开销的特征,并且被认为是可靠的。而在分布式计算中,处理器间的交互不频繁,交互特征是粗粒度,并且被认为是不可靠的。并行计算注重短的执行时间,分布式计算则注重长的正常运行时间。
- 联系:并行计算和分布式计算两者是密切相关的。某些特征与程度(处理器间交互频率)有关,而我们还未对这种交叉点(crossover point)进行解释。另一些特征则与侧重点有关(速度与可靠性),而且我们知道这两个特性对并行和分布两类系统都很重要。
总之,这两种不同类型的计算在一个多维空间中代表不同但又相邻的点。1
1.5 openMPI下载安装
openMPI在linux上运行更具效率,本文以Ubuntu20系统为例
- sudo apt install xxx安装
- 在官网上下载最新(建议下载stable的版本)版本的安装包,如:openmpi-4.0.5.tar.gz
在安装包中找到readme(文件后缀为md)文件(也就是安装说明文件)按照提示安装下载
官网地址:https://www.open-mpi.org/software/ompi/v1.6/
1.6 openmpi常用函数以及常量
其他作者总结:传送门
官方使用手册:传送门 (建议使用这个)
基础函数展示
并行程序的开始和结束
(1)并行初始化函数:int MPI_Init(int *argc,char ***argv)
参数描述:argc为变量数目,argv为变量数组,两个参数均来自main函数的参数
(2)并行结束函数: int MPI_Finalize()
获取进程标识和状态的函数
(3)获得当前进程标识函数:int MPI_Comm_rank(MPI_Comm comm,int *rank)
参数描述:comm为该进程所在的通信域句柄,rank为调用这一函数返回的进程在通信域中的标识号
(4)获取通信域包含的进程总数函数:int MPI_Comm_size(MPI_Comm comm,int *size)
参数描述:comm为通信域句柄,size为函数返回的通信域comm内包含的进程总数
进程间通讯的函数(数据的分散与收集)
(5)消息发送函数:int MPI_Send(void *buf,int count,MPI_Datatype datatype,int dest,int tag,MPI_Comm comm)
参数描述:buf为发送缓冲区的起始地址,count为将发送的数据个数(以后面的数据类型进行计数),datatype为发送数据的数据类型,dest为目的进程标识号,tag为消息标识,comm为通信域
MPI_Send()将发送缓冲区buf中得count个datatype数据类型的数据发送到标识号为dest的目的进程,本次发送的消息标识是tag
(6)消息接收受函数:int MPI_Recv(void *buf,int count,MPI_Datatype datatype,int source,int tag,MPI_Comm,MPI_Status *status)
参数描述:buf为接收缓冲区的起始地址,count为最多可接收的数据个数,datatype为接收数据的数据类型,
source为接收数据的来源进程标识号,tag为消息标识,应与相应发送操作的标识相匹配,comm为本进程和发送进程所在的通信域,status为返回状态