通过fortran中的静态变量来表现

fuz*_*fuz 6 optimization recursion fortran

在Fortran中,如果没有明确地声明它们,则无法递归调用子例程或函数recursive.Fortran程序员告诉我,由于这个原因,编译器可以为所有局部变量分配静态存储,从而提高程序的速度.我对此声明感到非常惊讶,因为今天的大多数处理器都经过优化,可快速引用堆栈.我认为,从静态地址加载的局部变量可能会导致很多缓存未命中,因为静态地址不会被其他子例程用于堆栈.

静态地址的局部变量真的有加速吗?还有哪些其他优化可能不允许递归子例程和函数?

Ian*_*anH 7

你咨询过的Fortran程序员有一些东西倒退 - 对递归的限制产生了,因为以前(假设的)编译器只能为任何变量分配静态存储.性能主要是一个无关紧要的考虑 - 虽然我想如果你根本不能做某事,那么你不太可能快速做到.

早期Fortran(F77和之前版本)旨在允许整个程序的内存要求由程序运行之前的fortran处理器静态确定.这适合当时的一些有限的机器架构.很难得到像递归(内存要求可能因程序输入而异)的情况,以便在一般情况下使用"必须能够通过静态分析计算总内存"限制 - 因此语言不允许它.

特定处理器实际上如何实现该语言取决于它们 - 如果他们想要使用基于堆栈的stoge用于局部变量,那么他们就可以.在标准边界之外编写的Fortran程序员可能在历史上习惯于期望使用静态存储获得的行为(非保存变量在调用之间记住它们的值等),但对底层实现敏感的程序不是标准符合.

(具有此限制的体系结构已被F90淘汰.该标准引入了程序内存需求可根据程序输入动态变化的几种方式 - 显而易见的是分配语句,但现在也允许使用自动变量.)

对于小的未保存的局部变量(标量),很可能(假设合理的硬件)更快地使相关存储在堆栈上.

区分能够递归的程序和那些不具有递归的程序今天仍具有一些实际价值 - 如果局部变量很大(数组或冗长的字符),那么它可能根本不适合堆栈.为避免这种情况 - 如果过程未标记为递归且阵列具有已知大小,则fortran处理器可以使用静态存储.这避免了与动态内存分配相关的任何开销,这可能相当昂贵.如果过程标记为递归(并且局部变量未保存)或者在编译时未知数组的大小,则fortran处理器别无选择 - 它要么希望数据适合堆栈,要么使用动态内存分配.