4

我在 Scott Meyers 的 Effective C++ 书中读到:

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

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

4

4 回答 4

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;
}
于 2014-07-10T13:22:39.970 回答
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
}

该函数现在要小得多,并且您没有函数调用的成本,尤其是(关于问题)分支的成本。

于 2014-07-10T13:19:47.967 回答
2

说功能是

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

并在上下文中使用预定义的false参数调用

bool param = false;
...
fun( param);

那么编译器可能会将函数体简化为

...
do_sth2();
于 2014-07-10T13:21:44.640 回答
0

我不认为特定于上下文的优化意味着特定的东西,你可能找不到确切的定义。

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

  1. 跳到吸气剂体
  2. 将值移动到注册表(eaxx86具有默认 Visual Studio 设置的 Windows 下)
  3. 跳回被调用者
  4. 将值从eax局部变量移动

而使用内联可以跳过几乎所有的工作并将值直接移动到局部变量。

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

更多关于优化的阅读在这里

于 2014-07-10T13:28:24.797 回答