一、什么是OpenMP
OpenMP是⼀种⽤于共享内存并⾏系统的多线程程序设计⽅案,⽀持的编程语⾔包括C、C++和Fortran。OpenMP提供了对并⾏算法的⾼层抽象描述,特别适合在多核CPU机器上的并⾏程序设计。编译器根据程序中添加的pragma指令,⾃动将程序并⾏处理,使⽤OpenMP降低了并⾏编程的难度和复杂度。当编译器不⽀持OpenMP时,程序会退化成普通(串⾏)程序。程序中已有的OpenMP指令不会影响程序的正常编译运⾏。
二、OpenMP的使用
1、获取本机的线程数
代码
#include<omp.h>
#include<iostream>
int main()
{
std::cout << "parallel begin:\n";
#pragma omp parallel
{
std::cout << omp_get_thread_num() << std::endl;
}
std::cout << "\n parallel end.\n";
std::cin.get();
return 0;
}
结果:
说明本机是16线程
2、基本的编译导语
#pragma omp parallel
omp中使用parallel制导指令标识代码中的并行段
如上个例子中的指令#pragma omp parallel,因此打印输出并行执行。
#pragma omp parallel
{
//线程并行执行的代码
}
parallel表示其后语句将被多个线程并行执行,“#pragma omp parallel”后面的语句(或者,语句块)被称为parallel region。多个线程的执行顺序是不能保证的。
#pragma omp parallel for
对for循环进行并行处理,每个核之间是并行执行,各线程顺序不能保证
- 不加openmp指令运行,耗时1.97s
#include <iostream>
#include <time.h>
void test()
{
int a = 0;
for (int i=0;i<100000000;i++)
a++;
}
int main()
{
clock_t t1 = clock();
for (int i=0;i<8;i++)
test();
clock_t t2 = clock();
std::cout<<"time: "<<t2-t1<<std::endl;
}
- 加openmp指令
#include <iostream>
#include <time.h>
void test()
{
int a = 0;
for (int i=0;i<100000000;i++)
a++;
}
int main()
{
clock_t t1 = clock();
#pragma omp parallel for
for (int i=0;i<8;i++)
test();
clock_t t2 = clock();
std::cout<<"time: "<<t2-t1<<std::endl;
}
#pragma omp parallel for num_threads(4)
指定使用线程数为4
3、解决线程竞争引入的编译导语
当多个线程并行执行时,有可能多个线程同时对某变量进行了读写操作,从而导致不可预知的结果。比如下面的例子,对于包含10个整形元素的数组a,我们用for循环求它各个元素之和,并将结果保存在变量sum里。
#include <iostream>
int main(