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

循环结构的并行(一)

 
阅读更多

在科学和工程应用中,许多程序都要在循环执行上花大量的时间,如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循环结构

    - **并行循环**:LabVIEW支持并行编程,你可以使用并行循环结构(如Parfor Loop)来加速计算密集型任务,尤其是当你的系统拥有多个处理器核心时。 - **优化技巧**:理解何时使用循环结构的优化选项,如预分配数组和...

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

    在这个“labview事件结构控制多个并行循环运行示例LV8.6版”中,我们将探讨如何利用LabVIEW的事件结构来实现多个并行循环的高效控制。 事件结构是LabVIEW中的核心编程机制之一,它允许程序对多个不相关的事件做出...

    一种面向众核处理器的嵌套循环多维并行识别方法.pdf

    4. **自动并行化系统实现**:该方法已集成到一个自动并行化系统中,这意味着它可以自动识别适合并行化的循环结构,并自动进行相应的优化,减轻了程序员的工作负担。 5. **实际应用效果**:在实际应用中,该方法展示...

    洛谷 深基 第1部分 语言入门 第4章 循环结构程序设计(2022.02.14).pdf

    * 通过优化循环结构,例如使用缓存、减少循环次数、使用并行处理等,可以提高循环结构的效率。 * 通过优化循环结构,可以提高程序的执行效率和可读性。 本章节通过循环结构的基本概念、应用、python3实现、实践例题...

    并行多核体系结构基础_课后习题

    并行多核体系结构基础_课后习题 本资源摘要信息涵盖了并行多核体系结构基础的课后习题,涉及到工艺技术升级、设计权衡、功率管理和Amdahl定律等多...此外,还需要使用共享编程模型对算法中的“for i”循环进行并行化。

    并行计算——结构·算法·编程 习题答案

    在《并行计算——结构·算法·编程》这本书中,作者深入探讨了这一主题,提供了丰富的习题来帮助读者理解和掌握相关概念。现在,我们来详细探讨这些习题答案中可能涵盖的知识点。 首先,结构方面,可能包括以下内容...

    【Java 循环结构】面试题解析

    Java 循环结构是编程中的基础概念,它允许程序重复执行一段代码,直到满足特定条件为止。Java 提供了三种主要的循环结构:for 循环、while 循环和 do-while 循环。 1. **for 循环**:for 循环通常用于已知迭代次数...

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

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

    计算第200位三角数的循环结构

    循环结构是计算机编程中的基础控制流之一,用于重复执行一段代码直到满足特定条件为止。常见的循环结构有for循环、while循环和do-while循环。在本例中,我们使用for循环来计算第200位三角数。for循环由三个部分组成...

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

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

    C语言程序中循环结构的性能优化.pdf

    文章主要探讨了C语言程序中循环结构的性能优化,内容涉及C语言、循环结构优化、缓存和并行等多个领域。首先,循环结构是C语言程序的基本结构之一,程序运行时,循环中的时间开销往往占据了总时间开销的大部分。因此...

    并行程序练习代码_并行程序代码_matlab并行_

    - `parfor`:用于并行循环,类似于普通的`for`循环,但可以并行执行循环体。 - `spmd`:同步并行多指令多数据(SPMD)结构,允许在所有工作节点上执行相同的代码段。 - `parfeval`:并行函数评估,可以在后台工作...

    并行计算实验快速排序的并行算法

    在快速排序的过程中,可以使用OpenMP的并行for循环来并行化“划分”和“递归”步骤。当划分完成后,可以并行地对子数组进行排序,这样就避免了频繁的消息传递,更适合于共享内存系统。 并行快速排序的挑战包括负载...

    C#各种循环结构的基础用法 个人资料.rar

    在编程语言中,循环结构是控制程序流程的重要组成部分,它允许我们重复执行一段代码,直到满足特定条件为止。C#作为.NET框架的核心编程语言,提供了多种循环结构供开发者使用。以下将详细介绍C#中的几种主要循环结构...

    计算机系统结构:第6章 并行处理技术I.pdf

    并行处理技术是计算机系统结构中一个重要的组成部分,它的研究内容包括了并行性的基本概念、并行处理技术的不同实现方式以及并行计算机算法和互连网络等多个方面。下面将详细阐述这些知识点。 首先,提到并行性,...

    cpp-BellmanFord算法的并行实现

    源代码可能会包含对图结构的表示,如邻接矩阵或邻接表,以及并行处理这些数据结构的方法。同时,可能还有性能测试和基准比较,以验证并行化带来的速度提升,并确保正确性。 并行化Bellman-Ford算法的关键挑战在于...

    实战matlab之并行程序设计

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

    python并行编程pdf

    异步编程是Python中另一个并行处理的方式,asyncio模块提供了基于事件循环的异步编程模型。可以使用asyncio来管理协程,控制任务,以及与Future对象进行交互,从而实现异步编程。 整个文档结构清晰地为读者介绍了...

Global site tag (gtag.js) - Google Analytics