如何将循环转换为向量赋值表示法

时间:2015-04-15 17:28:26

标签: loops fortran vectorization

如何转换这样的循环:

Do i = 2,101
   a(i) = b(i)
   c(i-1) = d(i) + d(i-1)
   d(i) = e(i) + 12
Enddo

Fortran的矢量符号中?我们显然可以拆分循环,并执行类似

的操作
a(2:101) = b(2:101)

但最后两个陈述相互依赖,因此无法真正发挥作用。

3 个答案:

答案 0 :(得分:2)

通过写出循环的几次迭代,

Jeff Irwin有正确的想法。 cd更新为:

c(1) = d(2) + d(1)
d(2) = e(2) + 12

c(2) = d(3) + d(2) = d(3) + e(2) + 12
d(3) = e(3) + 12

c(3) = d(4) + d(3) = d(4) + e(3) + 12
d(4) = e(4) + 12

因此,c的第N个值取决于N+1st的{​​{1}}值和d的{​​{1}}值。我们可以把整个循环写成:

Nth

答案 1 :(得分:1)

<强> OLD

Do i = 2,101
   a(i) = b(i)
   c(i-1) = d(i) + d(i-1)
   d(i) = e(i) + 12
Enddo

a(2:101) = b(2:101)
c(1:100) = d(2:101) + d(1:100)
d(2:101) = e(2:101) + 12

如果速度更快,我对此表示怀疑,就设计意图而言,它可能更加模糊,因此矢量化并不总是最好的方式。

编辑1

a(2:101) = b(2:101)
d(2:101) = e(2:101) + 12
c(1:100) = d(2:101) + d(1:100)

由于d仅取决于ec取决于d。从上面的循环d(1)需要先前定义。

答案 2 :(得分:-1)

首先,仔细看看你的非矢量化循环。前几次迭代将如下所示:

a(2) = b(2)
c(1) = d(2) + d(1)
d(2) = e(2) + 12

a(3) = b(3)
c(2) = d(3) + d(2)
d(3) = e(3) + 12

a(4) = b(4)
c(3) = d(4) + d(3)
d(4) = e(4) + 12

除非先前在代码中初始化d,否则可能导致不可预测的行为(具体而言,d(2)用于在c(1)本身被分配之前计算d(2)


编辑:正如High Performance Mark所指出的那样,这篇文章的其余部分是不正确的。我还是留在这里作为参考。

请注意,c取决于d,但d不依赖于c。因此,您可以按如下方式重写代码:

a(2: 101) = b(2: 101)
d(2: 101) = e(2: 101) + 12
c(1: 100) = d(2: 101) + d(1: 100)

这与mtrw的答案非常相似,但请注意+而不是-以及最后一行中c的索引。