并行块指导语句的形式如下:
!$OMP parallel [clause[[,] clause]...]
block
!$OMP end parallel
其中的可能的子句如下:
PRIVATE(list)
SHARED(list)
DEFAULT(PRIVATE | SHARED | NONE)
FIRSTPRIVATE(list)
REDUCTION({operator|intrinsic_procedure_name}:list)
IF(scalar_logical_expression)
COPYIN(list)
NUM_THREADS(scalar_integer_expression)
PARALLEL指导语句的基本语义如下:当程序执行到PARALLEL的时候,程序的主线程为程序产生一组线程(当然是否产生还依赖于其他的条件),线程组中的线程称为工作线程。所有的工作线程并行执行block的内容。当到达end
parallel的时候,除了主线程外,其它工作线程都会结束运行。
关于PRIVATE,SHARED,DEFAULT,FIRSTPRIVATE,REDUCTION,COPYIN是数据属性说明子句,PRIVATE用来指出某个变量是一个私有变量,需要由工作线程在自己的堆栈中分配(也就是说这个变量每个线程各有一个不相关的副本,线程间彼此不可见),而SHARED用来申明某个变量是在共享地址空间中的变量,所有线程都需要访问同一个变量),Default用来指出各变量的缺省属性。他们的详细含义我们将在后面介绍。
IF子句称为条件并行子句,当一个PARALLEL带有条件并行子句时,仅当条件子句所带的scalar_logical_expression为.TRUE.时,这个并行块会并行执行,否则并行块被串行执行。这给OpenMP程序提供了有限的运行时并行化(程序多版本)的能力。
NUM_THREADS子句给出了这个并行块对应的线程组中应该包含的线程数。
需要注意的是,block必须是一个结构化的程序块(也就是说不能有其他入口),下面讨论的其它指导语句中的block也同样必须满足这个要求。
下面的小例子hello先打印出系统中可用的处理器数目,然后每个工作线程打印Hello和自己的线程号。
PROGRAM hello
IMPLICIT NONE
INTEGER :: inode, nnode
INTEGER, EXTERNAL :: omp_get_num_procs, &
& omp_get_thread_num
nnode=omp_get_num_procs()
PRINT *, 'Running for',nnode,'Processors'
CALL omp_set_num_threads(nnode)
!$OMP parallel default(private) shared(nnode)
inode=omp_get_thread_num()
PRINT *, 'Hello From ', inode
!$OMP end parallel
END PROGRAM hello
|