Dre*_*mer 8 c++ optimization stack
我在Visual C++ 2008上尝试了这个代码,它显示A和B没有相同的地址.
int main()
{
{
int A;
printf("%p\n", &A);
}
int B;
printf("%p\n", &B);
}
Run Code Online (Sandbox Code Playgroud)
但是当B被定义时A不再存在,在我看来,相同的堆栈位置可以重用...
我不明白为什么编译器看起来不像一个非常简单的优化(例如在较大的变量和递归函数的上下文中可能很重要).并且似乎重用它不会在CPU和内存上更重.有没有人对此有解释?
我想答案是"因为它比它看起来要复杂得多",但老实说我不知道.
编辑:关于以下答案和评论的一些准确性.
这段代码的问题在于,每次调用此函数时,堆栈都会"增加一个整数".当然,这在示例中没有问题,但考虑大变量和递归调用,并且您可以轻松避免堆栈溢出.
我建议的是内存优化,但我不知道它会如何损害性能.
顺便说一句,这种情况发生在发布版本中,将进行所有优化.
为这样的本地人重用堆栈空间是一种非常常见的优化.事实上,在优化的构建中,如果你没有获取本地的地址,编译器甚至可能不会分配堆栈空间,变量只会存在于寄存器中.
由于多种原因,您可能看不到此优化.
首先,如果优化已关闭(如调试版本),编译器将不会执行其中任何一项以使调试更容易 - 您可以查看A的值,即使它不再在函数中使用.
如果您正在使用优化进行编译,我的猜测是,因为您正在获取本地的地址并将其传递给另一个函数,编译器不希望重用该存储,因为它不清楚该函数对该地址的作用.
还可以设想一个不使用此优化的编译器,除非函数使用的堆栈空间超过某个阈值.我不知道有任何编译器这样做,因为重用不再使用的局部变量空间没有成本,可以全面应用.
如果堆栈增长是您的应用程序的一个严重问题,即在某些情况下您遇到堆栈溢出,您不应该依赖编译器的堆栈空间优化.您应该考虑将堆栈上的大缓冲区移动到堆上,并努力消除非常深的递归.例如,在Windows上,线程默认具有1 MB堆栈.如果你担心溢出,因为你在每个堆栈帧上分配1k内存并进行1000次递归调用,修复不是试图诱使编译器从每个堆栈帧中节省一些空间.
归档时间: |
|
查看次数: |
1404 次 |
最近记录: |