OpenMP并行编程
在codeblocks上配置OpenMP
本质:
编译时添加 -fopenmp命令
链接时添加 -lgomp -lpthread
【vscode本机】
使用终端编译
g++ -fopenmp -lgomp -lpthread parallel.cpp
使用以下命令编译即可直接得到结果
g++ -fopenmp -lgomp -lpthread parallel.cpp -o process.exe ; .\process.exe
基础
#include<omp.h>
#include<iostream>
using namespace std;
int main()
{
#pragma omp parallel
{
cout << "Hello, world!" << endl;
}
}
设置并行线程个数
#pragma omp parallel num_threads(5)
或者
omp_set_num_threads(2);
#pragma omp parallel
循环
#include<omp.h>
#include<iostream>
using namespace std;
int main()
{
omp_set_num_threads(2);
#pragma omp parallel
{
#pragma omp for
for(int i=0;i<4;i++)
cout << omp_get_thread_num() << endl;
}
}
用schedule子句进行for循环任务调度的管理
schedule子句形式
schedule(type, size)
type参数有四种:1.static, 2.dynamic, 3.guided, 4.runtime
size参数是整形数据:表示循环迭代次数划分的单位。
static参数
静态调度,不用size参数时分配给每个程序的都是n/t次连续迭代,n为迭代次数,t为并行的线程数目。
dynamic参数
动态调度模式是先到先得的方式进行任务分配,不用size参数的时候,先把任务干完的线程先取下一个任务,以此类推,而不是一开始就分配固定的任务数。使用size参数的时候,分配的任务以size为单位,一次性分配size个。虽然很智能,在任务难度不均衡的时候适合用dynamic,否则会引起过多的任务动态申请的开销。
guided参数
刚开始每个线程会分配到比较大的迭代块,后来分配到的迭代块逐渐递减,没有指定size就会降到1,否则降到size。
runtime
基本不会用到,需要了解的可以自行了解。
sections制导指令
用sections把不同的区域交给不同的线程去执行
用法:
#include<omp.h>
#include<iostream>
using namespace std;
int main()
{
omp_set_num_threads(3);
#pragma omp parallel sections
{
#pragma omp section
{
cout <<omp_get_thread_num();
}
#pragma omp section
{
cout << omp_get_thread_num();
}
#pragma omp section
{
cout << omp_get_thread_num();
}
}
}
single制导指令
single制导指令所包含的代码段只有一个线程执行,别的线程跳过该代码,如果没有nowait子句,那么其他线程将会在single制导指令结束的隐式同步点等待。有nowait子句其他线程将跳过等待往下执行。
int main()
{
omp_set_num_threads(4);
#pragma omp parallel
{
#pragma omp single
{
cout << "single thread=" << omp_get_thread_num()<<endl;
}
cout << omp_get_thread_num() << endl;
}
}