我尝试使用forall
来分配动态数组,但gfortran并不喜欢这样。我还发现在write
块中禁止forall
个语句,我怀疑read
语句也是如此。
forall
块中不允许执行哪些其他功能/操作?
这个构造究竟是什么,除了有时在顺序无关紧要时替换do
循环?我认为它会使编码更清晰,更优雅,尤其是当操作顺序不重要时,但是在forall
内可以进行哪些操作似乎相当严格。
这些限制的原因是什么,即它们保护/防止用户搞砸了什么?使用forall
是个好主意吗?如果是这样,为了什么目的?
现在在我正在处理的代码中只有一个forall
块,如果我在do
循环中将它全部翻译出来,它将提供四个嵌套循环。哪种方式更好?
答案 0 :(得分:12)
现在不需要FORALL
和WHERE
构造。它们作为Fortran 95的一部分(Fortran 90的次要扩展)引入,主要是为了优化,当代码矢量化是HPC中的一个主要内容时。 FORALL
在应用程序中如此受限的原因正是因为它是为循环优化而设计的。另请注意,FORALL
不是循环结构,而是赋值。因此,块内只允许赋值语句。理论上,DO
循环给出了关于处理器将要循环的索引顺序的明确指令。 FORALL
构造允许编译器根据数组在内存中的存储方式选择最佳顺序。但是,随着时间的推移,这已失去意义,因为现代编译器非常擅长DO
循环向量化,并且您不太可能注意到使用FORALL
有任何改进。
查看有关FORALL
和WHERE
here
如果您担心代码性能,您可能更愿意考虑使用其他编译器 - PGI或ifort。根据我自己的经验,gfortran适合开发,但不适合HPC。使用pgf90或ifort编译的代码,您会发现执行速度提高了几倍。
答案 1 :(得分:6)
Forall
构造实际上限制太多,并且仅对阵列操作有用。有关确切的限制,请参阅IBM Fortran - FORALL。限制性较小的是Fortran 2008的do concurrent
构造。在那里允许read
和write
语句。请参阅Intel Fortran - DO CONCURRENT和New features of Fortran 2008。