一. OpenMP简介
OpenMP是一个共享存储并行系统上的应用程序接口。它规范了一系列的编译制导、运行库例程和环境变量。
它提供了C/C++和FORTRAN等的应用编程接口,已经应用到UNIX、Windows NT等多种平台上。
OpenMP使用FORK-JOIN并行执行模型。所有的OpenMP程序开始于一个单独的主线程(Master Thread)。主线程会一直串行地执行,直到遇到第一个并行域(Parallel Region)才开始并行执行。
①FORK:主线程创建一队并行的线程,然后,并行域中的代码在不同的线程队中并行执行;②JOIN:当诸线程在并行域中执行完之后,它们或被同步或被中断,最后只有主线程在执行。
作用域:
编译制导语句的作用域(Scopng)可分为静态范围、孤幼 制导和动态范围。
并行域结构:
一个能被多个线程执行的程序块,它是最基本的OpenMP并行结构,具体格式如下:
# pragma omp parallel [if (scalar_expression) | private (list) | shared (list) | defalut (shared | none) | firstprivate (list) | reduction (operator:list) | copyin (list)] newline
OpenMP的环境变量:
OMP_SCHEDULE:控制for循环任务分配结构的调度
OMP_NUM_THREADS:设置默认线程的个数
OpenMP的库函数
int omp_get_num_threads(void):返回当前使用的线程个数,如果在并行区域外则返回1;
int omp_set_num_threads(int i):设置要使用的线程个数,它可以覆盖OMP_NUM_THREADS;
int omp_get_thread_num(void):返回当前线程号,0代表主线程;
int omp_get_num_procs(void):返回可用的处理核(处理器)个数,对于支持超线程技术的处理器被算作两个处理核。
OpenMP的编译
windows平台 intel C++编译器: 命令 icl /Qopenmp
linux平台 intel C++编译器: 命令 icl -openmp
gcc: 命令 gcc -fopenmp
Visual Studio 对OpenMP的支持:
属性-C/C++-语言-OpenMP支持
Linux环境对OpenMP的支持:
在Linux上编译和运行OpenMP程序
编译OpenMP程序: gcc a.c –fopenmp –o a
运行OpenMP程序: ./a
二.利用积分法计算π
在这里简单说明一下求π的积分方法,使用公式arctan(1)=π/4以及(arctan(x))’=1/(1+x^2).
在求解arctan(1)时使用矩形法求解:
求解arctan(1)是取a=0, b=1.
1.串行代码:
#include <stdio.h>
static long num_steps = 100000;//越大值越精确
double step;
void main(){
int i;
double x, pi, sum = 0.0;
step = 1.0/(double)num_steps;
for(i=1;i<= num_steps;i++){
x = (i-0.5)*step;
sum=sum+4.0/(1.0+x*x);
}
pi=step*sum;
printf("%lf\n",pi);
}
2.使用并行域并行化的程序:
#include <stdio.h>
#include <omp.h>
static long num_steps = 100000;
double step;
#define NUM_THREADS 2
void main ()
{
int i;
double x, pi, sum[NUM_THREADS];
step = 1.0/(double) num_steps;
omp_set_num_threads(NUM_THREADS); //设置2线程
#pragma omp parallel private(i) //并行域开始,每个线程(0和1)都会执行该代码
{
double x;
int id;
id = omp_get_thread_num();
for (i=id, sum[id]=0.0;i< num_steps; i=i+NUM_THREADS){
x = (i+0.5)*step;
sum[id] +=