MWB
MWB

Reputation: 12567

GCC: when can I expect returning large C++ objects to be efficient?

This questions is about C++98/C++03 rather than C++11, and is specific to the latest GCC (4.8) with the optimization turned on (e.g. -O3)

If I'm working with large objects, e.g.

struct point {
  float x, y;
};

typedef vector<point> points;

struct two {
  points a, b;
};

when can I expect GCC to optimize the returns of such objects from a function or method, such as

vector<two> large;
//...
return large;

Upvotes: 1

Views: 133

Answers (3)

As Pepper_chico commented, it is related to return value optimization (RVO).

However, you could also consider the ABI specification for your particular implementation. The x86-64 ABI (and x86 calling conventions) specifies that on some occasions, a pair of registers can be used to return a small structure (instead of passing it on the stack)

BTW you could look at the generated assembly (using g++ -fverbose-asm -S -O3) or at intermediate gimple representations (dumping a lot of files with them using g++ -fdump-tree-all -O3, or using MELT ....).

Some "large" objects are actually implemented as pointers (fitting in a register). For instance instances of std::string (on Linux, with libstdc++ from GCC 4.7 or 4.8, sizeof(std::string) == sizeof(void*)), even if the underlying string has millions of bytes. Likewise, sizeof(std::vector<point>) is often 3*sizeof(void*) even for vectors of millions of point-s ...

Upvotes: 1

mockinterface
mockinterface

Reputation: 14860

The well known rule of thumb for returning objects in C++98/03 is that you'll get most out of GCC if your objects can fit into your CPU register(s). Return such objects by value, return objects larger than this by a reference or a pointer.

With the C++11 standard there is more freedom for the compiler to move objects and of course for you to move them explicitly. With C++11 I'd start by returning everything you can by value and measure the hotpath coupled with inspecting the generated assembly to decide if switching to returning by references is worthwhile. A classic read on this is Want Speed? Pass by Value..

Upvotes: 1

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145279

You can always expect efficiency when you have guaranteed it, e.g. by moving.

Otherwise it's a good to assume efficiency until the contrary has been proved by measuring.

g++ 4.8 implements most C++11 features including move semantics, and std::vector does have move constructor (i.e., you're not dependent on RVO).

Upvotes: 1

Related Questions