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的简单用法。