【问题标题】:Does the compiler optimize non-polymorphic calls to virtual methods?编译器是否优化了对虚拟方法的非多态调用?
【发布时间】:2013-06-09 14:35:12
【问题描述】:

编译器是否优化/内联对虚拟方法的非多态调用?我的意思是当调用是在非多态上下文中时,所以在编译时一切都是已知的?

【问题讨论】:

  • 是的,如果编译器可以肯定会。
  • 这被称为去虚拟化,是的,它有时会发生(尽管它有限制)。

标签: c++ optimization polymorphism virtual inline


【解决方案1】:

编译器是否优化/内联对虚拟方法的非多态调用?

是的,每个体面的编译器都会这样做。

GCC 和 MSVC 甚至在 -O0//Od 模式下也能做到这一点。

LIVE DEMO

#ifdef _MSC_VER
    #define NOINLINE __declspec(noinline)
#else
    #define NOINLINE __attribute__ ((noinline))
#endif

template<int>
NOINLINE void ASM_MARKER()
{
    static volatile int anti_opti = 11;
    (void)anti_opti;
}

void base();
void derived();

struct Base
{
    virtual void foo()
    {
        base();
    }
};
struct Derived: Base
{
    void foo() override
    {
        derived();
    }
};

int main()
{
    ASM_MARKER<1000>();
    Base b;
    b.foo();
    ASM_MARKER<2000>();
    Derived d;
    d.foo();
    ASM_MARKER<3000>();
    Base &r = d;
    r.foo();
    ASM_MARKER<4000>();
}

G++ 4.8 -O0:

    call    void ASM_MARKER<1000>()
    movq    vtable for Base+16, -32(%rbp)
    leaq    -32(%rbp), %rax
    movq    %rax, %rdi
    call    Base::foo()
    call    void ASM_MARKER<2000>()
    movq    vtable for Derived+16, -16(%rbp)
    leaq    -16(%rbp), %rax
    movq    %rax, %rdi
    call    Derived::foo()
    call    void ASM_MARKER<3000>()
    leaq    -16(%rbp), %rax
    movq    %rax, -8(%rbp)
    movq    -8(%rbp), %rax
    movq    (%rax), %rax
    movq    (%rax), %rax
    movq    -8(%rbp), %rdx
    movq    %rdx, %rdi
    call    *%rax      // <--------------- NOT OPTIMIZED
    call    void ASM_MARKER<4000>()

MSVC2010SP1 /Od:

; Line 34
    call    ??$ASM_MARKER@$0DOI@@@YAXXZ     ; ASM_MARKER<1000>
; Line 35
    lea rcx, QWORD PTR b$[rsp]
    call    ??0Base@@QEAA@XZ
; Line 36
    lea rcx, QWORD PTR b$[rsp]
    call    ?foo@Base@@UEAAXXZ          ; Base::foo
; Line 37
    call    ??$ASM_MARKER@$0HNA@@@YAXXZ     ; ASM_MARKER<2000>
; Line 38
    lea rcx, QWORD PTR d$[rsp]
    call    ??0Derived@@QEAA@XZ
; Line 39
    lea rcx, QWORD PTR d$[rsp]
    call    ?foo@Derived@@UEAAXXZ           ; Derived::foo
; Line 40
    call    ??$ASM_MARKER@$0LLI@@@YAXXZ     ; ASM_MARKER<3000>
; Line 41
    lea rax, QWORD PTR d$[rsp]
    mov QWORD PTR r$[rsp], rax
; Line 42
    mov rax, QWORD PTR r$[rsp]
    mov rax, QWORD PTR [rax]
    mov rcx, QWORD PTR r$[rsp]
    call    QWORD PTR [rax]       // <--------------- NOT OPTIMIZED
; Line 43
    call    ??$ASM_MARKER@$0PKA@@@YAXXZ     ; ASM_MARKER<4000>

【讨论】:

    猜你喜欢
    • 2019-04-29
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    • 1970-01-01
    • 2020-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多