一:简介
OpenMP(Open Multi-Processing)是一种共享内存编程模式,多线程并行应用程序界面,使用C,C++和Fortran语言。由两种形式实现并行功能:编译指导语句和运行时库函数。编译指导语句告诉程序何时开始并行,库函数用来设置线程数及实现其它并行功能。
基本概念:
1. 串行执行区:只能有单个线程执行的代码
2. 并行执行区:可有多个线程执行的代码
循环
独立的代码块
3. 变量作用域:
共享变量
私有变量
4. 数据相关
流相关(flow dependence) r1=r2+r0; r3=r1+2;
输出相关(output dependence) r1=r0+a; r1=3+4*r0
反相关(anti-dependence)a=b+c; b=3*r;
二:两个小程序
1. Hello_World.c 的并行
#include
#include //调用Openmp库函数
#define N 6
int main(int argc, char *argv[])
{
int i;
printf ("*Hello World! Thread: %d\n",
omp_get_thread_num());
#pragma omp parallel for
for (i = 0; i < N; ++i)
printf ("Hello World! Thread: %d, i: %d\n",
omp_get_thread_num(), i);
return 0;
}
其中:#pragma omp parallel for 是编译指导语句,声明下面的for语句要并行多线程执行。
omp_get_thread_num()是运行时的库函数,用来获取当前的线程号。
通过命令行
gcc -fopenmp Hello_World_omp.c -o hw_opmp
编译,生成可执行文件。运行程序:
./hw_opmp
结果如下:
$ ./hw_opmp
*Hello World! Thread: 0
Hello World! Thread: 2, i: 4
Hello World! Thread: 1, i: 2
Hello World! Thread: 1, i: 3
Hello World! Thread: 0, i: 0
Hello World! Thread: 0, i: 1
Hello World! Thread: 3, i: 5
可以看到,没有并行时,默认只有一个线程,ID 为0;当并行时,有4个线程,即通过4个CPU 来同时处理,我的电脑只有4个CPU 核心。
2. matrix_multiply_openmp.cpp
#include
#include
#include//记录程序运行时间
using namespace std;
int main()
{
int Matrix1[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
int Matrix2[4][2]={2,3,5,4,7,9,8,0};
int Matrix[3][2];
clock_t start, end;//声明类型为clock_t
cout<<"Matrix1:\n";
int i,j,k;
for(i=0;i<3;i++){
for(j=0;j<4;j++){
cout<
其中:omp_set_num_threads(3); 设置进程数为3
omp_get_num_procs(); 获取本机处理器核数,我的是4核。
#pragma omp parallel shared(Matrix1, Matrix2, Matrix) private(j,k) 编译指导语句,并设置Matrix1,Matrix2, Matrix为共享,j,k为私有。这是为了让3个进程都能使用Matrix1,Matrix2, Matrix,但每个进程计算自己的向量运算。
#pragma omp for //schedule(dynamic) 编译指导语句,声明下面的for循环,即第一个for循环进入3线程的并行计算。由于Matrix1是3行,故每个线程处理一行。schedule(dynamic)动态的为空闲进程分配指定大小的循环块。
注意:并行化for的注意事项:
(1)循环语句规范,易于判断循环次数;
(2)循环中不能包含允许循环提前退出的语句(将改变循环次数),如:break, return, exit.
命令行编译:
g++ -fopenmp matrix_multiply_openmp.cpp -o mm_openmp
c++源文件的编译使用g++, c源文件的编译使用gcc。
运行
./mm_openmp
$ ./mm_openmp
Matrix1:
1 2 3 4
5 6 7 8
9 10 11 12
Matrix2:
2 3
5 4
7 9
8 0
Thread_pnum =4
Thread_num:Thread_num:Thread_num:0
2
3
Matrix multiply time:0.007634
The result is:
65 38
153 102
241 166
可以看到程序使用了ID 为0,2,3的进程来处理第一个for循环。