为什么内联被认为比函数调用快? [英] Why is inlining considered faster than a function call?

查看:271
本文介绍了为什么内联被认为比函数调用快?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在,我知道这是因为没有调用函数的开销,但是调用一个函数的开销真的很重(并且值得膨胀的膨胀)。

Now, I know it's because there's not the overhead of calling a function, but is the overhead of calling a function really that heavy (and worth the bloat of having it inlined) ?

从我可以记住,当一个函数被调用,说f(x,y),x和y被推到堆栈,并且堆栈指针跳转到一个空块,并开始执行。我知道这是一个过度简化,但我错过了什么?几个推和一个跳转调用一个函数,是真的有很多开销吗?

From what I can remember, when a function is called, say f(x,y), x and y are pushed onto the stack, and the stack pointer jumps to an empty block, and begins execution. I know this is a bit of an oversimplification, but am I missing something? A few pushes and a jump to call a function, is there really that much overhead?

让我知道如果我忘记了什么,谢谢!

Let me know if I'm forgetting something, thanks!

推荐答案

p>除了没有呼叫(因此没有相关费用,如呼叫前的参数准备和呼叫后的清除)的事实之外,还有另一个显着的内联优点。当函数体内联时,它的body可以在调用者的特定上下文中重新解释。这可能立即允许编译器进一步缩减和优化代码。

Aside from the fact that there's no call (and therefore no associated expenses, like parameter preparation before the call and cleanup after the call), there's another significant advantage of inlining. When the function body is inlined, it's body can be re-interpreted in the specific context of the caller. This might immediately allow the compiler to further reduce and optimize the code.

对于一个简单的例子,这个函数

For one simple example, this function

void foo(bool b) {
  if (b) {
    // something
  }
  else {
    // something else
  }
}

-inline函数

foo(true);
...
foo(false);

但是,如果上述调用是内联的,编译器将立即消除分支。基本上,在上面的情况下,内联允许编译器将函数参数解释为编译时常量(如果参数是编译时常量) - 通常用非内联函数是不可能的。

However, if the above calls are inlined, the compiler will immediately be able to eliminate the branching. Essentially, in the above case inlining allows the compiler to interpret the function argument as a compile-time constant (if the parameter is a compile-time constant) - something that is generally not possible with non-inlined functions.

但是,它甚至不再局限于此。一般来说,内联的优化机会显着更深远。对于另一个例子,当函数体内联到特定的呼叫者上下文中时,编译器通常能够将调用代码中存在的已知的混叠相关关系传播到内联函数代码中,从而使得可以更好地优化函数的代码。

However, it is not even remotely limited to that. In general, the optimization opportunities enabled of inlining are significantly more far-reaching. For another example, when the function body is inlined into the specific caller's context, the compiler in general case will be able to propagate the known aliasing-related relationships present in the calling code into the inlined function code, thus making it possible to optimize the function's code better.

同样,可能的例子有很多,所有这些都源自基本事实,即内联调用沉浸在特定呼叫者的上下文,从而实现各种内联上下文优化,这对于非内联呼叫是不可能的。通过内联,您基本上可以获得原始功能的许多个别版本,每个版本都针对每个特定的呼叫方上下文进行定制和优化。价格显然是代码膨胀的潜在危险,但如果正确使用,它可以提供显着的性能优势。

Again, the possible examples are numerous, all of them stemming from the basic fact that inlined calls are immersed into the specific caller's context, thus enabling various inter-context optimizations, which would not be possible with non-inlined calles. With inlining you basically get many individual versions of your original function, each version is tailored and optimized individually for each specific caller context. The price of that is, obviously, the potential danger of code bloat, but if used correctly, it can provide noticeable performance benefits.

这篇关于为什么内联被认为比函数调用快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