【问题标题】:Is there language level optimization like RVO and NRVO?是否有像 RVO 和 NRVO 这样的语言级别优化?
【发布时间】:2013-12-20 04:03:43
【问题描述】:

RVO 是一种编译器优化,但可以提供非常有用的性能提升。但是,它不能保证,也不能依赖。

语言标准本身有什么可以优化返回值的吗?移动语义仍然复制成员值,对吗?

【问题讨论】:

  • 移动语义意味着尽可能少地复制。它通常只是指针交换。
  • 我想说 RVO 在很多情况下都可以依赖,除非您使用的是古老的编译器。任何足以支持移动语义的现代编译器都应该很好地掌握 RVO。并移动语义moves 事物。如果无法利用从不再使用的移动对象,这可能与副本相同,但它通常要快得多。

标签: c++ rvo


【解决方案1】:

我不知道我是否误解了您的问题,但 (N)RVO 实际上是“在语言标准本身中”。这称为复制省略,并在 §12.8.31 中进行了描述。

确实,移动构造比 RVO 在计算上更昂贵,因为正如您所说,它仍然必须将成员变量从一个内存位置“复制”到另一个内存位置(对象的浅拷贝)。 RVO 完全消除了这些读/写操作。

(N)RVO 在大多数情况下都有效,而它不能(当一个函数可以返回多个变量之一时)移动构造开始。

AFAIK 有一个共识,即自 C++11 以来,所有“优化返回值”的情况都已被充分覆盖

【讨论】:

  • 我在 N3337 当前标准的 12.8.31 中发现了复制省略...它说复制省略是 permitted ,但不是强制的..
  • 如果标准强制要求优化,那就太奇怪了。这不是正确的地方。无论如何,所有严肃的编译器都会做 RVO。
  • @ErikvanVelzen 与其他优化不同,NRVO/RVO 具有可观察到的副作用:其他优化是“好像”的,而 NRVO/RVO 可以显着改变程序行为。我怀疑最终会强制执行 NRVO/RVO。
  • @Yakk 老实说,即使它成为强制性的,它仍然是一个雷区。避免编写自己的移动/复制构造函数和赋值运算符并且永远不要让它们产生副作用是一个很好的策略。我能想到的唯一例外是当您编写容器时。
【解决方案2】:

C++11 保证在以某种方式从函数返回时隐式移动。

此外,您可以通过return {a,b,c};语法使用任何隐式构造函数直接构造返回值。

最后,rvo 如果失败就变成一个隐式移动,而上面的第一个隐式移动通常会变成 nrvo,因此这些技术很好地对齐。

【讨论】:

  • 你能把第一句话扩大一点吗?
  • @texasbruce:C++11 标准 12.8/32 要求“当满足或将满足复制操作的省略标准时,除了源对象是函数参数这一事实之外,并且要复制的对象由左值指定,首先执行为复制选择构造函数的重载决策,就好像对象由右值指定一样。
猜你喜欢
  • 2013-12-19
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 2018-08-03
  • 2020-04-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
相关资源
最近更新 更多