Skip to main content
gamedev.net
🔒 Locked

virtual function overhead

Started by AdamWebb Apr 7, 2005 at 6:46 AM 9 replies 4.3k views
Original Post
AdamWebb
AdamWebb
I was wondering if someone could give me an idea as to the overhead involved in using virtual functions. From what I understand the majority of the overhead comes from retrieving the pointer of the object from the vtable. How many extra bytes does the whole process take up and how great is this performance hit?
snk_kid
snk_kid
This should answer your question in detail.
AdamWebb
AdamWebb
Thanks for the link, that was a great help! Seems like they will not be a problem, so long as I don't over use in stupid places.
d000hg
d000hg
Yep. Something like this:
void SetIntValue(int *p){*p=3;}
Would be significantly slower as a virtual method. But unless a very small method is being called millions of times, it won't matter. Avoiding the issue by putting in extra methods is bad software engineering and will bloat your code.
AdamWebb
AdamWebb
So basically keep virtual function calls in the game loop to a minimum? I take it the lesson here is to design first?
silvermace
silvermace
Quote:
Original post by AdamWebb
So basically keep virtual function calls in the game loop to a minimum? I take it the lesson here is to design first?
not necissarily, just dont get crazy with your virtualisation. my engine is written in C++ and i use alot of inheritence (my engine's rendering engine is completely abstract), i have no noticable slow downs of any kind.

FYI, my engines current design is here [it is still nowhere near complete, and alot of design is yet-to-come]
AdamWebb
AdamWebb
Wow thanks silvermace, I had a quick look through your documentation and it's certainly helped with how I should design my OpenGL engine. Are you actually creating your own functions to call OpenGL functions i.e.

setViewport() might call glViewport()

Thanks Again.
silvermace
silvermace
yea, the idea is (the engine is being designed for two clients) and needs a D3D backend as well as an OpenGL backend.

i can do this
OpenGLDevice : public IRendererD3DDevice : public IRendererIRenderer *g_render;onStartup() {   if( GetConsole()["r_RenderDevice"] == "OpenGL" )       g_render = new OpenGLDevice();   else {       g_render = new D3DDevice();   }  } 
so the engine can seemlessly use both API's.

its important to understand that inheritence is a tool, and each tool should be used for its purposes specifically, and though my engine uses Inheritence, it doesnt mean yours should too.
AdamWebb
AdamWebb
I was only planning on using the OpenGL API (as that is the one I have more experience with) for rendering, so I don't suppose there would be a need to use inheritance for rendering purposes but I'm sure it'll come in handy elsewhere.

d000hg
d000hg
The only thing that might make virtual methods a bad choice for a graphics/game perspective(other than accessors and mutators for simple types) is if you were directly editing a screen-buffer / texture, and had some kind of SetPixel() method. Back doing 2D, you often would call this each frame, for every pixel. Aiming for 60fps in 800x600 mode means 28.8 million calls to SetPixel() per second. That's the level of use where virtual methods may cause a noticeable penalty. So unless you plan to do something similar I'd just use them wherever they fit your design.
MaulingMonkey
MaulingMonkey
Pretty much it boils down to:

BAD IDEA:

struct vertex{    double x,y,z;    virtual void render( void ) const = 0;};struct vertex_opengl{    virtual void render( void ) const    {        glVertex3d( x , y , z );    }};std::vector< vertex * > shitload_of_any_kind_of_vertex;void main_loop_render_opengl( void ){    glBegin( GL_TRAINGLES );    for_each( shitload_of_any_kind_of_vertex.begin() , shitload_of_any_kind_of_vertex.end() , mem_fun( &vertex::render ) );    glEnd();}


SEMI OK IDEA:

struct vertex{    double x,y,z;    virtual void render( void ) const = 0;};struct vertex_opengl{    virtual void render( void ) const    {        glVertex3d( x , y , z );    }};std::vector< vertex_opengl > shitload_of_opengl_vertexes;void main_loop_render_opengl( void ){    glBegin( GL_TRAINGLES );    for_each( shitload_of_opengl_vertexes.begin() , shitload_of_opengl_vertexes.end() , mem_fun_ref( &vertex_opengl::render ) );    glEnd();}


(This is semi-ok because in this case the compiler can deduce ahead of time what function will allways be called, meaning it can do things like inlining. It's bad because any mis-step into using a pointer to the base class will result in huge overhead - that is, the system is easy to mis-use. Further, the render() function really has no business being a member function of vertex - you can't render a single vertex, it makes no conceptual sense, a vertex is infinitely small - it belongs at the object level, those can be rendered).

Using virtual functions at, say the object rendering level is probably a good idea/acceptable. Why? Your objects will be varied anyways, so it's either the virtual function lookup or a lookup on some other table, the costs will be more or less the same, and unavoidable (unless you keep seperate lists of each type of object, but that plays havock with mantainability and memory space if you try and use oct-trees or the like, which would improve your preformance much more than eliminating a few virtual calls ever would).

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.