2015-05-13 5 views
6

Angenommen habe ich ein std::tuple:Optimiert GCC std :: tie nur zur besseren Lesbarkeit?

std::tuple<int,int,int,int> t = {1,2,3,4}; 

und ich möchte std::tie verwenden nur zur besseren Lesbarkeit Zweck wie folgt aus:

int a, b, c, d; // in real context these names would be meaningful 
std::tie(a, b, c, d) = t; 

vs. nur t.get<int>(0) mit etc.

Würde ein GCC den Speicherverbrauch dieses Tupels optimieren oder würde er zusätzlichen Speicherplatz für a, b, c, d Variablen zuweisen?

+4

warum nicht versuchen? (übrigens, würde es wahrscheinlich.) –

+0

Related [Do temporäre Variablen verlangsamen mein Programm?] (http://stackoverflow.com/q/26949569/1708801) –

+1

Check out [godbolt] (https: //gcc.godbolt. org /). Kurze Antwort: für ein einfaches Beispiel, ja. Summieren die Elemente in einem Tupel über 'tie()' oder 'get ()' erzeugt identische Assembly. – Barry

Antwort

7

In diesem Fall sehe ich keinen Grund, warum nicht, unter dem as-if rule muss der Compiler nur das beobachtbare Verhalten des Programms emulieren. Ein kurzer Versuch using godbolt:

#include <tuple> 
#include <cstdio> 

void func(int x1, int x2,int x3, int x4) 
{ 
    std::tuple<int,int,int,int> t{x1,x2,x3,x4}; 

    int a, b, c, d; // in real context these names would be meaningful 
    std::tie(a, b, c, d) = t; 

    printf("%d %d %d %d\n", a, b, c, d) ; 
} 

zeigt, dass gcc es in der Tat weg nicht optimieren:

func(int, int, int, int): 
    movl %ecx, %r8d 
    xorl %eax, %eax 
    movl %edx, %ecx 
    movl %esi, %edx 
    movl %edi, %esi 
    movl $.LC0, %edi 
    jmp printf 

Auf der anderen Seite, wenn Sie eine Adresse von t verwendet und ausgedruckt haben wir jetzt beobachtbare Verhalten der stützt sich auf t bestehenden (see it live):

printf("%p\n", static_cast<void*>(&t)); 

und wir können das gcc nicht mehr finden Sie in der t optimiert weg: auf das, was der Compiler generiert

movl %esi, 12(%rsp) 
leaq 16(%rsp), %rsi 
movd 12(%rsp), %xmm1 
movl %edi, 12(%rsp) 
movl $.LC0, %edi 
movd 12(%rsp), %xmm2 
movl %ecx, 12(%rsp) 
movd 12(%rsp), %xmm0 
movl %edx, 12(%rsp) 
movd 12(%rsp), %xmm3 
punpckldq %xmm2, %xmm1 
punpckldq %xmm3, %xmm0 
punpcklqdq %xmm1, %xmm0 

Am Ende des Tages schauen Sie brauchen, und das Profil der Code, es in komplizierteren Fällen können Sie sich überraschen. Nur weil der Compiler bestimmte Optimierungen durchführen darf, heißt das nicht, dass er es tun wird. Ich habe kompliziertere Fälle betrachtet, in denen der Compiler nicht das tut, was ich mit std::tuple erwarten würde. godbolt ist ein sehr hilfreiches Werkzeug hier, ich kann nicht zählen, wie viele Optimierungsannahmen ich hatte, die durch das Einfügen einfacher Beispiele in godbolt aufgehoben wurden.

Hinweis, ich verwende normalerweise printf in diesen Beispielen, weil Iostreams eine Menge Code generiert, der dem Beispiel in den Weg kommt.

+1

Wusste nicht, dass Sie godbolt Beispiele teilen können. Hier ist [meine] (https://goo.gl/ilaeZg). – Barry

+1

@Barry glücklich, dass Sie etwas Neues gelernt haben, ich fühle mich wie es ist ein wesentliches Merkmal, nicht in der Lage, Beispiele wie diese zu teilen wäre es viel weniger nützlich.Das ist das Tolle an SO, immer etwas Neues zu lernen. –

+0

Ich glaube, die wichtigste Information in Ihrer Antwort ist der letzte Absatz. – bolov