OpenMP: OpenMP嵌套并行
OpenMP中不建议使用并行嵌套,如果一个并行计算中的某个线程遇到了另外一个并行分支,程序运行将会变得不稳定。将一个完整的工作任务通过一组并行线程分成若干小任务,每个线程只执行指定给它的那段代码,并没用多余的线程去做其他的工作,即使并行计算中正在运行的某个线程遇到了一个新的并行分支,通过分割这个任务形成更多的线程,这并没有任何实际意义。因此,嵌套并行在OpenMP中将不考虑。OpenMP在处理多级并行嵌套时默认采用串行的执行方式,所以采用多级的并行在程序执行上并不会获得更高的计算效率。
下面通过一个例子来说明OpenMP中的并行嵌套。代码如下:
//File :NestingTest.cpp
#include"stdafx.h"
#include<omp.h>
#include<iostream>
using namespace std;
void NestingTest()
{
int i,j;
#pragma omp parallel for
for(i=0;i<4;i++)
{
#pragma omp parallel for
for(j=0;j<4;j++)
{
cout<<"j Threads:"<<omp_get_num_threads()<<" ThreadID:"<<omp_get_thread_num()<<"\n";
}
cout<<" i="<<i<<" Threads:"<<omp_get_num_threads()<<"\n";
}
}
这是一个简单的并行嵌套,运行结果如下:
j Threads:j Threads:1
ThreadID:01 ThreadID:0
j Threads:1 ThreadID:0
j Threads:1 ThreadID:0
j Threads:1 ThreadID:0
j Threads:1 ThreadID:0
j Threads:1 ThreadID:0
j Threads:1 ThreadID:0
i=2 Threads:8
j Threads:1 ThreadID:0
j Threads:1 ThreadID:0
j Threads:1 ThreadID:0
j Threads:1 ThreadID:0
j Threads:1 ThreadID:0
j Threads:1 ThreadID:0
j Threads:1 ThreadID:0
i=3 Threads:8
i=0 Threads:8
j Threads:1 ThreadID:0
i=1 Threads:8
从输出结果可以发现,在i的循环中循环之间处于并行状态,而在j中循环属于串行。默认情况下即使将j循环定义成并行,其内部执行时仍然按串行方式运行。
若需要使用嵌套并行,则需要使用 omp_set_nested()函数设置在程序中可用并行嵌套。如下例子:
//File :NestedTest.cpp
#include"stdafx.h"
#include<omp.h>
#include<iostream>
using namespace std;
void NestedTest()
{
int i,j,k;
k=omp_get_nested();
cout<<"是否支持并行嵌套:"<<k<<"\n";
omp_set_nested(1);//设置支持嵌套并行
k=omp_get_nested();
cout<<"是否支持并行嵌套:"<<k<<"\n";
double starttime,endtime;
starttime=omp_get_wtime();
#pragma omp parallel for
for(i=0;i<2;i++)
{
#pragma omp parallel for
for(j=0;j<4;j++)
{
cout<<" i="<<i<<" j="<<j<<" Threads:"<<omp_get_num_threads()<<" ThreadID:"<<omp_get_thread_num()<<"\n";
}
cout<<" I="<<i<<" Threads:"<<omp_get_num_threads()<<" ThreadID:"<<omp_get_thread_num()<<"\n";
}
endtime=omp_get_wtime();
k=omp_get_nested();
cout<<"是否支持并行嵌套:"<<k<<"\n";
cout<<"计算耗时:"<<endtime-starttime<<"s\n";
}
运行程序,其结果如下:
是否支持并行嵌套:0
是否支持并行嵌套:1
i= i=1 j=2 Threads:8 i=0 j=0 Threads:8 ThreadID:0
ThreadID:2
i=0 j=3 Threads:8 ThreadID:3
i=0 j=1 Threads:8 ThreadID:1
i=1 j=3 Threads:8 ThreadID:3
i=1 j=1 Threads:8 ThreadID:1
0 j=2 Threads:8 ThreadID:2
i=1 j=0 Threads:8 ThreadID:0
I=0 Threads:8 ThreadID:0
I=1 Threads:8 ThreadID:1
是否支持并行嵌套:1
计算耗时:0.0338853s
从上面结果可见,不仅在i的循环中每个循环处于并行,在j中每个循环也处于并行状态。默认情况下,程序的并行嵌套是不可用的,即并行中的并行将会当作串行来处理。如果使用omp_set_nested()设置其可用并行嵌套,则当并行中的线程遇到新的并行时,会创建新的线程来并行处理。
下面用一个例子来比较嵌套并行与非嵌套并行的运行效率,代码如下:
//File :NestingTest02.cpp
#include"stdafx.h"
#include<omp.h>
#include<iostream>
using namespace std;
void test()
{
int i;
for(i=0;i<100000000;i++);
}
void NestingTest02()
{
int i,j;
double starttime,endtime;
starttime=omp_get_wtime();
#pragma omp parallel for
for(i=0;i<8;i++)
{
#pragma omp parallel for
for(j=0;j<8;j++)
{
test();
}
}
endtime=omp_get_wtime();
cout<<"计算耗时:"<<endtime-starttime<<"s\n";
}
上面代码是一个嵌套并行,其计算耗时约为2.63688s。如果将j循环上面的并行指令注释,只有一个并行结构,其结果为0.678552s。如果将i循环上面的并行指令注释,保留j循环前面的并行指令,其结果为2.67237s。如果都不采用并行,直接用串行运行,其计算耗时为16.1329s。可以,采用嵌套并行并不一定能提高效率,只有在合适的地方设置并行才能达到事半功倍的效果。
OpenMP: OpenMP嵌套并行相关推荐
- 并行:四种C+OpenMP计算π的并行程序
四种C+OpenMP计算π的并行程序 VS2017中OpenMP配置 计算π的串行程序 计算π的并行程序 1.并行域并行化 2.共享任务结构并行化 3.private字句和critical制导语句并行 ...
- OpenMP共享内存并行编程详解
1. 介绍 并行计算机可以简单分为共享内存和分布式内存,共享内存就是多个核心共享一个内存,目前的PC就是这类(不管是只有一个多核CPU还是可以插多个CPU,它们都有多个核心和一个内存),一般的大型计算 ...
- OpenMP和MPI并行模式的区别?
1.OpenMP OpenMP是一种用于共享内存并行系统的多线程程序设计的库(Compiler Directive),特别适合于多核CPU上的并行程序开发设计.它支持的语言包括:C语言.C++.For ...
- OpenMP: OpenMP编程指南
from: OpenMP: OpenMP编程指南 进入多核时代后,必须使用多线程编写程序才能让各个CPU核得到利用.在单核时代,通常使用操作系统提供的API来创建线程,然而,在多核系统中,情况发生了很 ...
- OpenMP: sections分段并行
除了循环结构可以进行并行之外,还可以进行分段并行(parallel section).迄今为止,每谈到如何去并行一个程序时,我们主要关心的是在同一时间将一个任务划分成多个然后用多线程去完成.然而,如果 ...
- [openmp]使用嵌套互斥锁锁定变量
本文出自:http://www.cnblogs.com/svitter 转载请注明出处. 如果有一个线程必须要同时加锁两次,只能用嵌套型锁函数 函数名称 描述 void omp_init_nest_l ...
- OpenMP中omp_set_nested()和OMP_NESTED环境变量详解
(1)类似于omp_set_dynamic(http://blog.csdn.net/gengshenghong/article/details/7003688),omp_set_nested()的参 ...
- Cython 0.15,用 OpenMP 并行多核加速 Python!
赖勇浩(http://laiyonghao.com) 注: 0.读懂这篇文章需要了解 OpenMP 基本用法. 1.读懂这篇文章需要了解 GIL 基本概念. 2.基本上是这篇的翻译:http://do ...
- OpenMP并行编程
1.总览 OpenMP(Open Multi-Processing)是一种用于共享内存并行系统的多线程程序设计方案,支持的编程语言包括C.C++和Fortran.OpenMP提供了对并行算法的高层 ...
最新文章
- Autodesk Infrastructure Map Server 2014的开发文档在哪里?
- 记一次clickhouse查询问题Double-distributed IN/JOIN subqueries is denied (distributed_product_mode = ‘deny‘)
- Xcode搭建真机调试环境 图文实例
- java的回文是什么_Java实现回文判断
- 上海大学计算机学院客座教授,刘云虹教授受聘上海大学外国语学院客座教授并做学术讲座...
- BZOJ4107 : [Wf2015]Asteroids
- 【机器学习】监督学习--(回归)岭回归
- 拉登是我罩的队_软件需求规格说明书
- 2017年数模国赛B题第一小题的思路过程(个人思路)
- flutter2.x报错解决type (RouteSettings) => Route<dynamic> is not a subtype of type (RouteSettings) => Rou
- 粒子群算法组卷_概率表示的二进制粒子群算法在组卷中的应用
- 大神超短代码实现超牛特效
- 【UE4基础】UE4 垃圾回收
- 最大子段和(C++,DP)
- 计算机网络首部检验和怎么算,计算机网络校验和算法
- 银行计算机信息系统安全检查,银行网络安全自查报告.docx
- u8 系统服务器配置,用友u8服务器配置推荐
- IPX:互联网分组交换协议--网络大典
- 遗传算法解决8数码难题——Java
- 如何将embed嵌入式Flash网页播放器替换为CKplayer