
编译flag: -fopenmp
头文件:#include "omp.h"
代码中使用标识 :#pragma omp parallel
for循环并行化的约束条件
尽管OpenMP可以方便地对for循环进行并行化,但并不是所有的for循环都可以进行并行化。以下几种情况不能进行并行化:
- for循环中的循环变量必须是有符号整形。例如,
for (unsigned int i = 0; i < 10; ++i){}会编译不通过; - for循环中比较操作符必须是
<, <=, >, >=。例如for (int i = 0; i != 10; ++i){}会编译不通过; - for循环中的第三个表达式,必须是整数的加减,并且加减的值必须是一个循环不变量。例如
for (int i = 0;i != 10;i = i + 1){}会编译不通过;感觉只能++i; i++; --i;或i--; - 如果for循环中的比较操作为
<或<=,那么循环变量只能增加;反之亦然。例如for (int i = 0; i != 10; --i)会编译不通过; - 循环必须是单入口、单出口,也就是说循环内部不允许能够达到循环以外的跳转语句,
exit除外。异常的处理也必须在循环体内处理。例如:若循环体内的break或goto会跳转到循环体外,那么会编译不通过。
redcution工具
#pragma omp parallel for reduction(+:sum)
reduction虽然很方便,但它只支持一些基本操作,比如+,-,*,&,|,&&,||等。有些情况下,我们既要避免race condition,但涉及到的操作又超出了reduction的能力范围,应该怎么办呢?这就要用到openMP的另一个工具,critical。来看下面的例子,该例中我们求数组a的最大值,将结果保存在max里。
critical工具实例
|
|
上例中,for循环还是被自动分成N份来并行执行,但我们用#pragma omp critical将if (temp > max) max = temp括了起来,它的意思是:各个线程还是并行执行for里面的语句,但当你们执行到critical里面时,要注意有没有其他线程正在里面执行,如果有的话,要等其他线程执行完再进去执行。这样就避免了race condition问题,但显而易见,它的执行速度会变低,因为可能存在线程等待的情况。
sections工具
|
|
parallel sections里面的内容要并行执行,具体分工上,每个线程执行其中的一个section,如果section数大于线程数,那么就等某线程执行完它的section后,再继续执行剩下的section。在时间上,这种方式与人为用vector构造for循环的方式差不多,但无疑该种方式更方便,而且在单核机器上或没有开启openMP的编译器上,该种方式不需任何改动即可正确编译,并按照单核串行方式执行。
API示例
|
|




近期评论