D
David Mathog
Assume there are N (around 10) functions like:
func1(void *, void*, int )
...
funcN(void*,void*,int)
A subset of these are to be called in the inner loop of a program,
conditionally, but always in numerical order. That is, it might be
1,3,5, or 6, or 9,10, but never 2,1 or 2,3,2. I can think of three
ways to code this (here "args" is filled in with the appropriate
values using simple code that isn't
relevant to the point under discussion here):
1),
if(test1)func1(args);
if(test2)func2(args);
...
if(testN)funcN(args);
2)
store function pointers in a list and do:
for(i=0;i<listlen;i++){
list(args); /* list holds function pointer to funcI */
}
3.
use an enum selector with entries {USEFUNC1,USEFUNC2,... USEFUNCN}
and store those selectors in a list:
for(i=0;i<listlen;i++){
switch (list){
case USEFUNC1: func1(args); break;
case USEFUNC2: func2(args); break;
...
case USEFUNCN: funcN(args); break;
}
}
The functions all perform relatively small operations and could be
inlined. Except, I don't think they can be for (2), because of the
function pointers. Since this is in the inner loop, the resulting
function call overhead is likely to be significant compared to the
inlined access. If case (3) always reduced to the equivalent of a
Fortran computed goto it would be faster than (1), since it could skip
the unnecessary if tests. However, I don't think the standard
guarantees that, and it might well reduce to the same code. In any
case, it looks like (3) is likely to be the fastest, and in any case,
should not be slower than (1). (2) would be fastest (never any extra
logic tests) if the function pointers could be inlined, but is that
possible in this case?
Are there any other options for this situation?
Thanks,
David Mathog
func1(void *, void*, int )
...
funcN(void*,void*,int)
A subset of these are to be called in the inner loop of a program,
conditionally, but always in numerical order. That is, it might be
1,3,5, or 6, or 9,10, but never 2,1 or 2,3,2. I can think of three
ways to code this (here "args" is filled in with the appropriate
values using simple code that isn't
relevant to the point under discussion here):
1),
if(test1)func1(args);
if(test2)func2(args);
...
if(testN)funcN(args);
2)
store function pointers in a list and do:
for(i=0;i<listlen;i++){
list(args); /* list holds function pointer to funcI */
}
3.
use an enum selector with entries {USEFUNC1,USEFUNC2,... USEFUNCN}
and store those selectors in a list:
for(i=0;i<listlen;i++){
switch (list){
case USEFUNC1: func1(args); break;
case USEFUNC2: func2(args); break;
...
case USEFUNCN: funcN(args); break;
}
}
The functions all perform relatively small operations and could be
inlined. Except, I don't think they can be for (2), because of the
function pointers. Since this is in the inner loop, the resulting
function call overhead is likely to be significant compared to the
inlined access. If case (3) always reduced to the equivalent of a
Fortran computed goto it would be faster than (1), since it could skip
the unnecessary if tests. However, I don't think the standard
guarantees that, and it might well reduce to the same code. In any
case, it looks like (3) is likely to be the fastest, and in any case,
should not be slower than (1). (2) would be fastest (never any extra
logic tests) if the function pointers could be inlined, but is that
possible in this case?
Are there any other options for this situation?
Thanks,
David Mathog