OpenMP基本概念
OpenMP是一种用于共享内存并行系统的多线程程序设计方案,支持的编程语言包括C、C++和Fortran。OpenMP提供了对并行算法的高层抽象描述,特别适合在多核CPU机器上的并行程序设计。编译器根据程序中添加的pragma指令,自动将程序并行处理,使用OpenMP降低了并行编程的难度和复杂度。当编译器不支持OpenMP时,程序会退化成普通(串行)程序。程序中已有的OpenMP指令不会影响程序的正常编译运行。再Linux下使用OpenMP很简单,只需要再后面添加 -fopenmp,如果您的加了openmp发现并行速度比串行速度还慢,请点击这里https://blog.csdn.net/weixin_45873341/article/details/109225043
OpenMP执行模式
OpenMP采用fork-join的执行模式。开始的时候只存在一个主线程,当需要进行并行计算的时候,派生出若干个分支线程来执行并行任务。当并行代码执行完成之后,分支线程会合,并把控制流程交给单独的主线程。
一个典型的fork-join执行模型的示意图如下 OpenMP的编译器指令的目标主要有:1)产生一个并行区域;2)划分线程中的代码块;3)在线程之间分配循环迭代;4)序列化代码段;5)同步线程间的工作。编译制导指令以#pragma omp 开始,后边跟具体的功能指令,格式如:#pragma omp 指令[子句],[子句] …]。 指令太多,将我熟悉指令的以程序的形式说明: 测试环境再虚拟机Centos7下 CPU为4核 第一个程序 其中paraller指令是用来构造一个并行块的,也可以使用其他指令配合使用如for,sections等 parallel指令是用来为一段代码创建多个线程来执行它的。parallel块中的每行代码都被多个线程重复执行。
```cpp #include <iostream> int main() { #pragma omp parallel { std::cout << "Hello World!\n"; //我的CPU为四核,所以生成了4个线程 } }第二个程序 其中num_threads(5),指定了可用线程的数量被指定为5
#include <iostream> int main() { #pragma omp parallel num_threads(5) { std::cout << "Hello World!\n"; } }这里介绍另一种相当于num_threads(5)的写法,这将是介绍的第一个API:omp_set_num_threads。在 omp.h 头文件中定义该函数。 以下程序和上面功能相同。
#include <omp.h> #include <iostream> int main() { omp_set_num_threads(5); #pragma omp parallel { std::cout << "Hello World!\n"; } }第三个程序 将parallel和for组合使用,paralle for编译指示可以帮助您将for循环工作负载划分到多个线程中,每个线程都可以在不同的核心上运行,这显著减少了总的计算时间。 将#pragma 注释掉意味着不在并行计算,按照原先串行计算。 算出的sum的结果为10000000,如果将注释取消掉,可以看到 sum不再是我们想要的值,这个时候只需要再for后面添加 reduction(+:sum) 就可以得到想要的sum 第四个程序 我们已经了解了所有线程以并行的方式运行 pragma omp parallel 之后的代码块。您可以对代码块中的代码进一步分类,然后由选定的线程执行它。
int main( ) { #pragma omp parallel { cout << "All threads run this\n"; #pragma omp sections { #pragma omp section { cout << "This executes in parallel\n"; } #pragma omp section { cout << "Sequential statement 1\n"; cout << "This always executes after statement 1\n"; } #pragma omp section { cout << "This also executes in parallel\n"; } } }pragma omp sections 和 pragma omp parallel 之间的代码将由所有线程并行运行。pragma omp sections 之后的代码块通过 pragma omp section 进一步被分为各个子区段。每个 pragma omp section 块将由一个单独的线程执行。 以上就是openmp的简单用法。
