c/c++语言开发共享循环内的堆栈分配

在C中,当你编写这样的代码时:

void some_function(void) { while (something) { char buf[4096]; ... } } 

在调用函数时是否会发生buf的分配? 或者是否为循环的每次迭代都会进行单独的分配?

如果我把buf的声明放在循环之外(即在函数的开头),会有任何性能提升吗?

    buf在堆栈中some_function的框架中分配。 它只在调用some_function时分配一次。 所以即使你把buf的声明放在外面,你也不会获得任何性能提升。

    但是,如果你写一些类似的东西,那就不一样了

     while (...) { int a = 5; } 

    在循环。 赋值在每次迭代时发生。

    实际上,缓冲区是在循环的每次迭代中分配的。 但是,编译器优化,并且在没有初始化器的情况下,它们实际上不会生成代码来执行任何操作以在每次迭代时分配空间; 就好像变量是在循环之外声明的那样。 在定义中添加初始化,您将看到对性能的影响,因为初始化将在循环的每次迭代中完成。

    在通用处理器(x86,PowerPC,ARM)上的堆栈上分配最多是一条改变堆栈指针寄存器的指令。 这根本不会影响性能(见下面的注释)。 此外,编译器也可以为您提供循环外的堆栈分配。 底线是增益很小甚至没有。

    注意:更改堆栈指针寄存器会在无序处理器中引入指令依赖性。

    C标准允许编译器在每次迭代中分配和释放一次,或者为函数分配和释放一次。 在实践中,我见过的每个编译器都为该函数分配,而且还有很多。 然而,即使每次迭代分配一次,差异仍然是〜2指令使堆栈指针向下和向上碰撞(或向上和向下用于向上增长的堆栈)。 看到显着的性能差异将是罕见的。

    在您的具体情况下,可能没有性能损失。 在最坏的情况下(没有任何优化),分配但是类似于:

      sub sp, #4096 

    和解除分配是这样的

      add sp, #4096 

    请记住,即使没有优化,对于循环中定义的所有局部变量,也可能只发生一次。 如果您有这样的事情:

    它可能会被翻译成类似的东西

      sub sp, #4100 . . . . add sp, #4100 

    这样做

     void some_function(void) { char buf[4096]; while (something) { int x; ... } } 

    对于表现没有任何改变。

    添加初始化:

     void some_function(void) { while (something) { char buf[4096] = "Something" ; int x; ... } } 

    会增加性能。 在大多数情况下,开销很小。

    但是,将对象放在打开Internet连接的循环中会大大减慢速度。

    这是一个平衡问题。 对于大多数应用,

      char buf[4096] = "Something" ; 

    不明显。 在处理实时中断的循环中,它可能是关键的。

    代码清晰。 尽可能限制可变范围可提高清晰度。 表现来自表格设计; 没有编码。 如果您通过实际测量发现某些特定的编码结构导致运行缓慢,那么您可以更改代码。

      以上就是c/c++开发分享循环内的堆栈分配相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/523262.html

      (0)
      上一篇 2020年12月11日
      下一篇 2020年12月11日

      精彩推荐