Seite 1 von 1

RVO + Move Constructors

Verfasst: 07.02.2012, 10:49
von RustySpoon
Servus!

Mal angenommen, ich habe folgende Definitionen:

Code: Alles auswählen

struct a
{
    a()             { std::cout << "cons" << std::endl; }
    a(a const& o)   { std::cout << "copy cons" << std::endl; }
    a(a&& o)        { std::cout << "move cons" << std::endl; }
};

a f(a b)
{
    return b;
}
Kann mir jemand stichhaltig erklären, warum folgender Code...

Code: Alles auswählen

auto b = a();
b = f(std::move(b));
...zu dieser Ausgabe führt?
cons
move cons
move cons
Was ich im Wesentlich nicht verstehe ist, warum der Compiler nicht im Stande ist via RVO den zweiten Move wegzuoptimieren?

Ich verwende den GCC 4.6.2 nur mit -O3.

Re: RVO + Move Constructors

Verfasst: 07.02.2012, 11:01
von CodingCat
Kurze Antwort: RVO funktioniert nicht bei Rückgabe von Parametern.

Lange Antwort: Abschnitt Reality Bites.
Reality Bites hat geschrieben:Second, I’ve yet to find a compiler that will elide the copy when a function parameter is returned, as in our implementation of sorted. When you think about how these elisions are done, it makes sense: without some form of inter-procedural optimization, the caller of sorted can’t know that the argument (and not some other object) will eventually be returned, so the compiler must allocate separate space on the stack for the argument and the return value.

If you need to return a function parameter, you can still get near-optimal performance by swapping into a default-constructed return value (provided default construction and swap are cheap, as they should be):

Re: RVO + Move Constructors

Verfasst: 07.02.2012, 12:04
von Schrompf
Das hieße ja dann, dann Link Time Code Generation (oder das Äquivalent beim GCC) diese Kopie vermeiden können müsste.

Re: RVO + Move Constructors

Verfasst: 07.02.2012, 13:24
von RustySpoon
Danke Jungs!

Schade, ich hätte schon gehofft, dass der Compiler clever genug ist, zu erkennen, dass der Argument- und Return-Value-Stack-Slot zusammengelegt werden können. GCC und LTO schau ich mir grad an, hat jemand Erfahrung damit? Scheint alles noch etwas unausgereift/frickelig zusein, na mal schauen...

Re: RVO + Move Constructors

Verfasst: 07.02.2012, 13:26
von Schrompf
Beim GCC weiß ich das nicht, aber nach meinem Wissen geht das dort ganz gut, auch wenn die Doku dazu hundsmiserabel ist. Unter Visual Studio ist LTCG der Standard für Release Builds und bewirkt nach meinem Ermessen Performance-Wunder. Ich bekomme üblicherweise nochmal die doppelte bis dreifache Performance gegenüber einem volloptimierten Build ohne LTCG.

Re: RVO + Move Constructors

Verfasst: 08.02.2012, 17:00
von RustySpoon
Falls es wen interessiert: Ich hab das nunmal getestet und LTO greift in diesem speziellen Fall nicht. Natürlich gut möglich, dass ich mich einfach zu dusslig angstellt hab und es dennoch irgendwie geht.

Btw.: GCC 4.6.2 scheint noch ein paar Probleme mit -flto in Kombination mit OS X 10.6 zu haben. Die experimentelle 4.7.0 aus dem SVN-Repo tut's aber. Ich hab -flto und -fwhole-program als Flags benutzt.