现在的位置: 首页 > 综合 > 正文

OpenMP 参考 (同步构造)

2013年08月16日 ⁄ 综合 ⁄ 共 1577字 ⁄ 字号 评论关闭

 

同步构造

  • 考虑一个简单的示例,在两个不同处理器上的两个线程试图同时增加变量x的值(假定x被初始化为0):

THREAD 1:

 

increment(x)

{

    x = x + 1;

}

THREAD 1:

 

10  LOAD A, (x address)

20  ADD A, 1

30  STORE A, (x address)

THREAD 2:

 

increment(x)

{

    x = x + 1;

}

THREAD 2:

 

10  LOAD A, (x address)

20  ADD A, 1

30  STORE A, (x address)

  • 一种可能出现的执行顺序:

1.    线程一加载x到寄存器A

2.    线程二加载x到寄存器A

3.    线程一将寄存器A的值+1

4.    线程二将寄存器A的值+1

5.    线程一将寄存器A的值保存到x

6.    线程二将寄存器A的值保存到x

结果将会是1,而不是期望的2.(注:两个cpu,所以"寄存器 A"不是同一个)

  • 要避免这种情况,两个线程对x的增加操作必须同步来保证得到正确的结果
  • OpenMP提供了几种同步构造来控制一个线程处理与其他线程相关的执行

 

同步构造


MASTER
指令

目的:

  • MASTER指令指定一个只能被主线程执行的区域,其他的线程都将忽略这块代码区域
  • 这条指令没有相关隐式关卡

 

格式:

Fortran

 

!$OMP MASTER

 

   block

 

!$OMP END MASTER

C/C++

 

#pragma omp master  newline

 

   structured_block

限制:

  • 扩充MASTER 块是非法的

 

CRITICAL 指令

目的:

  • CRITICAL指令指定一块同一时间只能被一条线程执行的代码区域

格式:

Fortran

 

!$OMP CRITICAL [ name ]

 

   block

 

!$OMP END CRITICAL

C/C++

 

#pragma omp critical [ name ]  newline

 

   structured_block

注意:

  • 如果一条线程正在一个CRITICAL区域执行而另一个线程到达这个区域,并企图执行,那么它将会被阻塞,直到第一个线程离开这个区域.
  • 命名是可选项,使不同的CRITICAL区域共存:
    • 命名是全局标志符.具有相同命名的不同的CRITICAL区域被当作同一个区域
    • 所有未命名CRITICAL区域被当作同一个区域

 

限制:

  • 扩充CRITICAL 块是非法的.


Example: CRITICAL Construct

  • 所有的线程试图并行执行,但由于对x增加的代码被CRITICAL构造包围,在任何时刻均只能有一个线程对此进行读/增加/写操作

Fortran - CRITICAL Directive Example


 

      PROGRAM CRITICAL

 

      INTEGER X

      X = 0

 

!$OMP PARALLEL SHARED(X)

 

!$OMP CRITICAL

      X = X + 1

!$OMP END CRITICAL

 

!$OMP END PARALLEL

 

      END

· 

C / C++ - critical Directive Example


 

#include <omp.h>

 

main()

{

 

int x;

x = 0;

 

#pragma omp parallel shared(x)

  {

 

  #pragma omp critical

  x = x + 1;

 

  }  /* end of parallel section */

 

}

 

BARRIER 指令

目的:

  • BARRIER指令同步线程组中的所有线程
  • 到达一个BARRIER指令后,线程会原地等待其他的线程,然后恢复并行执行其后的代码

格式:

Fortran

 

!$OMP BARRIER

C/C++

 

#pragma omp barrier  newline

限制:

  • 线程组中的所有线程都将执行(不执行)BARRIER区域
  • 线程组中的所有线程遇到的work-sharing区域和barrier区域的顺序必须统一

 TASKWAIT 指令

目的:

抱歉!评论已关闭.