并行计算学习之OpenMP

1. OpenMP基本概念    

   OpenMP是共享存储体系结构上的 一个并行编程模型。适合于SMP共享内存多处理系统和多核处理器体系结构。

   OpenMP是基于线程的并行编程模型。
   OpenMP采用Fork-Join并行执行方式:
   OpenMP程序开始于一个单独的主线程(Master Thread),然后主线程一直串行执行,直到遇见第一个并行域(Parallel Region),然后开始并行执行并行域。其过程如下:
   Fork:主线程创建一个并行线程队列,然后,并行域中的代码在不同的线程上并行执行;
   Join:当并行域执行完之后,它们或被同步或被中断,最后只有主线程在执行。

   

2、OpenMP 指令和库函数介绍

   在C/C++程序中具体形式如下:

   #pragma omp <指令>  [子句]...

   OpenMP 的指令有以下一些:
              parallel,用在一个代码段之前,表示这段代码将被多个线程并行执行               for,用于 for 循环之前,将循环分配到多个线程中并行执行,必须保证每次循环之
间无相关性。
              parallel  for,  parallel  和  for 语句的结合,也是用在一个 for 循环之前,表示 for 循
环的代码将被多个线程并行执行。
              sections,用在可能会被并行执行的代码段之前
              parallel sections,parallel 和 sections 两个语句的结合
              critical,用在一段代码临界区之前
              single,用在一段只被单个线程执行的代码段之前,表示后面的代码段将被单线程执
行。
              barrier,用于并行区内代码的线程同步,所有线程执行到 barrier 时要停止,直到所
有线程都执行到 barrier 时才继续往下执行。
              atomic,用于指定一块内存区域被制动更新
              master,用于指定一段代码块由主线程执行
              ordered,  用于指定并行区域的循环按顺序执行
              threadprivate,  用于指定一个变量是线程私有的。
    OpenMP 除上述指令外,还有一些库函数,下面列出几个常用的库函数:
              omp_get_num_procs,  返回运行本线程的多处理机的处理器个数。
              omp_get_num_threads,  返回当前并行区域中的活动线程个数。
              omp_get_thread_num,  返回线程号
              omp_set_num_threads,  设置并行执行代码时的线程个数
              omp_init_lock,  初始化一个简单锁
              omp_set_lock,  上锁操作
              omp_unset_lock,  解锁操作,要和 omp_set_lock 函数配对使用。
              omp_destroy_lock,  omp_init_lock 函数的配对操作函数,关闭一个锁
 
    OpenMP 的子句有以下一些:
              private,  指定每个线程都有它自己的变量私有副本。
              firstprivate,指定每个线程都有它自己的变量私有副本,并且变量要被继承主线程中
的初值。
              lastprivate,主要是用来指定将线程中的私有变量的值在并行处理结束后复制回主线
程中的对应变量。
              reduce,用来指定一个或多个变量是私有的,并且在并行处理结束后这些变量要执
行指定的运算。
              nowait,忽略指定中暗含的等待
              num_threads,指定线程的个数
              schedule,指定如何调度 for 循环迭代
              shared,指定一个或多个变量为多个线程间的共享变量
              ordered,用来指定 for 循环的执行要按顺序执行
              copyprivate,用于 single 指令中的指定变量为多个线程的共享变量
              copyin,用来指定一个 threadprivate 的变量的值要用主线程的值进行初始化。
              default,用来指定并行处理区域内的变量的使用方式,缺省是 shared

  3.VI下写的一个简单求π的程序

#include <omp.h>
static long num_steps = 100000000;   double step;
#define NUM_THREADS   8  
void main ()
{
    int i ;  double pi, sum[NUM_THREADS] , start_time, end_time ;
    step = 1.0/(double) num_steps;
    omp_set_num_threads(NUM_THREADS);
    start_time=omp_get_wtime();
    int id;
    double x;
    double sm=0.;
    #pragma omp parallel reduction(+:sm) private(i,id,x)
    {
       id = omp_get_thread_num();
       for (i=id;i< num_steps; i+=NUM_THREADS){
            x = (i+0.5)*step;
           //sum[id]+= 4.0/(1.0+x*x); 
          sm+=4.0/(1.0+x*x);
        }
      //sm=sum[id];
    }
    pi=sm*step;
    end_time=omp_get_wtime();
    printf("Pi=%f\n Running time %15.12f\n", pi, end_time-start_time);
}

猜你喜欢

转载自985359995.iteye.com/blog/2291825