C ++内联函数&上下文特定优化

时间:2014-07-10 13:17:46

标签: c++ optimization compiler-optimization inline-functions

我读过Scott Meyers'有效的C ++书籍:

内联函数时,可以使编译器对函数体执行特定于上下文的优化。正常的函数调用不可能进行这样的优化。

现在的问题是:什么是特定于上下文的优化以及为什么需要它?

4 个答案:

答案 0 :(得分:6)

我不认为"特定于上下文的优化"是一个定义的术语,但我认为它基本上意味着编译器可以分析调用站点及其周围的代码,并使用此信息来优化函数。

这是一个例子。当然,它是设计的,但它应该证明这个想法:

功能:

int foo(int i)
{
  if (i < 0) throw std::invalid_argument("");
  return -i;
}

致电网站:

int bar()
{
  int i = 5;
  return foo(i);
}

如果单独编译foo,它必须包含比较和抛出异常的代码。如果它在bar中内联,则编译器会看到以下代码:

int bar()
{
  int i = 5;
  if (i < 0) throw std::invalid_argument("");
  return -i;
}

任何理智的优化工具都会将其评估为

int bar()
{
  return -5;
}

答案 1 :(得分:2)

如果编译选择内联函数,它将替换函数体对此函数的函数调用。现在它有更多的代码可以在调用者函数体内进行优化。因此,它通常会带来更好的代码。

想象一下:

bool callee(bool a){
   if(a) return false;
   else return true;
}

void caller(){
   if(callee(true)){
       //Do something
   }   
   //Do something
}

一旦内联,代码就像这样(近似地):

void caller(){
   bool a = true;
   bool ret;
   if(a) ret = false;
   else ret = true;

   if(ret){
       //Do something
   }   
   //Do something
}

也可以进一步优化:

void caller(){
   if(false){
       //Do something
   }   
   //Do something
}

然后:

void caller(){
   //Do something
}

现在这个功能要小得多,你没有功能调用的成本,特别是(关于问题)分支的成本。

答案 2 :(得分:2)

说功能是

void fun( bool b) { if(b) do_sth1(); else do_sth2(); }

并在具有预定义false参数

的上下文中调用它
bool param = false;
...
fun( param);

然后编译器可以将函数体缩减为

...
do_sth2();

答案 3 :(得分:0)

我不认为特定于上下文的优化意味着特定的内容,您可能无法找到准确的定义。

很好的例子是某些类属性的经典getter,没有内联程序必须:

  1. 跳到吸气体
  2. 使用默认的Visual Studio设置将值移动到注册表(eax下的x86下)
  3. 跳回callee
  4. 将值从eax移至本地变量
  5. 使用内联可以跳过几乎所有工作并将值直接移动到局部变量。

    优化严格依赖于编译器,但很多思考都可能发生(可能会跳过变量分配,代码可能会重新排序等等......但是你总是保存调用/跳转,这是昂贵的指令。

    有关优化here的更多信息。