有没有办法判断一个变量是否被优化了?

时间:2012-05-23 18:30:42

标签: memory assembly stack heap fortran

我有一些看起来像这样的fortran代码:

 subroutine foo(mx,my,mz)
    real pts(3,mx,my,mz)
 end

数组pts从未在子例程中实际使用过 - 我只是在重构代码时忘记删除它。现在,因为fortran没有堆栈与堆的概念,所以由编译器来分配pts - 这是gfortran中数组大小的函数,但我无法弄清楚portland组编译器的方式处理这个。

是否有可能判断是否在堆栈,堆上分配了pts,或者它是否完全被完全优化(可能应该如此)?是否有可能有一个stackoverflow而不知道它(即没有运行时错误)?我的直觉是,应该可以通过查看编译器生成的程序集来判断,但我不知道我在那里会看到什么。

2 个答案:

答案 0 :(得分:5)

最简单的方法是查看编译器在使用-S进行编译时提供的汇编代码,或者使用调试器查找符号。如果在堆上分配数组,则很可能会调用分配函数:

  • gfortran 会调用malloc
  • ifort 默认情况下会分配堆栈上的所有数组。如果按-heap-arrays <size>启用自动堆数组,则会生成对for_alloc的堆分配调用
  • PGI 编译器生成对pgf90_auto_alloc的调用,但我没有使用此编译器及其分配数组的方式

顺便说一下,即使使用默认优化级别, gfortran 也会在未引用数组时删除该数组。我猜其他编译器会做同样的事情,但我不会赌它。

答案 1 :(得分:2)

我认为这是高度特定于编译器的问题,因为与死代码消除相关的行为不是通用的,并且不仅是编译器特定的,而且是特定于案例的。打开优化的现代编译器肯定会消除所有无法访问的代码,或者代码在程序状态方面无法实现。未使用的变量和数组在最终的可执行文件中根本不会结束。

正如您所提到的,最好的办法是查看已编译二进制文件的汇编代码,看看它的作用。