OpenMP 参考 (指令格式)
来源:互联网 发布:开源电子网 知乎 编辑:程序博客网 时间:2024/05/28 23:10
OpenMP 指令格式
C / C++ 指令格式
格式:
#pragma omp
directive-name
[clause, ...]
newline
OpenMP C/C++ 指令都需要.
有效OpenMP 指令. 必须在pragma指令后,在 clauses指令前。
可选. 除非有另外的限制,子句可以任意顺序, 根据需要重复。
必需. 位于被这个指令包围的结构块之前。
示例:
#pragma omp parallel default(shared) private(beta,pi)
规则:
- 区分大小写
- 指令遵守C/C++编译器指令标准
- 每条指令只能有一个指令名称
- 每条指令适用于最少一条被结构块包围的语句
- 常指令可以在一条指令行结束后,用"/"连接
Fortran 指令格式
格式: (不区分大小写)
sentinel
directive-name
[clause ...]
所有的Fortan OpenMP指令必须以哨兵开始。 接受的哨兵依赖于Fortan源程序。可能的形式:
!$OMP
C$OMP
*$OMP
有效OpenMP指令,必须在哨兵和子句之间。
可选.除非有另外的限制,子句可以任意顺序, 根据需要重复。
示例:
!$OMP PARALLEL DEFAULT(SHARED) PRIVATE(BETA,PI)
固定格式源:
- !$OMP C$OMP *$OMP 作为接受的哨兵,必须出现在第一列
- 所有Fortan的固定规则,比如行长度,空格,继续,注释等,对整条指令都适合
- 初始指令行必须在第六列包含一个空格/0
- 接下来的指令行在第六列必须包含一个非空格/0
自由格式源:
- !$OMP 是唯一的接受哨兵. 可以出现在任何列,但必须前面只能有空格
- 所有Fortan的自由规则,比如行长度,空格,继续,注释等,对整条指令都适合
- 初始指令行之后必须有个空格
- 后续行的每一行,最后都必须有个作为非空白字符的符号
规则:
- 注释不能作为指令出现在同一行
- 每条指令只能指定一个指令名称
- 启用了OpenMP的Fortran编译器通常包含一条命令行选项,用来指示编译器激活并解释所有的OpenMP指令
- 几个Fortran OpenMP指令成对出现,格式如下所示. "end"是可选的,但为了提高可读性,建议不要省略.
!$OMP directive
[ structured block of code ]
!$OMP end directive
OpenMP 指令
指令作用域
不罗嗦了...
静态范围:
- 代码由一条OpenMP的指令开头,写在一个结构块的开始和结束之间
- 指令的静态范围不能跨越多个例程或代码文件
孤立指令:
- 看起来和另外一个包围指令没有关系的指令被称为孤立指令。 它存在于另外一个指令的静态范围之外。
- 跨越多个例程(也许是代码文件)
Dynamic Extent动态范围:
- 指令的动态范围包括它的静态范围以及孤立指令范围.
Example:
PROGRAM TEST
...
!$OMP PARALLEL
...
!$OMP DO
DO I=...
...
CALL SUB1
...
ENDDO
...
CALL SUB2
...
!$OMP END PARALLEL
SUBROUTINE SUB1
...
!$OMP CRITICAL
...
!$OMP END CRITICAL
END
SUBROUTINE SUB2
...
!$OMP SECTIONS
...
!$OMP END SECTIONS
...
END
静态范围
并行区域内的DO 指令
孤立指令
并行区域外的CRITICAL 和SECTIONS 指令
动态范围
CRITICAL 和SECTIONS 指令在DO 和PARALLEL 指令的动态范围内.
为什么这一点很重要?
- OpenMP 制定了一系列关于指令关联(绑定)与嵌套的范围规则
- 如果OpenMP的绑定与嵌套规则被忽略,可能导致程序非法或不正确
- 有关细节请参考Directive Binding and Nesting Rules
并行区域结构
作用:
- 并行区域是一块能被多个线程执行的代码。下面是基本的OpenMP并行结构:
格式:
Fortran
!$OMP PARALLEL [clause ...]
IF (scalar_logical_expression)
PRIVATE (list)
SHARED (list)
DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE)
FIRSTPRIVATE (list)
REDUCTION (operator: list)
COPYIN (list)
NUM_THREADS (scalar-integer-expression)
block
!$OMP END PARALLEL
C/C++
#pragma omp parallel [clause ...] newline
if (scalar_expression)
private (list)
shared (list)
default (shared | none)
firstprivate (list)
reduction (operator: list)
copyin (list)
num_threads (integer-expression)
structured_block
注意:
- 当线程遇到一个PARALLEL指令,它创建一组线程并成为主控者。主控者也属于这组线程,并在组内的线程号为0
- 从这个并行区域开始,代码被复制并被所有线程执行
- 并行区域结束时有个隐藏的关卡,只有主控线程能在此之后继续执行
- 并行区域内的任何线程终止都会终止所有的线程。工作不能继续,直到这点被消除定义。
有多少线程?
- 并行区域内的线程数量是由以下因素决定的,按优先级排序:
- IF 子句的值
- NUM_THREADS 子句的设置
- 使用 omp_set_num_threads() 库函数
- OMP_NUM_THREADS 环境变量
- 默认实现-一般是一个计算机的CPU数量,也可能是动态的(参考下节).
- 线程编号从0 (主线程) to N-1
动态线程:
- 用 omp_get_dynamic() 库函数检测动态线程是否被启用.
- 如果支持动态线程,下面两个方法可以启用动态线程:
- omp_set_dynamic() 库例程
- 设置 OMP_DYNAMIC 环境变量为TRUE
嵌套并行区域:
- 使用 omp_get_nested() 库函数检测嵌套并行区域是否被启用.
- 如果支持嵌套并行区域,可以用下面两个方法启用:
- omp_set_nested() 库例程
- 设置OMP_NESTED 环境变量为TRUE
- 如果不支持,嵌套并行区域默认将生成一个由单个线程组成的新组。
子句:
- IF 子句:如果存在,值必须为 .TRUE. (Fortran) 或者非零(C/C++) 以使能创建一组线程. 否则,此区域将被主线程串行执行.
- 在Data Scope Attribute Clauses 章节,将详细讨论剩下的子句.
限定:
- 一个并行区域必须是一个结构块,不能跨越多个程序或者代码文件
- 进入或者离开一个并行区域的分支都是非法的
- 只允许一个IF子句
- 只允许一个NUM_THREADS子句
Example: Parallel Region
- "Hello World" 程序
- 每一个线程都执行了并行区域的全部代码
- OpenMP 库例程用来获得线程标识与总线程数量
Fortran - Parallel Region Example
PROGRAM HELLO
INTEGER NTHREADS, TID, OMP_GET_NUM_THREADS,
+ OMP_GET_THREAD_NUM
C Fork a team of threads with each thread having a private TID variable
!$OMP PARALLEL PRIVATE(TID)
C Obtain and print thread id
TID = OMP_GET_THREAD_NUM()
PRINT *, 'Hello World from thread = ', TID
C Only master thread does this
IF (TID .EQ. 0) THEN
NTHREADS = OMP_GET_NUM_THREADS()
PRINT *, 'Number of threads = ', NTHREADS
END IF
C All threads join master thread and disband
!$OMP END PARALLEL
END
·
C / C++ - Parallel Region Example
#include <omp.h>
main () {
int nthreads, tid;
/* Fork a team of threads with each thread having a private tid variable */
#pragma omp parallel private(tid)
{
/* Obtain and print thread id */
tid = omp_get_thread_num();
printf("Hello World from thread = %d/n", tid);
/* Only master thread does this */
if (tid == 0)
{
nthreads = omp_get_num_threads();
printf("Number of threads = %d/n", nthreads);
}
} /* All threads join master thread and terminate */
}
- OpenMP 参考 (指令格式)
- OpenMP 参考(指令详解)
- OpenMP 参考(指令详解)
- OpenMP 参考(简介)
- OpenMP 参考(子句)
- OpenMP 参考 (同步构造)
- OpenMP Tutorial学习笔记(3)OpenMP指令之指令格式和指令范围
- OpenMP 参考(子句)
- OpenMP加速学习参考
- openmp 参考博文
- OpenMP常用指令释义
- OpenMP中的critical指令
- OpenMP指令之THREADPRIVATE指令
- 格式(可以参考)
- OpenMP Tutorial学习笔记(4)OpenMP指令之同步构造(Parallel)
- OpenMP Tutorial学习笔记(6)OpenMP指令之组合共享工作构造(Combined Work-Sharing)
- OpenMP Tutorial学习笔记(7)OpenMP指令之任务构造(Task Constructs)
- OpenMP Tutorial学习笔记(8)OpenMP指令之同步构造(Synchronization Constructs)
- oracle有条件显示
- 保存整个网页
- CSS实现完美垂直居中
- CSS实现完美垂直居中
- Multi-Touch 开发资源汇总
- OpenMP 参考 (指令格式)
- Net设计模式实例之单例模式( Singleton Pattern)
- EditPlus3.21注册码
- andorid API TestDemo 解析
- qemu虚拟磁盘的管理
- jsp 页面中点击删除按钮后弹出确认对话框
- 如何重新安装的Automator
- 如何解决java.util.Date 获取的不是当前时间
- ucos中如何定义全局变量