【问题标题】:Input parameter passing: is there a size threshold for efficient pass-by-value?输入参数传递:是否有有效的按值传递的大小阈值?
【发布时间】:2014-04-13 22:18:32
【问题描述】:

在 C++ 中,当输入参数复制起来很便宜(例如intfloat 等),它通常简单地按值传递 .相反,输入的“观察到”参数复制起来并不便宜(例如std::string)由const & 传递。

我想知道像 POD 这样的类型,它表示具有int 坐标的二维向量,例如

struct Vec2i
{
    int X;
    int Y;
};

在 32 位 MSVC 编译器上,它只有 8 个字节 (2 * sizeof(int))。你是按值传递还是通过const &传递?

如果Vec2d 具有double 类型的坐标呢?
(在 MSVC 上它将是 2 * sizeof(double),所以是 2 * 8 = 16 字节。)

是否有“大小阈值”(例如 16 字节?)用于放置一行并说:“对于大小 X 的 POD 通过 const &,对于较小的 POD 通过按价值”


PS:请不要在回复中使用参数作为“过早的优化”。
这对我来说听起来像是++itit++ 的情况(其中it 是一个STL 迭代器):并不是++it 是过早的优化,而是it++ 是一个过早悲观 :)

【问题讨论】:

  • +1 表示过早悲观。
  • 如果你关心,基准测试。跨架构没有通用答案。
  • @TonyD:我至少对 x86 和 x64 感兴趣; ARM 也是一个不错的补充。
  • 我认为对于像您列出的 Vec2i 这样简单的 POD 来说确实没有明显的区别。
  • @Mr.C64 - 如果有一个需要很长时间的用户定义的复制构造函数,这不是更多的问题吗?您可以创建一个“小”类,它的复制构造函数可能非常慢。

标签: c++ parameter-passing pass-by-value


【解决方案1】:

在幕后,一个驱动因素是是否可以在一个或多个寄存器中传递变量。在 20 世纪,当参数类型直接映射到寄存器时,编译器做得很好。在寄存器对中传递具有两个成员的结构是 21 世纪的优化。

正如您在 cmets 中提到的 x86,这是一种特殊情况。它是寄存器匮乏的,并且可能没有可用于参数传递的寄存器对。 x86 和 ARM 在这方面要好得多,这也是 x64 通常更快且 ARM 更省电的原因之一

boost::call_traits<T> 试图弄清楚通过引用传递T 是否明智,但这并不完美。

【讨论】:

  • 你写的时候可能有错别字“x86和ARM都好多了……”;也许您的意思是:x64 和 ARM...”
猜你喜欢
  • 1970-01-01
  • 2020-12-28
  • 2013-03-06
  • 2020-11-08
  • 2015-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多