OpenMP 参考(子句)

 

Data Scope Attribute Clauses

  • 也叫 Data-sharing 属性子句
  • 对数据作用域的理解与应用是OpenMP编程的重要因素
  • 因为OpenMP是基于内存共享编程模型的,很多变量都默认共享了
  • 全局变量包括:
    • Fortran: COMMON , SAVE 变量, MODULE 变量
    • C: 文件范围内的变量, static
  • 私有变量包括:
    • 循环索引变量
    • 被并行区域调用的子程序的栈(stack)变量
    • Fortran:语句块内的自动变量(automatic
  • OpenMP的数据作用域属性子句常用来显式定义变量的作用域,包括:
    • PRIVATE
    • FIRSTPRIVATE
    • LASTPRIVATE
    • SHARED
    • DEFAULT
    • REDUCTION
    • COPYIN
  • 数据作用域子句用来联合几个指令(PARALLELDO/forSECTIONS)来控制被封装变量的作用域。
  • 这些构造提供了在执行并行构造时控制数据环境的能力
    • 定义了在程序的串行化区域的哪些数据变量以何种方式传递给程序的并行区域
    • 定义了哪些变量应该对并行块的所有线程可见,哪些变量应该被所有线程私有分配
  • 数据作用域属性子句只有在它的词法/静态范围内才有效
  • 重要:请参考最新的OpenMP文献来获得更多的重要细节和关于此主题的详述
  •  方便起见,提供了Clauses / Directives Summary Table 

PRIVATE 子句

目的:

  • PRIVATE子句声明在它列表中的变量对各个线程都是私有的

格式:

Fortran

 

PRIVATE (list)

C/C++

 

private (list)

注意:

  • PRIVATE变量的有如下行为:
    • 对于组内的每个线程,相同类型的新对象都要被声明一次
    • 对原始对象的所有引用都被指向新线程的引用替换
    • 每个线程都假定被声明为PRIVATE的变量未初始化
  • 对比PRIVATETHREADPRIVATE

 

PRIVATE

THREADPRIVATE

数据项

C/C++: 变量
Fortran:
变量或者公共块

C/C++: 变量
Fortran:
公共块

声明位置

在区域或者工作共享组的开头

在使用块或者全局文件作用域的程序声明里

持久化?

范围

语法性的-除非当作参数传递给子程序

动态

初始化

使用 FIRSTPRIVATE

使用 COPYIN

问题:

 

For the C/C++ and Fortran THREADPRIVATE example codes, what output would you expect for alpha[3] and beta[3]? Why?



SHARED 子句

目的:

  • SHARED子句声明在其列表中的变量被线程组中的所有线程共有

格式:

Fortran

 

SHARED (list)

C/C++

 

shared (list)

注意:

  • 一个共享变量只存在一个内存位置,并且所有线程都可以对此地址读写
  • 确保多线程正确访问SHARED变量是程序员的职责(比如CRITICAL段)

DEFAULT 子句

目的:

  • DEFAULT子句允许用户在任何并行区域为所有变量指定词法范围的默认作用域

格式:

Fortran

 

DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE)

C/C++

 

default (shared | none)

注意:

  • 使用PRIVATE, SHARED, FIRSTPRIVATE, LASTPRIVATE, REDUCTION 子句可以使指定的变量不受此子句的影响
  • C/C++ OpenMP规范并不包含private或者firstprivate作为可能的DEFAULT。然而,实际实现时可能会提供此选项。
  • NONE作为default需要程序员明确范围内的所有变量

限制:

  • 一个PARALLEL指令只能被一个DEFAULT子句修饰

FIRSTPRIVATE 子句

目的:

  • FIRSTPRIVATE子句的行为相当于能自动初始化其列表中的变量的PRIVATE子句

格式:

Fortran

 

FIRSTPRIVATE (list)

C/C++

 

firstprivate (list)

注意:

  • 列表中的变量初始化的顺序与进入并行或工作共享构造的他们的原始对象顺序一致

