virtual member function early binding

virtual member function early binding

 I am using tbb with the intel c++ compiler (win7, msvc2010).

I am writting certain classes to be used by tbb algorithms. Typically these (algorithms) work like this:

The user provides with a class that is the body of the algorithm (say, ClassBody) to be run, and "attaches" it to the tbb algorithm.

The latter breaks up some user-provided-range over which the algorithm will run on different threads and some thread splitting policy (roughly at least,,), which however is independent of the ClassBody ( other than the user's choice at design time).

It seems to me that the compiler should be able to identify the implementation of the virtual function (lives inside the ClassBody) and early-bind (is this the right expression?) to it. In the case of a simple loop, this should be the expected behavior ( I think/hope, am I wrong ?).

Can you please confirm that there would be no performance penalty by such a design ? O/wise one would need to make the ClassBody a template which, apart from the coding complications, would result in a larger code footprint.

Thank you for your help,

Petros

10 posts / novo 0
Último post
Para obter mais informações sobre otimizações de compiladores, consulte Aviso sobre otimizações.

In case of just one C++ class with a virtual function(s) the Run-Time Dynamic Linking ( RTDL / also know as Late-Binding ) can not be used because a set of properly designed classes is needed. Do you need an example?

Hi Sergey,

yes, please, I would like an example.And also what does it mean "properly designed" ?

To be clear, if I have a function that calls 1000 times the same virtual function and the pointer of the class is known at the beginning and never changed, it would not be a penalty, is this correct ? Because in the end of the day, tbb runs a range of values with the same class pointer.

>>...what does it mean "properly designed"?

I'll provide more details.

>>...the pointer of the class is known at the beginning and never changed, it would not be a penalty, is this correct?

I don't know how you've created / implemented that class(es) and you need to use VTune to verify that there is No penalty at run-time.

This is a very basic example:

#include "stdio.h"

[ Class A - base ]

class A
{
public:
A(){};
virtual ~A(){};
virtual bool MyMethod() = 0;
};

[ Class B ]

class B : virtual public A
{
public:
B(){};
virtual ~B(){};
virtual bool MyMethod();
};

bool B::MyMethod()
{
printf( "B::MyMethod\n" );
return true;
}

[ Class C ]

class C : virtual public A
{
public:
C(){};
virtual ~C(){};
virtual bool MyMethod();
};

bool C::MyMethod()
{
printf( "C::MyMethod\n" );
return true;
}

[ Main program ]

int main( void )
{
printf( "Main start\n" );

A *b = ( B * )new B();
A *c = ( C * )new C();

b->MyMethod();
c->MyMethod();

printf( "Main end\n" );

return ( int )0;
}

[ Output ]

Main start
B::MyMethod
C::MyMethod
Main end

Take a look at a thread with a similar subject ( I mean Late-Binding / do not pay attention for its name ):

Forum Topic: Can't debug into method
Web-link: software.intel.com/en-us/forums/topic/364034

Well yes, this is understood.

My paraigm is the foolowing:

1st the simple example:
struct B{ virtual task(int i )=0 ; }

struct D1:public B{ virtual task(int i){ return i; }

struct D2:public B{ virtual task(int i){ return 2*i; }

( the public is unnecessary for struct).

Now I have the function :

void func( B* p )  { for ( int i = 0 ; i != 10000; ++i ) p->task(i) ;}

void f1() { D1 * p1 = new D1; func( pd1) ;

int main(){

B * p1 = new D1;          func( pd1) ;

B * p2 = new D2;          func( pd2) ;

return 1 ;

}

Do we agree agree that inside func the task function is matched to the implementation only once, i.e. before the loop ?

>>...func( pd1 ) ;
>>...func( pd2 ) ;

What are pd1 and pd2? Are these pointers to objects of types D1 and D2?

>>... that inside func the task function is matched to the implementation only once...

Yes and it happens at B *p1 = new D1; step.

Yes, they are - apologies for slopiness,

OK if this is the case, why wouldn't the compiler know" with what struct the origin of the thread-used copies of ClassBody virtual function to work with ?

Understandably there are copies of the pointer propagated along when task splitting happens but atleast within each function body to be used at the end the implementation should be deciphered, I am pretty sure on this.

OK I think I start seeing why..

Thank you for your help,

Petros

Hi Petros,

>>Take a look at a thread with a similar subject ( I mean Late-Binding / do not pay attention for its name ):
>>
>>Forum Topic: Can't debug into method
>>Web-link: software.intel.com/en-us/forums/topic/364034

In that thread we had a discussion why the original test-case doesn't look properly. It is related to my expression "...properly designed classes..." however it needs to be changed to "...properly used ( instansiated ) classes...".

Faça login para deixar um comentário.