并行计算复习————第四篇 并行计算软件支撑:并行编程

并行计算复习

第四篇 并行计算软件支撑:并行编程


Ch13 并行程序设计基础

13.1并行语言构造方法

  • 库例程:MPI、Pthreads
  • 扩展串行语言:Fortran90
  • 加编译注释构造:OpenMP

13.2并行性问题

可利用SPMD来伪造MPMD

那么并行扩展至需要支持SPMD即可

13.3交互/通信

(1)交互类型
  • 通信:进程间传数(共享变量、消息传递、参数传递[父进程传给子进程])
  • 同步:进程间相互等待或继续执行的操作(原子同步、控制同步[同步障、临界区]、数据同步[锁、condition、监控程序和事件])
  • 聚合:将分进程所计算的的结果整合起来(规约、扫描)
(2)交互方式
  • 同步交互:所有参与者全部到达后继续执行
  • 异步交互:任意进程到达后不必等待其他进程即可继续执行
(3)交互模式

按编译时是否能确定交互模式可分为静态的、动态的

按多少发送者和接收者:

  • 一对一:点到点通信
  • 一对多:广播、散播
  • 多对一:收集、规约
  • 多对多:全交换、扫描、置换、移位

13.4并行编程风范

  • 相并行:BSP模式,程序由一组超级步组成,步内各自并行计算,步间通信同步
  • 主从并行:主进程串行执行并且协调任务,子进程计算任务,需要划分设计并结合相并行
  • 分治并行:父进程把负载分割并指派给子进程,难以平衡负载
  • 流水线并行:进程划分成流水线,依次依赖,数据开始流动
  • 工作池并行:进程从工作池中取任务执行

13.5并行程序设计模型

(1)隐式并行

用串行语言编程,编译器货操作系统自动转化成并行代码

特点:语义简单、可以执行好、易调试易验证、but效率低

(2)数据并行

SIMD模型,包括数据选路和局部计算,特点:但现场、松散同步、常用聚合操作

数据并行计算π:

(3)消息传递

MPP、COW自然模型,MPI广泛应用:多线程异步并行、地址空间分开、常用SPMD形式编码

MPI消息传递计算π:

(4)共享变量

PVP、SMP、DSM自然模型,多线程异步,显示同步而隐式通信

OpenMP使用共享变量计算π:


Ch14 共享存储系统并行编程——OpenMP编程

14.1 OpenMP编程风格

1.OpenMP编程模型

OpenMP是FORK-JOIN模型,主线程串行执行,直到编译制导并行域出现

2.并行域

并行域格式:

线程数静态设定方法(线程 0~n-1):

  • 调用运行库omp_set_num_threads(numOfThreads)
  • 设置环境变量setenv OMP_NUM_THREADS numOfThreads
3.常用运行库

在include头文件”omp.h”后可以调用OpenMP运行库:

  • int omp_get_thread_num(void)获取并行域中当前线程的线程
  • int omp_get_num_threads(void)获取当前并行域使用的线程数

14.2 共享任务结构

OpenMP有三种典型的共享任务结构:

  • for:在线程组中共享一个循环的多次迭代(数据并行模式)
  • sections:把任务划分成离散段,每段由一个线程执行(功能并行模式)
  • single:指定串行执行

注意:共享任务结构入口处没有同步障,但出口处有一个隐含的同步障

(1)for

编译制导的for语句指令紧跟它的循环语句由线程组并行执行,语法格式为:

schedule指定划分方式,chunk指定size,若未指定则尽量平均分配

for编译制导语句必须在OpenMP并行域中,以向量加法举例:

(2)sections & single

sections编译制导语句可以作为任务划分方式,single编译制导语句用于标记非线程安全语句的串行化,略

(3)parallel for

与编译制导for的区别在于编译制导parallel for表明一个包含单独for语句的并行域,因此它不必在并行域中

上面的向量加法可以改写成编译制导parallel for的形式:

14.3 同步结构

OpenMP提供很多同步控制编译制导语句,注意它们必须在并行域中才能使用

(1)master

master编译制导语句制定代码段只有主线程执行:

(2)critical

critical编译制导语句指定代码段为临界区,仅有一个线程能够进入临界区,其他线程被阻塞

(3)barrier

barrier编译制导语句显式地声明一个同步障,所有线程均到达同步障后菜继续执行

(4)atomatic

atomatic编译制导语句指定代码段为原子执行,表示该操作必须由一个线程原子执行,它只能作用于自增语句

14.4 数据域属性

OpenMP是共享存储模型,因此我们需要指定并行域中出现的变量是共享还是私有,大多数变量默认是共享的

(1)private

private子句表示变量是线程私有的(必须在这些变量声明后使用),那么这条编译制导语句会为每个线程复制一个私有副本,一个线程对private变量操作对其他线程是不可见的