LASTPRIVATE 子句

目的:

  • LASTPRIVATE子句的作用相当于在循环迭代或者区域结束时将变量的值赋予原始变量对象的PRIVATE子句

格式:

Fortran

 

LASTPRIVATE (list)

C/C++

 

lastprivate (list)

注意:

  • 拷贝回原始变量对象的值是从封装构造的最后一次迭代(顺序)或者区域取得的

例如,执行一个DO代码段最后一次迭代,或者一个SECTIONS上下文的最后一个SECTION的小组成员,用其值完成这次拷贝


COPYIN 子句

目的:

  • COPYIN子句将THREADPRIVATE中的变量为所有线程组中的线程赋予同样的值

格式:

Fortran

 

COPYIN (list)

C/C++

 

copyin  (list)

注意:

  • list)包含了要拷贝的变量。对于Fortran,(list)可以包含公共块的命名和已命名变量
  • 主线程的变量作为拷贝源。进入并行构造的时候,线程组用它的值来初始化。

COPYPRIVATE 子句

目的:

  • COPYPRIVATE子句用来由单个线程将私有变量的值广播到其他线程中的实例
  • SINGLE指令关联
  • 查看最近的OpenMP规范文档获取更多信息与示例

格式:

Fortran

 

COPYPRIVATE (list)

C/C++

 

copyprivate  (list)


REDUCTION 子句

