windows系统下使用
基本使用:
在visual C++2010中使用OpenMP
1:将 Project 的Properties中C/C++里Language的OpenMP Support开启(参数为 /openmp);
2:在编写使用OpenMP 的程序时,则需要先include OpenMP的头文件:omp.h;
3:在要并行化的for循环前面加上 #pragma omp parallel for
#include <iostream>
#include <omp.h>
int main()
{
#pragma omp parallel for
for (char i = 'a'; i <= 'z'; i++)
std::cout << i << std::endl;
return 0;
}
2.## openmp使用条件
OpenMP 对可以多线程化的循环有如下五个要求:
循环的变量变量(就是i)必须是有符号整形,其他的都不行。
循环的比较条件必须是< <= > >=中的一种
循环的增量部分必须是增减一个不变的值(即每次循环是不变的)。
如果比较符号是< <=,那每次循环i应该增加,反之应该减小
循环必须是没有奇奇怪怪的东西,不能从内部循环跳到外部循环,goto和break只能在循环内部跳转,异常必须在循环内部被捕获。
3.## 避免数据竞争与依赖
// 假设数组已经初始化为1
#pragma omp parallel for
for (int i = 2; i < 10; i++) {
factorial[i] = i * factorial[i-1];
}
编译器会把这个循环多线程化,但是并不能实现我们想要的加速效果,得出的数组含有错误的结构。因为每次迭代都依赖于另一个不同的迭代,这被称之为竞态条件。要解决这个问题只能够重写循环或者选择不同的算法。
每个循环(或线程)都会读写变量,需要确定哪些变量是循环共有的,哪些变量是循环私有的,这个很重要。公有数据,每个线程访问都使用共同的地址,私有数据,每个线程都拥有一份私有的备份。默认情况下,除了循环变量以外,其他变量都是公有的,可以通过以下方法设置变量为私有:
// 1. 在循环内部声明变量
#pragma omp parallel for
for (int i = 0; i < 100; i++) {
int temp = array[i];
array[i] = doSomething(temp);
}
// 2. 通过OpenMP指令说明私有变量
int temp;
#pragma omp parallel for private(temp)
for (int i = 0; i < 100; i++) {
temp = array[i];
array[i] = doSomething(temp);
}
如下面例子中,对sum私有或公有都有问题,使用Reductions关键字,使得sum在每个线程中都具备一个私有备份,当线程结束时,再将各个线程的sum私有量进行加和。
int sum = 0;
#pragma omp parallel for reduction(+:sum)
for (int i = 0; i < 100; i++) {
sum += array[i];
}
同样的,具备同样功能的还有以下符号:
操作 私有临时变量初值
- 、- 0
-
1
& ~0
| 0
^ 0
&& 1(true)
|| 0(false