最常用的private变量就是for循环里的循环控制变量i

(2)shared

shared子句指定变量是所有线程共享的,变量访问正确性由程序员保证

(3)reduction

reduction子句指定变量是规约的,并行段初始为所有线程创建一个副本,并行段结束时根据指定的operation对私有副本进行规约,最后存在改变量的全局值中

14.5 编程实例

举出一个用并行规约求π的OpenMP简例:


Ch15 分布存储系统并行编程——MPI编程

MPI是一种消息传递接口的标准,适用于分布式存储系统的编程模型

与OpenMP不同的是,MPI是多进程的并行模式,运行时需要在外部指定开启进程数,并且是用SPMD的编程风格去模拟MPMD的编程风格(用进程 区别),不会FORK-JOIN而是通过消息传递同步

15.1 MPI基本函数

(1)启动函数

完成MPI启动,进入MPI并行环境:

直接把main函数的命令行传入参数argc和argv传入MPI_Init即可

(2)结束函数

完成MPI结束,退出MPI并行环境:

(3)获取进程编

获取MPI进程编 来区别不同的进程:

用取址运算&rank传入一个指针指定rank结果写入的地址

MPI_Comm是MPI通信域,通信域相当于消息传递范围,一般使用全局通信域MPI_COMM_WORLD

(4)获取总进程数

获取总进程数来,一般用于划分任务比例:

和rank一样,用取址运算&size传入一个指针指定size结果写入的地址

(5)发送消息函数

该函数把起始地址为buf的count个datatype类型的数据发送给目标进程,int是目标进程进程 ,tag是这个消息的标签,comm指定消息传播的通信域

(6)接收消息函数

该函数从comm域中原进程source处接收标记是tag的消息,把该消息存储到起始地址为buf的count个datatype类型的数据缓冲区中

从发送消息和接收消息的API可以看出消息长度是由程序员手动维护的,一定要保证同tag发送的消息长度是一致的,否则会引发的缓冲区溢出

15.2 MPI点对点通信

MPI_Send和MPI_Recieve都是点对点通信,MPI点对点通信支持多种通信模式和通信机制

(1)通信模式

通信模式包括了发送方和接收方的缓存管理和同步方式,MPI有以下四种通信方式:

  • 标准通信模式:MPI决定是否对发送数据缓存,而不是用户决定(大多数);发送操作不管接收操作是否启动都可以执行
  • 缓冲通信模式:需要申请一块缓冲区,发送方不必管接收方是否启动都可执行
  • 同步通信模式:同步发送直到接受方接受过程已经启动才能返回
  • 就绪通信模式:发送方必须等到接收方开始接收后才能发送,否则出错
(2)通信机制

发送和接收包括阻塞和非阻塞两种通信机制,阻塞必须等待通信完成后才能返回,而非阻塞不必等待操作是否完成就能返回

15.3 MPI集群通信

集群通信是指一个进程组(同一个通信域中)中所有进程都要参加的全局通信操作,MPI提供一套完整的API来实现集群的通信、聚集和同步等工作

(1)广播通信

进程 为root的进程给comm域内所有进程(包括自己)发送一条长度为count的datatype类型的消息,address既是root发送数据的地址,也是所有进程接收数据的地址

(2)收集通信

进程 为root的进程从comm域内所有进程(包括自己)收集一条消息,并且把数据依次存放在recvAddress为起始地址的长为count * size的datatype类型的缓冲区中

这个API比较奇怪的是给出了两个count和type,实际上这两个值必须保持一致啊/p>

(3)散播通信

进程 为root的进程从comm域内所有进程(包括自己)发送一条消息,这些发送消息依次排列在sendAddress为起始地址的长为count * size的datatype类型的缓冲区中

Scatter是Gather的反操作,之前提到的疑问同样存在

(4)全局收集通信

全局收集相当于每个进程都执行一次Gather,每个进程send一条消息,每个进程接受size条消息依次存放在接收缓冲区中,Allgather后所有进程接受缓冲区的内容一致

(5)全局交换通信

全局交换相当于每个进程都进行一次Scatter,进程按进程 依次排列所有进程Scatter的消息,每个进程像所有进程发送发送缓冲区中依次排列的size条消息,每个进程接收缓冲区中接收来自所有进程各一个的消息,共size条

(6)同步障

显式地设置一个同步障

(7)规约聚合

该API定义了一个规约聚合操作,Op是规约运算操作(MPI内置),规约后保存在receiveAddress地址中

(8)扫描聚合

扫描聚合是一种特殊的规约聚合,它让所有进程都做一次规约,进程 为i的进程对进程 在它前面的所有进程(0,…,i)做一次规约

15.4 MPI编程实例

下面是一个MPI实现计算的程序:

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2015年5月8日
下一篇 2015年5月8日

相关推荐