OpenMP是一种面向共享内存以及分布式共享内存的多处理器多线程的并行编程语言。
OpenMP编程模型
Fork-Join
- 开始执行时,只有主线程存在
- 主线程运行过程中,当遇到需要并行计算的时候,Fork新线程来并行执行任务。
- 并行执行时,主线程和派生线程共同工作
- 并行部分执行结束后,派生线程退出并挂起,不再工作,控制流回到单独的主线程中(Join)
编译制导语句
编译制导语句是在编译器编译程序时,识别特定的、包含OpenMP程序语义的注释
在C/C++程序中,用
#pragma omp parallel来标识一段并行程序块。在一个无法识别OpenMP语义的普通编译器中,这些特定的注释会被视作普通的注释而被忽略。
并行域
并行域中的代码被所有线程执行
|
|
示例:
|
|
共享任务
共享任务结构将它所包含的代码划分给线程组的各成员来执行。
for语句
for语句:指定紧随它的循环语句必须由线程组并行执行
|
|
schedule(type, [,chunck]):描述如何将循环的迭代划分给线程组中的线程,其中chunck表示每个线程分配的计算量(未指定则尽可能平均分配),type则有static(静态划分)和dynamic(动态划分)
示例:
|
|
sections语句
sections编译制导语句指定内部的代码被划分给线程组中的各线程,不同的section由不同的线程执行
|
|
示例:
|
|
single语句
single编译制导语句指定内部代码只有线程组中的一个线程执行,线程组中没有执行single语句的线程会一直等待代码块的结束(使用nowait子句除外)
|
|
示例:
|
|
parallel for语句
parallel for编译制导语句表明一个并行域包含一个独立的for语句
|
|
示例:
|
|
parallel sections语句
parallel sections编译制导语句表明一个并行域包含单独的一个section语句
|
|
示例:
|
|
同步
| 制导语句 | 作用 | 格式 |
|---|---|---|
| master | 指定代码段只有主线程执行 | #pragma omp master newline |
| critical | 表明域中的代码一次只能在一个线程执行,其他线程被阻塞在临界区 | #pragma omp critical [name] newline |
| barrier | 同步一个线程组中的所有线程,先到达的在此阻塞,等待其他线程 | #pragma omp barrier newline |
| atomic | 指定特定的存储单元将被原子更新 | #pragma omp atomic newline |
| flush | 用以标识一个同步点,用以确保所有的线程看到一致的存储器视图 | #pragma omp flush (list) newline |
| order | 指出其所包含循环的执行按照循环次序进行,任何时候只能有一个线程执行被ordered限制的部分 | #pragma omp ordered newline |
数据域
数据域共享属性子句
| 子句 | 作用 | 格式 |
|---|---|---|
| private | 表示它列出的变量对于每个线程是局部的 | private(list) |
| shared | 表示它所列出的变量被线程组中的所有线程共享,所有线程都能对它进行读写访问 | shared(list) |
| default | 让用户自行规定在一个并行域的静态范围内所定义的变量的缺省作用范围 | default(shared | none) |
| firstprivate | private子句的超集,对变量作原子初始化 | firstprivate(list) |
| lastprivate | private子句的超集,将变量从最后的循环迭代或段复制给原始的变量 | lastprivate(list) |
| reduction | 使用指定的操作对其列表中出现的变量进行规约,初始时每个线程保留一份私有拷贝,结构尾部对变量进行规约并更新全局值 | reduction(operator: list) |
| threadprivate | 使一个全局文件作用域的变量在并行域内变为每个线程私有,复制一份私有拷贝 | #pragma omp threadprivate (list) newline |
| copyin | 为线程组中所有线程的threadprivate变量赋相同的值,主线程中该变量的值作为初始值 | copyin(list) |
| copyprivate | 用一个私有变量将一个值从一个线程广播到执行同一个并行区域的其他线程 | copyprivate(list) |
运行库与环境变量
OpenMP标准定义了一个应用编程接口来调用库中的函数
对于C/C++,需要在程序开头引用文件<omp.h>
| 环境变量 | 含义 |
|---|---|
OMP_SCHEDULE |
线程调度类型,只能用到for,parallel for中 |
OMP_NUM_THREADS |
定义执行中最大的线程数 |
OMP_DYNAMIC |
通过设定变量值TRUE或FALSE来确定是否动态设定并行域执行的线程数 |
OMP_NESTED |
确定是否可以并行嵌套 |