RVO + Move Constructors

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
RustySpoon
Establishment
Beiträge: 298
Registriert: 17.03.2009, 13:59
Wohnort: Dresden

RVO + Move Constructors

Beitrag 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.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: RVO + Move Constructors

Beitrag 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):
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: RVO + Move Constructors

Beitrag von Schrompf »

Das hieße ja dann, dann Link Time Code Generation (oder das Äquivalent beim GCC) diese Kopie vermeiden können müsste.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
RustySpoon
Establishment
Beiträge: 298
Registriert: 17.03.2009, 13:59
Wohnort: Dresden

Re: RVO + Move Constructors

Beitrag 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...
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: RVO + Move Constructors

Beitrag 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.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
RustySpoon
Establishment
Beiträge: 298
Registriert: 17.03.2009, 13:59
Wohnort: Dresden

Re: RVO + Move Constructors

Beitrag 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.
Antworten