如何转换这样的循环:
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)
但最后两个陈述相互依赖,因此无法真正发挥作用。
答案 0 :(得分:2)
Jeff Irwin有正确的想法。 c
和d
更新为:
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
仅取决于e
而c
取决于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
的索引。