2012-09-13 2 views
5

Con un codice come di seguito, un compilatore può dire che a è in realtà un'istanza di B e ottimizzare la ricerca della tabella virtuale?Ottimizzazione delle ricerche di tabelle virtuali

#include <iostream> 

class A 
{ 
    public: 
    virtual void f() 
    { 
     std::cout << "A::f()" << std::endl; 
    } 
}; 

class B : public A 
{ 
    public: 
    void f() 
    { 
     std::cout << "B::f()" << std::endl; 
    } 
}; 

int main() 
{ 
    B b; 
    A* a = &b; 
    a->f(); 

    return 0; 
} 

domanda supplementare dopo le risposte di Jonthan Seng e Reima: Nel caso si usa gcc, sarebbe necessario utilizzare eventuali bandiere per costringerlo a ottimizzare la ricerca vtable?

+0

L'unico modo per sapere con certezza è quello di guardare in assemblea. Ma sì, la virtualizzazione è un'ottimizzazione del compilatore standard. – Mysticial

+0

È stato appena aggiunto lo smontaggio per GCC. Ho usato il flag '-O1' per le ottimizzazioni di base. – reima

risposta

5

Clang può facilmente rendere questa ottimizzazione e persino in linea la chiamata di funzione. Questo può essere visto dal complesso generato:

Dump of assembler code for function main(): 
    0x0000000000400500 <+0>: push %rbp 
    0x0000000000400501 <+1>: mov %rsp,%rbp 
    0x0000000000400504 <+4>: mov $0x40060c,%edi 
    0x0000000000400509 <+9>: xor %al,%al 
    0x000000000040050b <+11>: callq 0x4003f0 <[email protected]> 
    0x0000000000400510 <+16>: xor %eax,%eax 
    0x0000000000400512 <+18>: pop %rbp 
    0x0000000000400513 <+19>: retq 

mi sono permesso di sostituire std::cout << … da chiamate equivalenti a printf, poiché ciò riduce notevolmente l'ingombro in smontaggio.

GCC 4.6 può anche dedurre che non è necessaria alcuna ricerca vtable, ma non lo fa in linea:

Dump of assembler code for function main(): 
    0x0000000000400560 <+0>: sub $0x18,%rsp 
    0x0000000000400564 <+4>: mov %rsp,%rdi 
    0x0000000000400567 <+7>: movq $0x4007c0,(%rsp) 
    0x000000000040056f <+15>: callq 0x400680 <B::f()> 
    0x0000000000400574 <+20>: xor %eax,%eax 
    0x0000000000400576 <+22>: add $0x18,%rsp 
    0x000000000040057a <+26>: retq 
+0

+1 Visual Studio 2010 la ridimensiona. Ma non lo in linea. – Mysticial

+0

Al momento ho solo gcc 4.4. Non sembra per ottimizzare la ricerca anche con -O3: subq \t $ 24,% RSP .cfi_def_cfa_offset 32 ​​ movq \t $ _ZTV1B + 16, (% RSP) movq \t% RSP,% RDI chiamata \t * _ZTV1B +16 (% rip) XORL \t% eax,% eax addq \t $ 24,% RSP .cfi_def_cfa_offset 8 ret – Ruup

+1

avvitare! Non riesco a formattarlo! – Ruup

-2

Forse può - che dipenderebbe dalle capacità del compilatore e dai requisiti di ottimizzazione.

Ma questa è una chiamata. Perché ti preoccupi di ottimizzare questa sola chiamata? E se ti interessa, perché non prendi il tipo giusto per questa sola chiamata?

La prima risposta a tutte le domande sull'ottimizzazione è "Perché è necessario ottimizzarlo?" Avere un rapporto sullo strumento delle prestazioni che dice che il 50% del tempo di applicazione è un posto, e la domanda viene data risposta. "Oh, ma è inefficiente", la risposta più comune, porta a codice non gestibile che raramente ottimizza il codice che è in realtà inefficiente.

+1

Non ho votato meno, ma se il PO non gliene importava, questa domanda non sarebbe stata posta. – Mysticial

+2

Spesso le persone si preoccupano dell'ottimizzazione quando non c'è motivo di farlo. Quindi, ne farò una domanda. –

+0

La risposta sarebbe stata nei commenti quindi .. –