输入参数传递:是不是有有效的按值传递的大小阈值?
Posted
技术标签:
【中文标题】输入参数传递:是不是有有效的按值传递的大小阈值?【英文标题】:Input parameter passing: is there a size threshold for efficient pass-by-value?输入参数传递:是否有有效的按值传递的大小阈值? 【发布时间】:2014-04-13 22:18:32 【问题描述】:在 C++ 中,当输入参数复制起来很便宜(例如int
、float
等),它通常简单地按值传递 .相反,输入的“观察到”参数复制起来并不便宜(例如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:请不要在回复中使用参数作为“过早的优化”。
这对我来说听起来像是++it
与it++
的情况(其中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...”?以上是关于输入参数传递:是不是有有效的按值传递的大小阈值?的主要内容,如果未能解决你的问题,请参考以下文章