【问题标题】:Why is there overhead when calling functions?为什么调用函数时会有开销?
【发布时间】:2015-10-25 02:10:16
【问题描述】:

通常,人们谈到在程序中调用函数会产生一定量的开销,或者是不可避免的一组额外的关注点和情况。与没有函数调用的类似程序相比,这可以更好地解释和比较吗?

【问题讨论】:

  • 你指的“这些套路”是什么?
  • 内联并不总是可能的。递归函数、虚函数和函数指针都是示例。 (有时它们仍然可以内联,但不是在一般情况下)
  • 同样重要的是要注意,输入参数有时是常量值(硬编码参数,例如循环计数,在编译时已知,但因调用站点而异)。 inlineing 此类函数会将这些常量值暴露给编译器,从而实现更积极的优化。

标签: c performance optimization memory-management overhead


【解决方案1】:

这取决于您的编译器设置及其优化代码的方式。一些函数是内联的。其他人不是。这通常取决于您是针对大小进行优化还是针对速度进行优化。

一般来说,调用函数会导致延迟有两个原因:

  • 程序需要挂钩到内存中函数代码开始的某个随机位置。为此,它需要将当前光标位置保存到堆栈中,以便知道从哪里返回。此进程消耗多个 CPU 周期。

  • 根据您的 CPU 体系结构,可能存在一个管道,它与您当前的指令执行并行地将内存中的下几条指令提取到 CPU 缓存中。这是为了加快执行速度。当您调用一个函数时,游标会挂接到一个完全不同的地址,并且所有缓存的指令都会从管道中刷新。这会导致进一步的延迟。

【讨论】:

  • 1) 和 2) 不是标准。现代架构可以很好地预测代码执行。另请注意,函数调用总是是可预测的,因为您知道执行的位置,因此您可以预取代码并填充管道。那里没有延误。
  • 它们适用于 x86 架构 AFAIK
  • 不,x86 CALL 这些天大约是一个周期。
  • 调用约定也很重要。需要保存和恢复被调用者和调用者破坏的寄存器。当您添加堆栈调整和帧指针时,内联小函数通常更便宜,即使在优化大小时也是如此。
【解决方案2】:

另请参阅 herehere,了解有关内联何时有意义的讨论。

  • 内联

    一般情况下,您只能向编译器建议inline 一个函数,但编译器可能会做出其他决定。 Visual Studio 提供了自己的 forceinline 关键字。有些函数不能内联,例如当它们是递归的或在编译时无法确定目标函数时(通过函数表调用,C++ 中的虚函数调用)。

    我建议你相信编译器是否应该内联函数。如果您真的想内联代码,请考虑改用宏。

  • 开销

    使用函数时内存开销最小,因为您不会重复代码;内联代码被复制到调用站点。现在的性能开销可以忽略不计,因为现代架构真的很好地预测和调用,只需大约 1-2 个周期开销。

【讨论】:

    【解决方案3】:

    函数可以是inlined,但规范(大多数情况下)是函数位于特定地址,传递给函数的值放入堆栈,然后将结果放入堆栈并返回。

    【讨论】:

    • 在优化代码以使数据尽可能接近执行时,几乎所有架构都使用基于寄存器的调用约定。返回值总是在寄存器中返回。
    • 有些是,但我认为这是一种优化。我做了很多嵌入式编程,其中很多都没有多少寄存器空间来做到这一点。
    • @Jens x86 仍然使用基于堆栈的调用约定,并且由于缺少寄存器,大多数其他微控制器仍然使用堆栈来传递参数。仅当寄存器足够小以适合 1 或 2 个寄存器时,返回值才会通过寄存器传递,否则将通过堆栈返回
    【解决方案4】:

    如果满足某些条件,函数当然可以内联,但它们绝对不总是内联。大多数情况下,调用函数会产生真正的非内联函数调用。函数调用附带一些额外的费用,例如

    • 根据函数的调用约定为函数准备参数
    • 接收函数的返回值
    • 函数序言和结语代码,负责本地内存管理、参数内存管理和寄存器值保存
    • 函数可能会破坏某些 CPU 寄存器,从而破坏它们在调用代码中的使用,从而阻碍优化
    • 以非线性方式执行的代码的 CPU 缓存友好和虚拟内存友好行为较少

    如果函数体内嵌到调用代码中,所有这些都会产生开销。

    【讨论】:

      猜你喜欢
      • 2015-10-21
      • 1970-01-01
      • 2018-08-24
      • 1970-01-01
      • 1970-01-01
      • 2013-07-24
      • 2018-12-25
      • 2013-08-01
      • 2020-07-03
      相关资源
      最近更新 更多