【问题标题】:Example of polymorphism preventing compiler optimization?多态性阻止编译器优化的示例?
【发布时间】:2014-03-08 13:10:44
【问题描述】:

不记得我现在在哪里看到它了——但是我在某处读到动态多态性会阻止编译器进行各种优化。

除了内联之外,有人可以用多态性阻止编译器制造的这种“错过”优化机会的任何示例来启发我吗?

【问题讨论】:

  • 当然是内联。并初始化“常量”。暂时想不出别的了。
  • 我会说那些错过的优化是内联失败的影响。我认为这是最大的损失,这似乎是去虚拟化背后的最大动力。

标签: c++ gcc optimization compiler-construction polymorphism


【解决方案1】:

与:

Derived d;
d.vMethod(); // that will call Derived::vMethod statically (allowing inlining).

With(除非DerivedDerived::vMethod 之一在C++11 中声明为final):

void foo(Derived& d)
{
    d.vMethod(); // this will call virtually vMethod (disallowing inlining).
}

虚拟调用需要额外费用(作为通过 vtable 的间接调用)。

C++11 引入了final 关键字,这可能会变成静态调用中的最后一个例子。

【讨论】:

  • 间接调用在目标预测方面通常也更昂贵。通过静态调用,可以在处理器的前端计算目标地址,因此可以更快地纠正目标错误预测。此外,可变目标的硬件预测更复杂(当不只是预测与最后一次遇到指令时相同时),因此有时在简单的处理器中并不准确,并且对于“随机”目标的预测非常困难。
【解决方案2】:

至少在 C++ 中,多态对象必须是指针或引用的形式。有时这会阻止将它们放在堆栈变量或 List 类型上的可能性,您需要使用 List。堆栈变量备用动态分配等。

对 Poly.vmethod() 的调用总是在编译时解析,即使 vmethod() 是虚拟的,而 Poly->vmethod() 会查询虚拟方法表。 (好吧,如果方法是虚拟的,则意味着它是多态的。静态方法在任何一种情况下都是静态解析的。)

返回值优化 (RVO) 是另一个在返回指针或引用时没有位置的技巧。 RVO 通常通过传递一个隐藏参数来实现:一个指向内存区域的指针,其中填充了“返回的”对象。这个区域的大小和类型必须在编译时完全知道。

【讨论】:

  • 您能否详细说明您的 RVO 评论?
  • 多态对象可以存在于堆栈、按值集合等中,因为指针和引用可以指向任何内存。例如,void f(Base &o) { o.vmethod() } 可以这样调用:Derived on_stack; f(on_stack);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-12
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
  • 1970-01-01
相关资源
最近更新 更多