I am creating a Rendering Engine. And theres 2 ways of me creating a task management system. Creating my own custom call backs that get called before and after render, Or implementing a task management system in which I would have to derive a class from a parent TaskClass and then throw it into queue.

Honestly I feel creating callbacks is better because it allows me to create task management subsystem that is independent from the actual rendering engine. This allows me to focus more on the rendering engine and worry about task management later.

But my question is... "is it costly to use callbacks ?" Is it a practice that is common in a processor intense environment such as a game engine.

+2  A: 

Callback is a function pointer. Calling a function through one is not very expensive, but certainly induces some overhead - the function will not be inlined at the very least.

Only you can justify if you can afford it - write a small test program and profile it. Depending on how often you will call the function the overhead will take lesser or greater share of processor time. Without profiling predictions and analysis are not worth much.

Yea, I was just trying to see if there was anyone out there with the experience of profiling callbacks within a rendering engine or game engine. I would presume that the callback would be called 1/30th or 1/60th of a second, if not a full cpu cycle. who knows.
Emm... What??? What processor are you designing for that needs whole 1/30th of a second to invoke a function through a function pointer?
I am messing with the directX api. If I am animating. I want my objects to move 30 frames per second, in other words, 1/30th a second. Therefore my callback that handles updates of obects will be called 1/30th a second. Which is pretty slow compared to moving at regular cpu speed. So I think it wont be that bad
You still need to do some action, don't you? That action will take time anyway. It's likely that calling that action through a callback will not be much slower compared to calling that action some other way. But you need to profile to evaluated whether the overhead of using a callback is tolerable.

Callbacks are quite cheap when they don't involve closures.

Callbacks involving closures are a little more expensive.


Callbacks by itself are not costly, but care should be taken not to do too much computation. Usually callback posts a message, gives a semaphore/signal etc and stops.

+5  A: 

First of all, costly is relative, if you'll call these callbacks at 10000Hz, yes, some callback implementations can be too costly. However, a simple function-pointer based callback will actually have almost no overhead.

But most important: this is an example of premature optimization, certainly as it looks you're going to call these callbacks only 60 times per seconds on an average 30 fps game. In most games there will be much more crucial performance issues. Start with one method, profile it when you have performance issues and if it really does not suffice then optimize it. You'll probably loose much more cpu cycles on math or AI functions anyway.

Finally: in many games, the bottleneck is the GPU, not the CPU ;).

Well, the callbacks will only be used for CPU task such as AI and Game mechanics in which I am not too worried about.

"is it costly to use callbacks ?"

It can be as little as the cost of calling a virtual function.

Depending on your environment, it may be more expensive: if it's a callback from kernel-mode to user-mode for example, then you may need to do clever and/or expensive things to implement an apparent ring transation.

One of the problems with callbacks is locks: if your code is multithreaded and/or thread-safe, then if you own any locks at the moment when you invoke the callback then (depending on what the user code in the callback does, e.g. try to acquire more locks) you may get a deadlock.

+4  A: 

Concerning the cost of callbacks when performed using function pointers in C, for this little snippet

void func1() { }

void func2() 
  void (*funcptr)() = func1;


gcc -S generates the following assembler instructions for the body of func2:

movq $func1, -8(%rbp)
movl $0, %eax
call func1
movq -8(%rbp), %rdx
movl $0, %eax
call *%rdx

So, as expected, you only pay for the pointer indirection, i.e. you shouldn't worry about performance.

Greg S

If you're using Visual Studio and looking at a task management system, take a look at the Concurrency Runtime, Parallel Pattern Library and Agents Library in VS 2010 here.

You don't need to build your own task system, you can build on top of one.