OpenMP简介

一、Openmp是什么:

OpenMP制导指令将C语言扩展为一个并行语言,但OpenMP本身不是一种独立 的并行语言,而是为多处理器上编写并行程序而设计的、指导共享内存多线程并行的编译制导指令和应用程序编程接口(API),可在C、C++和Fortran 77/90/95中应用,并在串行代码中以编译器可识别的注释形式出现。OpenMP标准由一些具有国际影响力的软件和硬件厂商共同定义和提出,是一种在共享存储体系结构上的可移植编程模型,广泛应用于UNIX、Linux、Windows等多种平台上。 

OpenMP包含三个基本要素:1.编译制导指令 2.运行库 3.环境变量

OpenMP是开放式多处理( Open Multi-Processing )的缩写。  


二、Openmp目的:

1、标准化 :提供各种共享内存架构/平台的标准 由一组主要的计算机硬件和软件供应商共同定义和认可。

2、精益平均 :建立一个简单的和有限的程序共享内存机器指令集。  重要的并行,可以通过只使用3个或4个指令来实现。

3、使用方便 :提供递增地并行化串行程序的能力,不像消息传递库通常需要一种极端的方式  提供实现粗粒度和细粒度并行的能力 

4、可移植性:API支持C、C++和Fortran

最主要的平台已实现包括Unix / Linux平台和Windows


三、OpenMP执行模式:OpenMP的执行模式采用fork-join的形式,其中fork创建新线程或者唤醒已有线程;join即多线程的汇合

fork-join执行模式在刚开始执行的时候,只有一个称为“主线程”的运行线程存在。主线程在运行过程中,当遇到需要进行并行计算的时候,派生出线程来执行并行任务。在并行执行的时候,主线程和派生线程共同工作。在并行代码执行结束后,派生线程退出或者阻塞,不再工作,控制流程回到单独的主线程中。

并行域(Paralle Region)定义为在成对的fork和join之间的区域,称为并行域,它既表示代码也表示执行时间区间。

OpenMP线程定义为在OpenMP程序中用于完成计算任务的一个执行流的执行实体,可以是操作系统的线程也可以是操作系统上的进程。


四、OpenMP编程要素:1、编译制导 2、API函数 3、环境变量

OpenMP编程模型以线程为基础,通过编译制导指令来显式地指导并行化,OpenMP为编程人员提供了以上三种编程要素来实现对并行化的完善控制。


五、编译制导

在 C/C++程序中,OpenMP 的所有编译制导指令是以#pragma omp 开始,后面跟具体的功能指令(或命令),其具有如下形式:#pragmaomp 指令 [子句[, 子句] ···]

支持 OpenMP 的编译器能识别、处理这些制导指令并实现其功能。其中指令或命令是可以单独出现的, 而子句则必须出现在制导指令之后。制导指令和子句按照功能可以大体上分成四类:1、并行域控制类 2、任务分担类 3、同步控制类 4、数据环境类

并行域控制类指令用于指示编译器产生多个线程以并发执行任务,任务分担类指令指示编译器如何给各个并发线程分发任务, 同步控制类指令指示编译器协调并发线程之间的时间约束关系,数据环境类指令处理并行域内外的变量共享或私有属性以及边界上的数据传送操作等。


 parallel:用在一个结构块之前,表示这段代码将被多个线程并行执行;

 for:用于 for 循环语句之前,表示将循环计算任务分配到多个线程中并行执行,以实现任务分担,必须由编程人员自己保证每次循环之间无数据相关性;

 parallel for:parallel 和 for 指令的结合,也是用在 for 循环语句之前,表示 for循环体的代码将被多个线程并行执行,它同时具有并行域的产生和任务分担两个功能;

 sections:用在可被并行执行的代码段之前,用于实现多个结构块语句的任务分担, 可并行执行的代码段各自用 section 指令标出 (注意区分 sections 和 section) ;

 parallel sections:parallel 和 sections 两个语句的结合,类似于 parallel for;

OpenMP的子句有以下一些:

 private:指定一个或多个变量在每个线程中都有它自己的私有副本;

 firstprivate:指定一个或多个变量在每个线程都有它自己的私有副本,并且私有变量要在进入并行域或任务分担域时,继承主线程中的同名变量的值作为初值;

 lastprivate:是用来指定将线程中的一个或多个私有变量的值在并行处理结束后复制到主线程中的同名变量中,负责拷贝的线程是 for 或 sections 任务分担中的最后一个线程;

 reduction: 用来指定一个或多个变量是私有的, 并且在并行处理结束后这些变量要执行指定的归约运算,并将结果返回给主线程同名变量;

 nowait:指出并发线程可以忽略其他制导指令暗含的路障同步;

 num_threads:指定并行域内的线程的数目;

 schedule:指定 for 任务分担中的任务分配调度类型;

 shared:指定一个或多个变量为多个线程间的共享变量;

 ordered:用来指定 for 任务分担域内指定代码段需要按照串行循环次序执行;

 copyprivate:配合 single 指令,将指定线程的专有变量广播到并行域内其他线程的同名变量中;

 copyin:用来指定一个threadprivate 类型的变量需要用主线程同名变量进行初始化;

 default:用来指定并行域内的变量的使用方式,缺省是 shared。这些制导指令将会在后面的编程部分进行详细说明解释。

 

OpenMP还提供了一组 API 函数用于控制并发线程的某些行为,

下面列出 OpenMP 2.5 所有的 API 函数:

OpenMPAPI  函数

omp_in_parallel  判断当前是否在并行域中

omp_get_thread_num  返回线程号

omp_set_num_threads  设置后续并行域中的线程个数

omp_get_num_threads  返回当前并行区域中的线程数

omp_get_max_threads  获取并行域可用的最大线程数目

omp_get_num_procs  返回系统中处理器个数

omp_get_dynamic  判断是否支持动态改变线程数目

omp_set_dynamic  启用或关闭线程数目的动态改变

omp_get_nested  判断系统是否支持并行嵌套

omp_set_nested  启用或关闭并行嵌套

omp_init(_nest)_ lock  初始化一个(嵌套)锁

omp_destroy(_nest)_lock  销毁一个(嵌套)锁

omp_set(_nest)_lock  (嵌套)加锁操作

omp_unset(_nest)_lock  (嵌套)解锁操作

omp_test(_nest)_lock  非阻塞的(嵌套)加锁

omp_get_wtime  获取 wall time 时间

omp_set_wtime  设置 wall time 时间

 

OpenMP规范中定义了一些内部控制变量 ICV(Internal Control Variable),用于表示系统的属性、能力和状态等,可以通过 OpenMP API 函数访问也可以通过环境变量进行修改。但是变量的具体名字和实现方式可以由各个编译器自行决定。

 

OpenMP规范定义了一些环境变量,可以在一定程度上控制 OpenMP 程序的行为。 以下是开发过程中常用的环境变量

1.  OMP_SCHEDULE:用于 for 循环并行化后的调度,它的值就是循环调度的类型;

2.  OMP_NUM_THREADS:用于设置并行域中的线程数;

3.  OMP_DYNAMIC:通过设定变量值,来确定是否允许动态设定并行域内的线程数;

4.  OMP_NESTED:指出是否可以并行嵌套。

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值