循环并行化.PDFVIP

  • 29
  • 0
  • 约1.23万字
  • 约 10页
  • 2018-02-28 发布于天津
  • 举报
循环并行化

5.2.1 环并行化 环并行化编译制导语句的格式: 环并行化是使用OpenMP 来并行化程序的最重要的部分,它是并行区域编程的一个特例。 由于大量的科学计算程序将很大一部分时间用在处理循环计算上,对于 环进行并行化处理 对这一部分应用程序非常关键,因此 环并行化是OpenMP 应用程序中是一个相对独立且非 常重要的组成部分。在C/C++语言中, 环并行化语句的编译制导语句格式如下: 代码5.2 环并行化语句的编译制导语句格式 #pragma omp parallel for [clause[clause…]] for (index = first ; test_expression ; increment_expr){ body of the loop; } 或者 #pragma omp parallel [clause[clause]] { #pragma omp for [clause[clause]] for (index = first; test_expression; increment_expr) { body of the loop; } } 这两个版本的效果基本相同。只是,如果并行的线程需要在 环的开始、或结束时作些工作 的话,就只 用parallel 与for 子句分离的版本。 这个编译制导语句中的parallel 关键字将紧跟的程序块扩展为若干完全等同的并行区域, 每个线程拥有完全相同的并行区域;而关键字for 则将循环中的工作分配到线程组中,线程 组中的每一个线程完成 环中的一部分内容。编译制导语句的功 区域一直延伸到 for 环、或用大括号{}包围起来的程序块的结束。编译制导语句后面的字句 (clause)用来控制 编译制导语句的具体行为,在后面将通过例子来详细讲解子句的构成以及相关子句的语法状 况。 环并行化语句的限制 并不是所有的 环语句都能够在其前面加上#pragma omp parallel 来实现并行化,在OpenMP 2.5 规范中,OpenMP 对于可以以多线程执行的循环有以下约束: ·循环语句中的循环变量必须是有符号整型,如果是无符号整型,就无法使用。注意,在未 来的OpenMP 3.0 规范中,这个约束可 被取消。 · 环语句 中的比较操作必须是这样 的形式: loop_variable , =, 或= loop_invariant_integer。 ·循环语句中的第三个表达式 (for 环的循环步长)必须是整数加或整数 ,加 的数值 必须是一个循环不变量 (loop invariant value) ·如果比较操作是或=,那么循环变量的值在每次迭代时都必须增加;相反地,如果比较 操作是或=,那么循环变量的值在每次迭代时都必须减少。 ·循环必须是单入口、单出口的,也就是说循环内部不允许有 够到达循环之外的跳转语句, 也不允许有外部的跳转语句到达循环内部。在这里,exit 语句是一个特例,因为它将中止 整个程序的执行。如果使用了goto 或break 语句,那么它们的跳转范围必须在循环之内, 不 跳出循环。异常处理也是如此,所有的异常都必须在循环内部处理。 虽然这些约束看上去有些多,但大多数循环都能够非常容易地被重写成符合约束条件地形 式。只有满足上述约束条件,编译器才 通过OpenMP 将循环并行化。然而,虽然编译器 够完成循环的并行化,仍然需要程序员来保证循环功 的正确。 简单循环并行化 我们首先看一个简单 环的并行化过程,将两个向量相加,并将计算的结果保存到第三个向 量中,向量的维数为n。向量相加即向量的各个分量分别相加。 for (int i=0;in;i++) z[i]=x[i]+y[i]; 显然向量相加的算法中,各个分量之间没有数据相关性, 环计算的过程也没有循环依赖性, 即某一次循环的结果不依赖于其它次 环的结果。而如下的例子当中就存在循环依赖性。 for (int i=0;in;i++) z[i]=z[i-1]+x[i]+y[i] 可以看出,第i 次的循环依赖于i-1 次的 环的结果,对于这样有依赖性的循环进行并行化 必须考虑循环依赖性。 关于数据相关的概念,如果语句S2

文档评论(0)

1亿VIP精品文档

相关文档