目的:

  • REDUCTION子句对在其列表中的变量执行一次约简(reduction
  • 对列表中的每个变量创建各个线程的私有拷贝。约简结束时,约简变量被应用到相关共享变量的所有私有拷贝,并且最终的结果被写到其全局共享变量。

格式:

Fortran

 

REDUCTION (operator|intrinsic: list)

C/C++

 

reduction (operator: list)

示例: REDUCTION - Vector Dot Product:

  • 并行循环迭代为线程组中的线程均分为同等大小的块(SCHEDULE STATIC
  • 在并行循环构造结束时,所有的线程将把他们得到的值加到主线程中的全局拷贝上

Fortran - REDUCTION Clause Example


 

       PROGRAM DOT_PRODUCT

 

       INTEGER N, CHUNKSIZE, CHUNK, I

       PARAMETER (N=100)

       PARAMETER (CHUNKSIZE=10)

       REAL A(N), B(N), RESULT

 

!      Some initializations

       DO I = 1, N

         A(I) = I * 1.0

         B(I) = I * 2.0

       ENDDO

       RESULT= 0.0

       CHUNK = CHUNKSIZE

 

!$OMP  PARALLEL DO

!$OMP& DEFAULT(SHARED) PRIVATE(I)

!$OMP& SCHEDULE(STATIC,CHUNK)

!$OMP& REDUCTION(+:RESULT)

 

       DO I = 1, N

         RESULT = RESULT + (A(I) * B(I))

       ENDDO

 

!$OMP  END PARALLEL DO NOWAIT

 

       PRINT *, 'Final Result= ', RESULT

       END

· 

C / C++ - reduction Clause Example


 

#include

 

main ()  {

 

int   i, n, chunk;

float a[100], b[100], result;

 

/* Some initializations */

n = 100;

chunk = 10;

result = 0.0;

for (i=0; i < n; i++)

  {

  a[i] = i * 1.0;

  b[i] = i * 2.0;

  }

 

#pragma omp parallel for      / 

  default(shared) private(i)  / 

  schedule(static,chunk)      / 

  reduction(+:result) 

 

  for (i=0; i < n; i++)

    result = result + (a[i] * b[i]);

 

printf("Final result= %f/n",result);

 

}

限制:

  • 列表中的变量必须是数值变量,不能是数据或者结构类型变量。而且,他们必须在封装的上下文中被声明为SHARED
  • 约简操作可能也无法与实数相关
  • Reduction operations may not be associative for real numbers.
  • 规定REDUCTION子句只能用于区域(region)或者工作共享构造,而且语句中的约简变量要遵守以下形式:

Fortran

C / C++

x = x operator expr
x = expr operator x
(except subtraction)
x = intrinsic(x, expr)
x = intrinsic(expr, x)

x = x op expr
x = expr op x
(except subtraction)
x binop = expr
x++
++x
x--
--x

x list中的数值变量
expr
为不引用x的数值表达式

intrinsic MAX, MIN, IAND, IOR, IEOR
operator
+, *, -, .AND., .OR., .EQV., .NEQV.

x list中的数值变量
expr
为不引用x的数值表达式

op 不是重载的(overloaded, 为下面之一: +, *, -, /, &, ^, |, &&, ||
binop
不是重载的(overloaded),为下面之一: +, *, -, /, &, ^, |

 

子句 / 指令 总结

  • 下面的表格总结了哪些子句可被哪些OpenMP指令接受(黑色表示否)

子句

指令

PARALLEL

DO/for

SECTIONS

SINGLE

PARALLEL
DO/for

PARALLEL
SECTIONS

IF

 

 

 

 

 

 

PRIVATE

 

 

 

 

 

 

SHARED

 

 

 

 

 

 

DEFAULT

 

 

 

 

 

 

FIRSTPRIVATE

 

 

 

 

 

 

LASTPRIVATE

 

 

 

 

 

 

REDUCTION

 

 

 

 

 

 

COPYIN

 

 

 

 

 

 

COPYPRIVATE

 

 

 

 

 

 

SCHEDULE

 

 

 

 

 

 

ORDERED

 

 

 

 

 

 

NOWAIT

 

 

 

 

 

 

  • 下面的OpenMP指令不接受子句:
    • MASTER
    • CRITICAL
    • BARRIER
    • ATOMIC
    • FLUSH
    • ORDERED
    • THREADPRIVATE
  • 实现时,关于哪些子句被哪些指令支持可能(肯定)会有差异

 

指令绑定和嵌套规则

 

该章节主要作为管理OpenMP指令和绑定规则的快速参考。用户应该查阅它们的实现文档和OpenMP标准获得更多的条款说明和限制。

  • 如果没有特别指出,规则同时适用于FortranC/C++OpenMP实现
  • 注意:FortranAPI也定义了一些数据环境规则,这里就不重复提及了

指令绑定:

  • The DO/for, SECTIONS, SINGLE, MASTER BARRIER 指令绑定到动态封装的PARALLEL, 如果存在. 如果当前没有要被执行的PARALLEL区域,这些指令就没有效果
  • ORDERED指令绑定到动态封装的DO/for
  • ATOMIC指令在所有线程中执行独占访问,而不仅仅是当前线程组
  • CRITICAL指令在所有线程中执行独占访问,而不仅仅是当前线程组
  • 指令不会绑定到超出最近那个PARALLEL封装的任何其他指令

指令嵌套:

  • 除非启用嵌套并行处理,一个动态进入另一个PARALLEL指令的PARALLEL指令逻辑上建立的新线程组只有一个当前线程组成。
  • 绑定到同一个PARALLELDO/for, SECTIONS, SINGLE 指令,不允许相互嵌套
  • DO/for, SECTIONS, SINGLE 指令不允许在CRITICAL, ORDERED and MASTER 区域的动态范围内.
  • 相同命名的CRITICAL指令不允许相互嵌套
  • BARRIER 指令不允许在DO/for, ORDERED, SECTIONS, SINGLE, MASTER CRITICAL 区域的动态范围内.
  • MASTER 指令不允许在DO/for, SECTIONS SINGLE 指令的动态范围内.
  • ORDERED 指令不允许在CRITICAL 区域的动态范围内.
  • 任何允许在一个PARALLEL区域动态执行的指令也被允许在一个PARALLEL区域外执行。当指令在一个用户指定的并行区域外动态执行时,只受由主线程组成的线程组的影响。

你可能感兴趣的:(并行)