【问题标题】:Is there any way to tell if a variable was optimized out?有什么方法可以判断变量是否已优化?
【发布时间】:2012-05-30 08:18:11
【问题描述】:

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

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

数组 pts 从未在子例程中实际使用过——我只是在重构代码时忘记删除它。现在,由于 fortran 没有堆栈与堆的概念,这取决于编译器在哪里分配 pts - 这是 gfortran 中数组大小的函数,但我无法弄清楚波特兰组编译器如何处理这个。

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

【问题讨论】:

    标签: assembly memory fortran heap-memory stack-memory


    【解决方案1】:

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

    • gfortran 插入对malloc 的调用
    • ifort 默认分配堆栈上的所有数组。如果您通过-heap-arrays <size> 启用自动堆数组,它将生成对for_alloc 的调用以进行堆分配
    • PGI 编译器生成对 pgf90_auto_alloc 的调用,但我没有使用此编译器及其分配数组的方式的经验

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

    【讨论】:

      【解决方案2】:

      我认为这是一个高度特定于编译器的问题,从某种意义上说,与死代码消除相关的行为并不普遍,不仅是编译器特定的,而且是特定于案例的。启用优化的现代编译器肯定会消除所有无法访问的代码,或者在程序状态方面没有实现任何目标的代码。未使用的变量和数组根本不会出现在最终的可执行文件中。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-18
        • 1970-01-01
        • 1970-01-01
        • 2011-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多