Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

virtual function overhead when deterministic (c++)

I know that virtual functions are essentially function pointers contained on a vtable, which makes polymorphic calls slower because of indirection etc. But I'm wondering about compiler optimisation when call is deterministic. By deterministic, I mean the following cases:

  1. The object is a value and not a reference, so there is no polymorphism possible:
struct Foo
{
    virtual void DoSomething(){....}
};

int main()
{
    Foo myfoo;
    myfoo.DoSemthing();
    return 0;
}
  1. The reference is to a childless class:
struct Foo
{
    virtual void DoSomething();
};
struct Bar : public Foo
{
   virtual void DoSomething();
};

int main()
{
    Foo* a = new Foo();
    a->DoSomething(); //Overhead ? a doesn't seem to be able to change nature.

    Foo* b = new Bar();
    b->DoSomething(); //Overhead ? It's a polymorphic call, but b's nature is deterministic.

    Bar* c = new Bar();
    c->DoSomething(); //Overhead ? It is NOT possible to have an other version of the method than Bar::DoSomething
    return 0;
}
like image 602
bisthebis Avatar asked Feb 10 '16 17:02

bisthebis


People also ask

Where does the overhead in a C++ virtual function come from?

Most overhead of virtual functions comes from small functions, they cost more to call than to execute. Also, the compiler is really good at optimizing small virtual functions. Keep objects in the vector sorted by type.

Are virtual functions bad for performance?

Virtual functions are slow when you have a cache miss looking them up. As we'll see through benchmarks, they can be very slow. They can also be very fast when used carefully — to the point where it's impossible to measure the overhead.

Is virtual function Function Overriding?

The virtual keyword can be used when declaring overriding functions in a derived class, but it is unnecessary; overrides of virtual functions are always virtual. Virtual functions in a base class must be defined unless they are declared using the pure-specifier.

Does C support virtual function?

You get the same runtime performance as a C++ member function call, but without any compile-time checking to enforce access control. In C, virtual function calls look unlike any other kind of function call.


1 Answers

In the first case, this will not be a virtual call. The compiler will issue a call straight to Foo::DoSomething().

In the second case, it's more complicated. For one, it's at-best a link time optimization, since for a specific translation unit, the compiler doesn't know who else might inherit from that class. The other problem you get is with shared libraries which might also inherit without your executable knowing anything about it.

In general, though, this a compiler optimization known as virtual function call elimination, or devirtualization, and is somewhat of an active field of research. Some compilers do it to some extent, others don't do it at all.

See, in GCC (g++), -fdevirtualize and -fdevirtualize-speculatively. The names kind of hint at the guaranteed level of quality.

like image 54
Yam Marcovic Avatar answered Oct 18 '22 23:10

Yam Marcovic