I have a program which currently calls functions that are located in an array of function pointers. I have to use this method because there are hundreds of functions and which ones to be called can only be determined at runtime (i.e. by the index it is in the array).

This is great but is causing a little problem:

Functions are called rapidly so speed is key. The issue that I have is that the functions being called contain code which are generally only 3-4 lines, so I'm thinking they can truely be macros.

I would like to use macros instead of functions because functions can be too expensive over time (putting variables on the stack, operating on the return address) etc.... Its just extra code I want to try to avoid, and I don't want the overhead of "calling a function"

My question is: Is there a way to provide an array of macro functions? I want to try to eliminate calling functions, because im finding that it could be too expensive. Maybe there is a better way to do it?

01-28-2009

root4

Quote:

My question is: Is there a way to provide an array of macro functions?

No, it makes no sense, macros are just patterns expanded at compilation time.
I suggest to define all your functions as inline (or use macros, it works in this case) and find an alternative to the array, for instance store indirect indexes instead of addresses and use a switch statement...

01-28-2009

matsp

Quote:

Originally Posted by root4

No, it makes no sense, macros are just patterns expanded at compilation time.
I suggest to define all your functions as inline and find an alternative to the array, for instance store indirect indexes instead of addresses and use a switch statement...

It is unlikely that a switch statement is noticeably faster.

Calling functions through a function pointer is amongst the faster ways to achieve fast dispatch to other functions. In an x86 processor, the lookup of the table and indirect call probably add about 3 cycles [unless tables or code is not in cache, but then the overhead of lookup and call is probably not the REAL performance proble, but rather cache-hit ratio].

Have you actually run a profiler (e.g. Oprofile, vtune or CodeAnalyst) on the code to see where you are spending time in a typical use-case?

--
Mats

01-28-2009

root4

Quote:

It is unlikely that a switch statement is noticeably faster.

I did not say it would be faster, I only proposed an alternative to the (indirect) function call, as requested by the OP...

01-28-2009

MK27

Quote:

Originally Posted by someprogr

I would like to use macros instead of functions because functions can be too expensive over time (putting variables on the stack, operating on the return address) etc.... Its just extra code I want to try to avoid, and I don't want the overhead of "calling a function"

I also seem to have noticed at some point that because macros do not store a variable, if you call it with an argument that is the output of another macro or function, that macro or function will then get called each and every time it is referenced in the macro. Which means you might end up putting variables on a stack even more without knowing it. For example:

Code:

#define max(a,b) (a)>(b)? a : b
x=max(5,somefunc());

Now, when max is evaluated, somefunc will be called twice to substitute b, once for the first b and again for the second b in the macro. And it will be called each and every time the "variable" is mentioned in the macro. If somefunc is another macro, the macro is used AGAIN. If you don't believe this, put a static int in somefunc which increments for each call. That one call to max will increment it twice.

I am just warning you, because if you want to save some time typing, you might, but you may not save any processor activity, etc. If your macros are anything but simple arithmetic, you could end up with some incredibly nested instruction sets.

01-28-2009

MK27

Here's an example of what I mean:

Code:

#define max(a,b) (a)>(b)? a:b

int test() {
puts("HELLO");
return 4;
}

int main() {
int x;
x=max(3,test());
}

Output:HELLO
HELLO

If max were a function, then test() would only be called once. So you may pay more than you thought you saved.

01-28-2009

brewbuck

I don't think you're going to make this noticeably faster no matter what you do. I'd concentrate on reducing the time spent passing arguments. If all the functions take similar arguments, you could package these into a struct and pass a single pointer to that struct, instead of passing multiple arguments, and see how that changes things. This could actually have an impact if some of the arguments don't change very often.

A switch statement which dispatches to inline functions might be marginally faster, but only if the compiler optimizes the crap out of everything. It might not even inline everything.