forall与do循环的区别
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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
一本英文原著的解释