【问题标题】:return value optimization vs auto_ptr for large vectors大向量的返回值优化与 auto_ptr
【发布时间】:2012-05-04 13:33:27
【问题描述】:

如果我使用 auto_ptr 作为填充大型向量的函数的返回值,这会使该函数成为源函数(它将创建一个内部 auto_ptr 并在返回非 const auto_ptr 时传递所有权)。但是,我不能将此函数与 STL 算法一起使用,因为为了访问数据,我需要取消对 auto_ptr 的引用。我猜一个很好的例子是一个大小为 N 的向量字段,每个向量有 100 个分量。如果 N 很大,该函数是否按值或按 ref 返回每个 100 个分量向量是不一样的。

另外,当我尝试这个非常基本的代码时:

class t
{
    public: 
         t() { std::cout << "ctor" << std::endl; }
         ~t() { std::cout << "dtor" << std::endl; }
};

t valueFun()
{
   return t();
}

std::auto_ptr<t> autoFun()
{
   return std::auto_ptr(new t());
}

autoFun 和 fun 调用都会产生输出

导演 管理员

所以我实际上看不到正在创建以传递给 return 语句的自动变量。这是否意味着为 valueFun 调用设置了返回值优化?在这种情况下 valueFun 是否会创建两个自动对象?

然后,我如何使用函数优化大量如此庞大的数据结构?

【问题讨论】:

  • 您是否在问 RVO 是否也适用于您的大型向量?如果是这样,你不能用上面的例子来测试它吗?
  • 当我测试它时,这是否意味着它适用于所有编译器/平台?我怎么知道 RVO 是否包含在内,我应该阅读编译器规范吗?如果代码在使用不同编译器的 HPC 集群上编译,并且库很大,会发生什么情况?
  • 是的,我明白你的意思。这是编译器允许但不需要做的事情之一,所以你永远无法确定。顺便说一句,你有 C++11 支持吗?

标签: c++ auto-ptr rvo


【解决方案1】:

这有很多选择,动态分配可能不是最好的。


在我们深入讨论之前:这是一个瓶颈吗?

如果您没有分析并确保它是一个瓶颈,那么这个讨论可能完全没有意义......请记住,分析调试版本几乎没有用。


现在,在 C++03 中,有几种选择,从最可口到最少:

  • 信任编译器:例如,即使在 gcc 中的调试版本中,未命名的变量也会使用 RVO。
  • 使用“out”参数(通过引用传递)
  • 在堆上分配并返回一个指针(智能与否)
  • 检查编译器输出

就个人而言,除非分析器证明我错了,否则我会相信我的编译器。

在 C++11 中,移动语义帮助我们更加自信,因为每当有 return 语句时,如果 RVO 无法启动,则可以自动使用移动构造函数(如果可用);并在vector 上移动构造函数非常便宜。

这样就变成了:

  • 信任编译器:RVO 或移动语义
  • 在堆上分配并返回unique_ptr

但实际上,第二点应该仅用于移动语义没有太大帮助的少数类:移动语义的成本通常与sizeof 的返回成正比,例如std::array&lt;T,10&gt; 的大小等于到10*sizeof(T),所以它不是很好,可能会受益于堆分配+unique_ptr


Tangent:你已经信任你的编译器了。你相信它会警告你错误,你相信它会警告你危险/可能不正确的结构,你相信它可以正确地将你的代码翻译成机器程序集,你相信它会应用有意义的优化来获得不错的加速.. . 不相信编译器在明显的情况下应用 RVO 就像不相信你的心脏外科医生拿着 10 美元的钞票:这是你最不用担心的。 ;)

【讨论】:

  • 非常感谢您的切线! :)
【解决方案2】:

我相当肯定编译器会为 valueFun 做返回值优化。编译器无法应用返回值优化的主要情况有:

  • 返回参数
  • 根据条件返回不同的对象

因此 auto_ptr 不是必需的,并且由于必须使用堆而会更慢。

如果您仍然担心移动如此大的向量的成本,您可能想考虑使用移动语义(C++11 的std::vector aCopy(std::move(otherVector))。这些几乎与 RVO 一样快,并且可以在任何地方都可以使用(在不能使用RVO时也保证用于返回值。)

我相信目前大多数现代编译器都支持移动语义(或技术上的右值引用)

【讨论】:

  • “相当肯定”让我有点困扰。 :) 从我的角度来看,如果我要在 100 个内核上运行这个东西并且它会随着时间的推移而增长,我需要 100% 确定代码的作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-02
  • 1970-01-01
  • 2023-03-30
  • 2016-06-26
相关资源
最近更新 更多