`
yuanlanxiaup
  • 浏览: 859844 次
文章分类
社区版块
存档分类
最新评论

循环结构的并行(一)

 
阅读更多

在科学和工程应用中,许多程序都要在循环执行上花大量的时间,如Fortran中的do循环和C语言中的for循环,通过并行中的loop-level可以减少这些循环的运行时间。OpenMP提供了parallel forparallel do指令来对循环结构进行并行处理,这个指令可以用于大部分的循环结构,它也是OpenMP中使用最多和最频繁的指令。当然,程序员必须清楚哪些循环是可以进行并行的。

OpenMP中用于循环的指令结构为:

C:

#pragma ompparallel for [clause [clause …]]

for循环结构

Fortran:

!$omp parallel do[clause [,] [clause …]]

do循环结构

end do

[!$ompend parallel do]

注:方括号[]表示可选项。

parallel forparallel do指令后,紧接着就必须是for循环(对于C语言)或do循环(对于Fortran语言),并形体就是for或do循环中的程序。只是在fortran中还可以添加!$omp end parallel do指令来表示循环并行结束。OpenMP还提供了用于控制并行执行的一些循环选项条件(clause),根据这些条件的类型可以分为范围条件、schedule条件、if条件、ordered条件和copyin条件等。

1、范围条件

范围条件主要有default(shared | none)shared(list)private(list)、firstprivate(list)、lastprivate(list)和reduction(operator:list)等。default条件用于设置并形体中涉及到的变量默认是shared共享的还是非共享的,default后的括号中只有值sharednoneshared条件表示其后list列出的那些变量在并形体中是共享的,意思就是说并形体外部和并形体内部都可以对该变量进行读取和修改,它就像全局变量一样。

private条件用于表示其后list列出的那些变量在并形体中是私有的。既然是私有的,那么在并形体外部设置的该变量值无论为多少,在并形体中都将无法使用。所有这些private变量在并形体中都必须初始化设置值,换句话说,这些private的变量在并形体中与在并形体外是完全隔离的、毫无关系的。在for循环中定义的循环变量默认就是private的。下面举一个例子来说明private,如下代码:

// File: PrivateTest.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"

#include<omp.h>

#include<iostream>

using namespace std;

//private测试

int PrivateTest()

{

cout<<"private输出:\n";

inti=0,j=10;

#pragmaomp parallel for private(j)

for(i=0;i<8;i++)

{

cout<<i<<":"<<j<<"\n";

j++;

cout<<i<<":"<<j<<"\n";

}

return0;

}

如果运行该程序,将会出现变量j没有初始化的错误,错误提示如下图所示:

奇怪的是为什么没有提示i?因为i已经初始化为0,而并形体中还没有为j设置初始化值,如果将j=10添加到for循环中,程序就运行正常了。如下代码(红色表示修改的部位):

// File: PrivateTest.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"

#include<omp.h>

#include<iostream>

using namespace std;

//private测试

int PrivateTest()

{

cout<<"private输出:\n";

inti=0,j=10;

#pragmaomp parallel for private(j)

for(i=0;i<8;i++)

{

j=10;

cout<<i<<":"<<j<<"\n";

j++;

cout<<i<<":"<<j<<"\n";

}

return0;

}

firstprivate条件用于表示其后list列出的变量在并形体中私有的,但其在并形体中的初始化值为并行之前设置的值。同样以上面的代码为例:

// File: FirstPrivateTest.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"

#include<omp.h>

#include<iostream>

using namespace std;

//FirstPrivateTest测试

int FirstPrivateTest()

{

cout<<"firstprivate输出:\n";

inti=0,j=10;

#pragmaomp parallel for firstprivate(j)

for(i=0;i<8;i++)

{

cout<<i<<":"<<j<<"\n";

j++;

cout<<i<<":"<<j<<"\n";

}

return0;

}

该代码与之前代码没有什么太大区别,尽管在并形体中没有对j进行初始化,但是它能正常正确的运行,其原因就是将变量j设置成了firstprivate。虽说在并形体中并没有对j进行初始化,但是在并形体中j的初始值就是10。

lastprivate条件与firstprivate的含义类似,只是它设置的变量需要在并形体中初始化,但是其最后的结果可以在并形体外部使用。

// File: LastPrivateTest.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"

#include<omp.h>

#include<iostream>

using namespace std;

//LastPrivateTest测试

int LastPrivateTest()

{

cout<<"lastprivate输出:\n";

inti=0,j=10;

#pragmaomp parallel for lastprivate(j)

for(i=0;i<8;i++)

{

j=5;

cout<<i<<":"<<j<<"\n";

j++;

cout<<i<<":"<<j<<"\n";

}

cout<<"最后j的值为:"<<j<<"\n";

return0;

}

最后输出的j的值为6,注意,j的值不是10,也不是11,也不是5+8=13,而是5+1=6。另外,如果设置变量为lastprivate,它必须在并形体中初始化,否则会出错。

reduction条件具有sharedprivate的特性,其后结构为(operator: list),其中操作operator用于每次累积时list列出变量的操作。这些操作只针对并形体并行时,它不会影响并形体中该变量的值(包括初始值),但是并形体中该变量值将影响最后该变量在并形体外部的值。该变量将分为两部分,一部分属于shared类型,一部分属于private类型,最终该变量的值就是该变量初始值(在并行之前的值)与并形体中private类型值的operator运算,如果operator为+,则为这些之和。如下面的例子:

// File: ReductionTest.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"

#include<omp.h>

#include<iostream>

using namespace std;

//ReductionTest测试

int ReductionTest()

{

cout<<"reduction输出:\n";

inti=0,j=10;

#pragmaomp parallel for reduction(+:j)

for(i=0;i<8;i++)

{

j=2;

cout<<i<<":"<<j<<"\n";

j++;

cout<<i<<":"<<j<<"\n";

}

cout<<"最后j的值为:"<<j<<"\n";

return0;

}

程序运行结果为:

reduction输出:

0:2

0:3

6:2

6:3

2:2

2:3

3:2

3:3

1:2

1:3

5:2

5:3

4:2

4:3

7:2

7:3

最后j的值为:34

从上面的结果可知,变量j在并形体中是以private形式存在,而最后在并形体之间通过操作(+)来完成各个并形体中j的值与初始值(10)的计算,所以最后j的值为:10+(3)+(3)+(3)+(3)+(3)+(3)+(3)+(3)=34。如果操作符是*,则最终j的值为:10*(3)*(3)*(3)*(3)*(3)*(3)*(3)*(3)=65610。

reduction的操作符主要有:

操作符

数据类型

初始值

+

整型,浮点型

0

-

整型,浮点型

0

*

整型,浮点型

1

&

整型

On

|

整型

0

^

整型

0

&&

整型

1

||

整型

0

其中初始值是指在没有为该reduction变量在并形体中初始化时,它默认的值。

如果要列出多个变量,list中用逗号隔开相邻的变量。如果有多种类型的要定义,即有shared又有private等等,相互之间用空格隔开即可。如下格式:

#pragma omp parallel for private(a,b,c) firstprivate(d,e)reduction(+:sum)


相关程序源码下载地址:

http://download.csdn.net/detail/xwebsite/3843187


分享到:
评论

相关推荐

    labview事件结构控制多个并行循环运行示例LV8.6版

    labview论坛-事件结构控制多个并行循环运行示例LV8.6版

    计算机结构并行化程序的替代方法的研究.pdf

    我们将我们的方法与pthread par allelization进行比较,表明(1)我们的并行执行是确定性的,(2)我们的线程管理缺陷,(3)我们的并行性是隐式的,(4)我们的方法并行化函数和循环。隐式并行性使并行代码易于编写...

    微机原理与接口技术实验题目及其答案,汇编程序源码,汇编语言分支和循环结构,8255并行,8254,8259 中断控制,8251

    微机原理与接口技术实验题目及其答案,汇编程序源码,汇编语言分支和循环结构,8255并行接口实验,使用8255完成流水灯实验,8254定时/计数器应用实验,8254 典型应用电路的接法,8259 中断控制器的工作原理, 8259 ...

    实战matlab之并行程序设计

    第一个分太高了要50,过分,通过阅读和学习,读者可以掌握基于多种平台(多核、多处理器、集群和GPU等),利用多项技术(Matlab并行计算工具箱、多线程MEX文件、OpenMP和GPU等),学习理解Matlab并行程序设计的原理、...

    《实战Matlab之并行程序设计》

    第2 章为利用parfor 对for 循环进行并行;第3 章为SPMD 并行结构;第4 章为其他Matlab 并行结构;第5 章为Matlab 并行计算数据类型;第6 章为Matlab 通用并行程序设计;第7 章为MDCE 配置;第8 章为创建多线程MEX ...

    OpenMP并行计算程序设计基础

    五、循环结构的并行 17 1、范围条件 17 2、shedule条件 22 3、threadprivate指令 24 六、分段并行 25 七、嵌套并行 29 八、OpenMP中的常用函数 33 1、设置线程数目 33 2、获取线程数目 33 3、获取最多线程数目 33 4...

    0积分下载《实战Matlab之并行程序设计》程序代码

    第2章为利用parfor对for循环进行并行;第3章为SPMD并行结构;第4章为其他Matlab并行结构;第5章为Matlab并行计算数据类型;第6章为Matlab通用并行程序设计;第7章为MDCE配置;第8章为创建多线程MEX文件;第9章为在...

    matlab并行parfor 宏观串行

    有些时候因为循环次数比较多,我们需要matlab并行处理。 比如用parfor i = 1:10000 end (有很多时候我们想要程序按照i的值从小打到执行) 并行处理中i的值不是顺序的, 所以如果程序突然死掉后也非常麻烦,因为已经...

    并行计算导论(原书第2版).[美]Ananth Grama(带详细书签).pdf

    本书系统介绍涉及并行计算的体系结构、编程范例、算法与应用和标准等。覆盖了并行计算领域的传统问题,并且尽可能地采用与底层平台无关的体系结构和针对抽象模型来设计算法。书中选择MPI(Message Passing Interface)...

    _LDPC码的高效编译码实现技术研究_低密度奇偶校验码_LDPC_LDPC并行_准循环LDPC码_

    本文针对部分并行结构的准循环LDPC码译码器,提出了一种将译码准码字存储在信道信息和外信息存储块中的高效存储方法,该方法可减少译码器对存储资源的需求量,并降低了译码电路的布线复杂度;另外,本文通过分析 ...

    C#并行编程高级教程:精通.NET 4 Parallel Extensions中文(第一部分)

    ◆讲解命令式数据并行、命令式任务并行、并发集合以及协调数据结构。 ◆描述PLINQ高级声明式数据并行。 ◆讨论如何使用新的Visual Studio 2010并行调试功能来调试匿名方法、任务和线程。 ◆演示如何对数据源进行...

    LabVIEW的While循环

    结构子选板中的While循环和执行过程控制子选板中的While循环用法和作用是相同的,只不过在建立循环结构时有点小差别。   图1 执行控件中的While循环结构  While循环有两个参数:当前循环次数i和条件判断布尔...

    论文研究-国数字地面电视标准中LDPC码的半并行译码结构设计.pdf

    根据该类LDPC码的准循环特性,提出了一种基于后验概率的简化最小和算法及其对应的半并行译码结构。其可实现在同一接收机中尽量复用硬件资源并减少消耗情况下LDPC码的多码率译码。最后,使用可编程门阵列实现了此结构...

    C#并行编程高级教程:精通.NET 4 Parallel Extensions中文(第2部分)

    ◆讲解命令式数据并行、命令式任务并行、并发集合以及协调数据结构。 ◆描述PLINQ高级声明式数据并行。 ◆讨论如何使用新的Visual Studio 2010并行调试功能来调试匿名方法、任务和线程。 ◆演示如何对数据源进行...

    C#并行编程高级教程:精通.NET 4 Parallel Extensions中文(第3部分)

    ◆讲解命令式数据并行、命令式任务并行、并发集合以及协调数据结构。 ◆描述PLINQ高级声明式数据并行。 ◆讨论如何使用新的Visual Studio 2010并行调试功能来调试匿名方法、任务和线程。 ◆演示如何对数据源进行...

    C语言中对于循环结构优化的一些入门级方法简介

    主要介绍了C语言中对于循环结构优化的一些入门级方法,包括算法设计的改进来提高一些并行性等方法,要的朋友可以参考下

    一种新型大容量电力电子通信中16位CRC并行算法.pdf

    大容量电力电子装置在电路结构、空间布局及控制功能上往往都存在较明显的分布性.需采用实时性高 且复杂的分布式控制技术,而实现该分布式控制技术的关键是高速串行通信。循环冗余校验(CRC)作为串行通 讯中最常见...

    论文研究-网络拓扑的超能整循环图构造.pdf

    循环图是一类重要的网络拓扑结构图,在并行计算和分布计算中发挥重要作用。图[G]的能量[E(G)]定义为图的特征值的绝对值之和。具有[n]个顶点的图[G]称为超能图如果图[G]的能量[E(G)&gt;2n-2]。一个图称为循环图,若它是...

    论文研究-NCL电路并行处理结构研究.pdf

    利用一个和扫描链等长的扫描移位寄存器,对传统扫描链进行改造,提出了一种新型的选择触发的扫描链结构。它有效地降低了传统扫描链扫描移位过程中的动态功耗,并提高了扫描时钟频率,同时它所需要的测试数据为原始...

    计算机体系结构试题及答案

    第一章 计算机体系结构的基本概念 1.1 引论 1.2 计算机体系结构的概念 1.2.1 计算机系统中的层次概念 1.2.2 计算机体系结构 1.2.3 计算机组成和计算机实现技术 1.3 计算机体系结构的发展 1.3.1 ...

Global site tag (gtag.js) - Google Analytics