C/C++ openMP并发编程 (学习整理)

并发系统分为两种:

  1. 共享内存系统:各个核可以共享访问计算机的内存。
  2. 分布式内存系统:每个核都有自己独立私有的内存,核之间的通信需要通过网络发送消息。

OpenMP是一种用于共享内存系统的多线程程序设计方案,支持C,C++,Fortran编程语言。OpenMP提供了对并行算法的高层抽象,特别适合多核计算机上道德并行编程设计。当前很多编译器都内置了OpenMP,当编译器不支持OpenMP时,编译器会忽视OpenMP指令,程序自动退化为串行程序,不影响程序的正常编译。特别需要强调一点:在VS编译器中,只有在Release模式下才能体现OpenMP并行化,Debug模式下编译器不会对代码进行优化。

OpenMP采用fork-join(分叉-合并)并行执行模式。线程遇到并行结构时,就会创建由其自身及其它一些线程组成的线程组。遇到并行结构的线程称为线程组中的主线程,其它线程称为组的从线程。所有线程组的成员都执行并行构造内的代码。如果某个线程完成了其在并行构造内的工作,它会在并行构造末尾的隐式屏蔽处等待。当所有组成员都达到该屏蔽处,这些线程就可以离开该屏障。主线程继续执行并行结构之后的代码,而从线程则等待被召集加入到其他组。

OpenMP运行时库维护一个线程池,该线程池的线程可以用作并行区域中的从线程。当线程遇到并行结构并需要创建包含多个线程的线程组时,该线程将检查该池,从池中获取空闲线程,将其作为组的从线程。如何池中没有足够的空闲线程,则主线程获取的从线程可能会比所需的要少。组完成执行并行区域时,从线程就会返回到池中。

上面对OpenMP有一个整体的认识,下面按照OpenMP10.0开发文档的结构,对OpenMP中关键点进行整理介绍:

目录

PARALLEL-并行区域构造

工作共享构造

合并并行工作共享构造

 同步构造

 数据作用域

  调度子句


PARALLEL-并行区域构造

parallel指令定义并行区域,该区域多个线程以并行方式执行的程序区域。默认并行线程数为电脑的核数目,下面代码我的电脑输出12个语句。

#pragma omp parallel   //C,C++使用以#pragma omp开头的标准预处理指令
{
    cout << "parallel run!!!\n";
}

输出:parallel run!!!;parallel run!!!;parallel run!!!;parallel run!!!.....................................

工作共享构造

工作共享构造在遇到该结构的线程组成员中分配封装代码区域的执行。要使工作共享构造以并行方式执行,构造必须封装在并行区域内。

1.for构造

#pragma omp parallel
#pragma omp for
for (int i = 0; i < 10; i++)
{		
    cout << i << endl;
}

注意:一定要在#pragma omp for指令前加入#pragma omp parallel指令,不然退化为串行执行

2.sections构造

sections构造用于封装要在线程组中分配的一组结构化代码块,每个代码块由线程组内的一个线程执行一次。每段以section指令开头,该指令对第一段为可选指令。

#pragma omp parallel
#pragma omp sections
{
	#pragma omp section  //此处可选字段,可以不加
	cout << "work1" << endl;

	#pragma omp section  //此处必选字段,不加此字段报错OpenMP“sections”区域中的结构化块的前面必须是“#pragma omp section”	
	cout << "work2" << endl;

	#pragma omp section  //此处必选字段
	cout << "work3" << endl;
}

输出:work1,work2,work3(顺序不一定,但是只执行一次)

3.single构造

single封装的结构化块只由线程组中的一个线程来执行,除非指定nowait,否则组内未执行single块的线程会在块结尾处等待。

#pragma  omp parallel
#pragma omp single 
{
cout<<"work1"<<endl;
}

4.task构造

task是3.0及以上OpenMP标准实现,task主要用于方便实现任务分解。可能被遇到的线程马上执行,也可能被延迟给线程组内的某个线程执行。task构造必须在并行区域内,并且task外面使用single子句,防止任务执行多次。如果想线程等待其他线程等待完成任务,则添加#pragma omp taskwait。task指令共享变量默认是firstprivate方式共享。

task主要用于不规则的循环迭代和递归函数的调用,for指令,sections指令:无法根据运行时的环境动态的进行任务划分,必须预先知道任务的划分情况。新特

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值