没有堆栈分配整个程序编译?

如果您编写的应用程序是:

  • 单线程
  • 在调用图中没有周期
  • 不使用alloca或VLA
  • 现代整个程序优化编译器可以优化所有堆栈分配(例如GCC,MSVC,ICC)吗? 看起来在这些情况下,它应该能够静态分配所有可能的堆栈空间。 “整个程序”是指编译器可以访问/所有/源代码(在运行时没有可能发生的事情,等等)。


    如果你能保证你陈述的条件,那么是的:这将有可能有效地让堆栈完全静态分配。 每个函数都有一个堆栈内存块。

    但是,实际的编译器会这样做吗? 没有。

    它完全没有这样做。 事实上,它可能获得的不是什么。 很多时候,大部分工作堆栈都在缓存中,所以修改它很便宜。 如果堆栈在静态内存中,那么任何特定函数的“堆栈”内存将被缓存的唯一时间将是如果您最近调用了该函数。 使用真正的堆栈,您更有可能在缓存中工作。

    此外,为每个函数提供一个堆栈内存块可以很容易地使您的程序的静态内存使用量远大于需要的数量。 堆栈是一个固定大小的构造; 无论您有多少功能,堆栈都会占用一定的大小。 如果你有10万个函数,每个函数占用64个字节的空间,那么你的静态“堆栈”必须占用6.4MB的空间。

    为什么? 你永远不会在任何时候使用大部分内存。 该程序可以在1MB或甚至512KB的堆栈中运行, 为什么要占用6倍的存储空间?

    所以这不是性能优化,可能会增加程序的内存。


    这是一个评论太长而无法评论:

    请注意,虽然所有堆栈分配可能在理论上被优化掉,但可能会分配更多的数据。 这不是OP所要求的,但可以考虑一下。 找到所需的最小分配量就相当于解决暂停问题。 设想一个程序结构为:

    <do 'something'>
    <call last thing which happens to require more
     stack space than everything else in 'something'>
    

    如果<do 'something'> do'something <do 'something'> “halts”,您只需要额外的堆栈空间。

    您还可以想象其他变化,其中优化变得非常困难。 例如,你的程序可以简单地用用户输入来评估一个3SAT表达式,并根据它来做一些事情 - 但是3SAT表达式可能有也可能没有任何结果为真的值。

    也许有一个更微不足道的情况:用户可能根本不会输入需要更多堆栈空间进行处理的输入。


    编译器可以做到这一点,但它可能是一个特定的优化,它可能不会。

    如果你有一个完全内联的程序,你可以考虑为函数调用设置栈帧的开销。

    但是,如果您还想摆脱局部变量的堆栈分配,编译器必须将这些局部变量转换为全局变量。 我知道没有编译器会这样做,并且在某些平台上,与局部变量相比,它需要额外的指令来引用全局变量(因为地址必须加载两条指令而不是一条)。 另外,由于引用堆栈变量是一种常见操作,因此通常将其编码为更小的指令。

    链接地址: http://www.djcxy.com/p/58851.html

    上一篇: No stack allocation whole program compilation?

    下一篇: How to pass a parameter to a SQL Job that will execute a stored procedure