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

4

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

当你将一个函数内联时,你可以使编译器对函数体进行上下文特定的优化。这种优化是普通函数调用所无法实现的。

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

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;
}

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

假设这个函数是:

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

它在上下文中被称为预定义的false参数。

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

那么编译器可能会将函数体简化为
...
do_sth2();

0

我认为上下文特定优化并没有具体的含义,你可能找不到确切的定义。

一个很好的例子是某些类属性的经典getter,在不进行内联的情况下,程序必须执行以下操作:

  1. 跳转到getter主体
  2. 将值移动到寄存器(在默认Visual Studio设置下,Windows上的x86中为eax
  3. 跳回调用者
  4. 将值从eax移动到局部变量

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

优化严格依赖于编译器,但很多事情都可能发生(变量分配可能被跳过,代码可能被重新排序等等...但你总是可以节省昂贵的调用/跳转指令。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接