forall与do循环的区别

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

FORTRA N中FORALL与DO的区别

FORTRAN中FORALL与DO的区别:

以下是个人对FORALL与DO的区别的理解,完全基于一些程序【仅列出下面一个程序】和参考国内与国外教材而得出的。如果有不对的地方,请联系我。谢谢!

INTEGE R :: nn(0:8)=(/0,1,2,3,4,5,6,7,8/), mm(0:7)

FORALL(i=0:7)

nn(i) = 0

mm(i) = nn(i+1)

END FORALL

! 等价于nn(0:7) = 0

! mm(0:7) = nn(1:8)

write(*,'(a,10i2)') 'nn= : ',nn

write(*,'(a,10i2)') 'mm= : ',mm

nn(0:8)=(/0,1,2,3,4,5,6,7,8/)

DO i=0,7

nn(i) = 0

mm(i) = nn(i+1)

END DO

write(*,*)

write(*,'(a,10i2)') 'nn= : ',nn

write(*,'(a,10i2)') 'mm= : ',mm

END

程序运行结果:

nn= : 0 0 0 0 0 0 0 0 8

mm= : 0 0 0 0 0 0 0 8

nn= : 0 0 0 0 0 0 0 0 8

mm= : 1 2 3 4 5 6 7 8

P ress any key to continue

先对DO理解:

DO i=0,7

nn(i) = 0

mm(i) = nn(i+1)

END DO

当i为0时,nn(0)=0,并返还到nn,此时数组是nn(0:8)=(/0,1,2,3,4,5,6,7,8/)【nn(0:7)没有完全改变】

mm(0)=nn(1),所以mm(0)值为1

当i为1时,nn(1)=0,并返还到nn,此时数组是nn(0:8)=(/0,0,2,3,4,5,6,7,8/)【nn(0:7)没有完全改变】

mm(1)=nn(2),所以mm(1)值为2

以此类推......

当i为6时,nn(6)=0,并返还到nn,此时数组是nn(0:8)=(/0,0,0,0,0,0,0,7,8/)【nn(0:7)没有完全改变】

mm(6)=nn(7),所以mm(7)值为7

当i为7时,nn(7)=0,并返还到nn,此时数组是nn(0:8)=(/0,0,0,0,0,0,0,0,8/)【nn(0:7)完全改变】

mm(7)=nn(8),所以mm(7)值为8

最后得出结果是:

nn= : 0 0 0 0 0 0 0 0 8

mm= : 1 2 3 4 5 6 7 8

也就是说是用DO的时候,处理器是按次序来操作每一个连续的迭代,一个接着一个。在一个完成之后才执行下一个。就如同我上面的解释一样,先是0,然后是1,之后是2....最后是7。只有在i=7结束时,nn(0:7)才完全改变。【具体是不是这样的呢?你可以在nn(i)=0后面添加这2个语句来试一试

write(*,*)"nn(",i,")=",nn(i)

write(*,*)"nn(",i+1,")=",nn(i+1)】

再来看FORALL结构

FORALL(i=0:7)

nn(i) = 0

mm(i) = nn(i+1)

END FORALL

输出结果是:

nn= : 0 0 0 0 0 0 0 0 8

mm= : 0 0 0 0 0 0 0 8

很显然是mm(i)中使用的nn(i+1)是已经变化过的nn。

程序开始,对于i=0,7并不是一个一个按次序来的,而是同时进行的,即:没有先后次序。系统识别到nn(i)=0,于是就同时将nn(0)、nn(1)、nn(2)、nn(3)、nn(4)、nn(5)、nn(6)、nn(7)赋值为0,然后将他们返回给nn,现在数组nn就变成了nn(0:8)=(/0,0,0,0,0,0,0,0,8/)。【就在这一步nn(0:7)完全改变了,而不像DO要用7步才完成。】

到此nn(i)=0这一个执行语句已经结束了。

接下来是mm(i) = nn(i+1)。同样,系统同时将nn(1)赋给mm(0)、nn(2)赋给mm(1)、nn(3)赋给mm(2)、......nn(8)赋给mm(7)。【就在这一步mm(0:7)完全改变了,而不像DO要用7步才完成。】于是数组mm就变成了nn(0:7)= (/0,0,0,0,0,0,0,8/)。

到此mm(i) = nn(i+1)这一个执行语句已经结束了。

所以这里给出一个结论是

FORALL是同时处理数据,而DO是逐个处理数据的。

【只要系统支持并行的赋值,FORALL语句以及结构,就能够自然地实现对一个庞大的数组的所有元素进行同时赋值,从而充分地利用了系统的并行效能。这个新特征的引入充分显示了FORTRAN在并行运算方面的努力。】

另外给出一个例子:摘自《Standard programming language Fortran》作者不详,出版时间和地点不详。

This FORALL construct contains a WHERE statement and an assignment statement.

INTEGE R A(5,4), B(5,4)

FORALL ( I = 1:5 )

WHERE ( A(I,:) .E Q. 0 ) A(I,:) = I

B (I,:) = I / A(I,:)

END FORALL

When executed with the input array

0 0 0 0

1 1 1 0

A = 2 2 0 2

1 0

2 3

0 0 0 0

the results will be

1 1 1 1 1 1 1 1

1 1 1

2 2 2 2 1

A = 2 2 3 2

B = 1 1 1 1

1 4

2

3

4 1 2 1

5 5 5 5 1 1 1 1

一本英文原著的解释

相关文档
最新文档