🔒 Locked
virtual function overhead
Advertisement
Original Post
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?
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.
Quote: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.
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?
FYI, my engines current design is here [it is still nowhere near complete, and alot of design is yet-to-come]
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
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.
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.
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.
Pretty much it boils down to:
BAD IDEA:
SEMI OK IDEA:
(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).
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.
Advertisement