OpenMP简介
OpenMP应该是历史比较悠久的并行工具吧,至少我最先知道的是它,作为共享存储标准,它是为多处理器多核心的设备上编写并行程序而设计的一个应用编程接口,包括一套编译知道语言和一个支持它的函数库。
上述都是比较官方的话语,对我而言,它有两个优点:其一为可结合标准的C/C++(外加Fortran)进行工作,并且基本应用较为简单,易于学习(仅限于皮毛);其二为支持跨平台,VS中可通过编辑属性直接开启此功能,Linux只要包含头文件就可以了,支持gcc,g++编译器,这也就降低了安装配置的难度。
OpenMP编译指导语句
简单介绍下OpenMP编译指导语句:
- parallel 用在代码段前,指示该代码可被多个线程并行执行
- for 用在C/C++标准的for循环之前,但是每个循环之间必须是无相关性的,这样才可以分配到每个线程中执行
- parallel for 字面意思parallel + for的组合
- sections 用在代码段之前,该代码段可能会被并行执行
- parallel sections 顾名思义parallel + sections的组合
- critical 用在代码临界区之前(还没用过)
- single 若代码段只能被单个线程执行,则用此语句
除此之外,还有几个比较关键的函数:
- omp_get_num_procs 返回处理器的个数
- omp_get_num_threads 返回线程个数
- omp_get_thread_num 返回线程索引号
- omp_set_num_threads 指定线程个数
工作模式
OpenMP中,标准的并行模式为fork/join模式,简单将就是只有一个主线程(一般是按照串行执行的),当需要并行执行时,就会派生(fork)出多个线程,此时,主线程与这些派生线程协同工作,在并行代码段执行结束是,派生的线程挂起,控制流重新回到(join)主线程中,知道完成整个程序。(晚些时候会附个图说明)
语言简介
parallel for
从现在的应用看,这个组合占了半壁江山,所以还是需要好好看看的,先上个示例代码:
#单层for循环更改
int b[300]
#pragma omp parallel for
for(int i = 0; i < 300; i++)
b[i] = i;
上述代码即完成了此for
循环的并行化,比较简单,也比较常用,但有时候也会出现用到双重循环,这就需要进化下代码了:
#双重循环
#pragma omp parallel for private(j)
for(int i = 0; i < 100; i++)
for(int j = 0; j < n; j++)
a[i][j] = j;
双重循环就有点难度了,需要讲解下, parallel for
不用解释了, private
声明私有变量,保证 j
的独立性,使其他线程无法访问此该变量。
功能并行
parallel for
及其附属占了半壁江山,那剩下的半壁江山就是即将介绍的:parallel sections
,该方法是为了实现功能并行,简单讲就是你可以分配线程a实现功能A,线程b实现功能B......待全部完成后,再统一回到主线程中:
#代码块功能并行
#pragma omp parallel sections
{
#pragma omp section
{
a = A;
}
#pragma omp section
{
b = B;
}
}
其中,#pragma omp section
中执行具有独立功能的代码块,方便灵活使用。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。