Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

return by value inline functions

I'm implementing some math types and I want to optimize the operators to minimize the amount of memory created, destroyed, and copied. To demonstrate I'll show you part of my Quaternion implementation.

class Quaternion
{
public:
    double w,x,y,z;

    ...

    Quaternion  operator+(const Quaternion &other) const;
}

I want to know how the two following implementations differ from eachother. I do have a += implementation that operates in-place to where no memory is created, but some higher level operations utilizing quaternions it's useful to use + and not +=.

__forceinline Quaternion Quaternion::operator+( const Quaternion &other ) const
{
    return Quaternion(w+other.w,x+other.x,y+other.y,z+other.z);
}

and

__forceinline Quaternion Quaternion::operator+( const Quaternion &other ) const
{
    Quaternion q(w+other.w,x+other.x,y+other.y,z+other.z);
    return q;
}

My c++ is completely self-taught so when it comes to some optimizations, I'm unsure what to do because I do not know exactly how the compiler handles these things. Also how do these mechanics translate to non-inline implementations.

Any other criticisms of my code are welcomed.

like image 265
Mark Avatar asked Aug 21 '09 19:08

Mark


People also ask

What is the inline function in C++?

Inline function in C++ is an enhancement feature that improves the execution time and speed of the program. The main advantage of inline functions is that you can use them with C++ classes as well.

Can we use loop in inline function?

A function with loops can be made inline, But every time a function is called, there is a certain amount of performance overhead that occurs.

What is inline function example?

Example. In the following class declaration, the Account constructor is an inline function. The member functions GetBalance , Deposit , and Withdraw aren't specified as inline but can be implemented as inline functions. In the class declaration, the functions were declared without the inline keyword.

Is inline always faster?

inline functions might make the code faster, they might make it slower. They might make the executable larger, they might make it smaller.


3 Answers

Your first example allows the compiler to potentially use somehting called "Return Value Optimization" (RVO).

The second example allows the compiler to potentially use something called "Named Return Value Optimization" (NRVO). These 2 optimizations are clearly closely related.

Some details of Microsoft's implementation of NRVO can be found here:

  • http://msdn.microsoft.com/en-us/library/ms364057.aspx

Note that the article indicates that NRVO support started with VS 2005 (MSVC 8.0). It doesn't specifically say whether the same applies to RVO or not, but I believe that MSVC used RVO optimizations before version 8.0.

This article about Move Constructors by Andrei Alexandrescu has good information about how RVO works (and when and why compilers might not use it).

Including this bit:

you'll be disappointed to hear that each compiler, and often each compiler version, has its own rules for detecting and applying RVO. Some apply RVO only to functions returning unnamed temporaries (the simplest form of RVO). The more sophisticated ones also apply RVO when there's a named result that the function returns (the so-called Named RVO, or NRVO).

In essence, when writing code, you can count on RVO being portably applied to your code depending on how you exactly write the code (under a very fluid definition of "exactly"), the phase of the moon, and the size of your shoes.

The article was written in 2003 and compilers should be much improved by now; hopefully, the phase of the moon is less important to when the compiler might use RVO/NRVO (maybe it's down to day-of-the-week). As noted above it appears that MS didn't implement NRVO until 2005. Maybe that's when someone working on the compiler at Microsoft got a new pair of more comfortable shoes a half-size larger than before.

Your examples are simple enough that I'd expect both to generate equivalent code with more recent compiler versions.

like image 196
Michael Burr Avatar answered Sep 20 '22 03:09

Michael Burr


Between the two implementations you presented, there really is no difference. Any compiler doing any sort of optimizations whatsoever will optimize your local variable out.

As for the += operator, a slightly more involved discussion about whether or not you want your Quaternions to be immutable objects is probably required... I would always lead towards creating objects like this as immutable objects. (but then again, I'm more of a managed coder as well)

like image 33
LorenVS Avatar answered Sep 17 '22 03:09

LorenVS


If these two implementations do not generate exactly the same assembly code when optimization is turned on, you should consider using a different compiler. :) And I don't think it matters whether or not the function is inlined.

By the way, be aware that __forceinline is very non-portable. I would just use plain old standard inline and let the compiler decide.

like image 27
Dima Avatar answered Sep 17 '22 03:09

Dima