输入参数传递:是不是有有效的按值传递的大小阈值?

Posted

技术标签:

【中文标题】输入参数传递:是不是有有效的按值传递的大小阈值?【英文标题】: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 - 如果有一个需要很长时间的用户定义的复制构造函数,这不是更多的问题吗?您可以创建一个“小”类,它的复制构造函数可能非常慢。 【参考方案1】:

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

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

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

【讨论】:

你写的时候可能有错别字“x86和ARM都好多了……”;也许您的意思是:x64 和 ARM...”

以上是关于输入参数传递:是不是有有效的按值传递的大小阈值?的主要内容,如果未能解决你的问题,请参考以下文章

浅析js的函数的按值传递参数

Java的按值传递和按引用传递解说

String的按值传递,java传参都是传值

String的按值传递,java传参都是传值(转)

java的按值传递与按引用传递

对 Java 的按值传递和不变性感到困惑