Petr Skocik
Petr Skocik

Reputation: 60068

Virtual function overhead of negative 0.6ns per call?

I wrote the following benchmark to estimate the overhead of virtual functions:

struct A{
  int i = 0 ;
  virtual void inc() __attribute__((noinline)); 
};

#ifdef VIRT
  struct B : public A{
    void inc() override __attribute__((noinline));
  };

  void A::inc() { }
  void B::inc() { i++; }
#else
  void A::inc() { i++; }
#endif

int main(){
#ifdef VIRT
  B b;
  A* p = &b;
#else
  A a;
  A* p = &a;
#endif
  for( ;p->i < IT; p->inc()) {; }
  return 0;
}

I compile it with

G=$((1000**3))
g++ -O1 -DIT=$((1*G)) -DVIRT virt.cc  -o virt
g++ -O1 -DIT=$((1*G)) virt.cc  -o nonvirt

And the results I got were that nonvirt was about 0.6ns slower than virt per function call at -O1 and about 0.3ns slower than virt at -O2 per function call.

How is this possible? I thought virtual functions were supposed to be slower.

Upvotes: 1

Views: 60

Answers (2)

Tezirg
Tezirg

Reputation: 1639

EDIT: Has been corrected

Your main is wrong. the for loop is defined 2 times in one case and once in the other. This should not impact performance since the second time the loop exits immediately ?

Correct it like that :

int main(){
#ifdef VIRT
  B b;
  A* p = &b;
  /* removed this for loop */
#else
  A a;
  A* p = &a;
#endif
  for( ;p->i < IT; p->inc()) {; }
  return 0;
}

Upvotes: 1

John Zwinck
John Zwinck

Reputation: 249153

First, just because you invoke a method through a pointer doesn't mean the compiler can't figure out the target type and make the call non-virtual. Plus, your program does nothing else, so everything will be well-predicted and in cache. Finally, a difference of 0.3 ns is one cycle, which is hardly worth noting. If you really want to dig into it, you could inspect the assembly code for each case on whatever your platform is.

On my system (Clang, OS X, old Macbook Air), the virtual case is a little slower, but it's hardly measurable with -O1 (e.g. 3.7 vs 3.6 seconds for non-virtual). And with -O2 there's no difference I can distinguish.

Upvotes: 4

Related Questions