Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Input parameter passing: is there a size threshold for efficient pass-by-value?

In C++, when an input argument is cheap to copy (e.g. like an int, float, etc.), it's usually passed simply by value. Instead, input "observed" arguments that aren't cheap to copy (e.g. std::string) are passed by const &.

I was wondering about types like a POD representing a 2D vector having int coordinates, e.g.

struct Vec2i
{
    int X;
    int Y;
};

On 32-bit MSVC compiler, it's just 8 bytes (2 * sizeof(int)). Would you pass it by value or by const &?

And what about a Vec2d having double-type coordinates?
(On MSVC it would be 2 * sizeof(double), so 2 * 8 = 16 bytes.)

Is there a "size threshold" (e.g. 16 bytes?) for putting a line and say: "for PODs over size X pass by const &, and for smaller PODs pass by value"?


PS: Please don't use arguments as "premature optimization" in replies.
This to me sounds like the case of ++it vs. it++ (where it is an STL iterator): it's not that ++it is a premature optimization, the point is that it++ is a premature pessimization :)

like image 635
Mr.C64 Avatar asked Mar 10 '14 16:03

Mr.C64


1 Answers

Behind the scenes, one driving factor is whether it's possible to pass a variable in one or more registers. In the 20th century, compilers were doing quite well when an argument type mapped directly to a register. Passing a structure with two members in a register pair is a 21st century optimization.

As you mention x86 in your comments, that's a special case. It's register-starved, and may not have a register pair available for argument passing. Both x86 and ARM are much better in this respect, one of the reasons why x64 is often faster and ARM more power-economic

boost::call_traits<T> is an attempt to figure out whether it's smart to pass T by reference, but it's not perfect.

like image 171
MSalters Avatar answered Sep 21 '22 15:09

MSalters