【问题标题】:Are std::functions inlined by the C++11 compiler?C++11 编译器是否内联了 std::functions?
【发布时间】:2013-05-19 18:11:47
【问题描述】:

我正在使用 C++11 开发一个小型数学优化框架,我想知道用户提供特定领域逻辑的最佳方式是什么。我可以强迫她使用框架可以调用的钩子方法定义类,但我想保持精简并尽可能利用新的 C++11 工具。所以我正在考虑接受 std::function 对象,可能是从 lambda 表达式实例化的,作为参数,并在需要时调用它们。我想知道的唯一想法是编译器(在我的情况下是 gcc,但我也想了解 Xcode 和 Visual C++)是否能够获取 std::function 对象并内联函数定义,以便它们与其余代码一起优化。

PS:从 cmets 看来,我的问题的第一个修订版对大多数用户来说都是模糊的,这可能是我使用不正确语言的错。所以我改写了它,我希望有人能理解我在这里试图传达的概念(并可能提出解决方案)。

PPS:有人建议使用模板,这是我考虑过的一个想法,但我想知道是否有替代方案。我对模板没有任何反对意见,但我计划在这个版本工作后立即制作一个基于模板的版本,因为我发现根据动态对象进行推理更容易。

【问题讨论】:

  • 怎么样...模板?
  • 我计划在第一个版本运行后立即使用模板进行编译时优化。
  • 编译 std::function 对象了吗?这是什么意思?
  • 现在更清楚了。 std::function 绝不是轻或瘦的。这是一个非常复杂的多态包装器,具有许多特性,但需要付出一定的代价。例如,std::function 进行一些堆分配!我不了解 GCC,但在 Visual Studio 中,std::function 是优化的障碍,因此您将进行间接调用。如果你想内联使用模板作为参数而不是 std::function。
  • 我在stackoverflow.com/a/11127742/981959描述了GCC的std::function的一些实现细节(以及它们如何影响优化)

标签: c++ compiler-construction c++11 compiler-optimization lambda


【解决方案1】:

std::function 是一个可调用对象,可以存储任何个可调用对象。它在设计上尽可能灵活。然而,这种设计也有缺点。因为functions 可以包含几乎任何东西(可调用),所以它们必须能够处理任何东西

在内部,function 在编译时不知道它可能存储什么。由于此确定是在运行时进行的,因此大多数普通编译器几乎不可能内联。通过函数指针内联是可能的,但前提是它在本地知道该指针的值是什么。 function 比单纯的函数指针复杂得多。

理论上可以内联这样的东西,但仅作为某种配置文件引导的优化系统的一部分,其中重复执行代码能够确定某些function 对象将始终与某些内容一起使用从而内联它们。但即便如此

如果你想内联任意可调用对象,你应该使用模板函数,而不是std::functionfunction 适用于当你不能使用模板(可能是因为你需要在一个容器中存储多个函数,或者因为你不想破坏封装,或其他什么),但仍然需要存储任意可调用对象。

【讨论】:

  • 调用std::function 的成本与调用struct foo { virtual void do_stuff() = 0; } 的成本相似。创建std::function 的边际成本是复制底层类型(可以是函数指针、lambda 或其他)的成本,加上比底层类型稍大的空闲存储(堆)分配。创建std::function 的固定成本是template 构造函数创建的代码,该构造函数创建pImpl 类型类,带有virtual 函数表。 (这假设std::function 的实现相对传统)
  • @Yakk:请注意,某些实现确实使用小对象优化来避免在可能的情况下进行堆分配。
猜你喜欢
  • 2015-11-09
  • 1970-01-01
  • 1970-01-01
  • 2019-11-07
  • 1970-01-01
  • 2019-03-18
  • 1970-01-01
  • 1970-01-01
  • 2015-09-12
相关资源
最近更新 更多