Which one is efficient !!

K

Kevin Handy

ragi said:
Hi All,

In terms of efficiency, whether normal function call or using a
function pointer.

In terms of sentence structure, whether to verb or none?

How are you defining efficiency?
Miles/gallon? functions/volume Ease of use? Conversion percentage?

Pick one definition, and then write test code to measure it.
Or stop trying to write code that sucks.

I've delt with too much code that has been hand "optimized",
and by "unoptimizing" it, I've made the programs run faster,
more reliabily, smaller, and easier to understand.

If you use what makes sense, instead of trying to save two
nanoseonds over five thousand runs, your code will be much
easier to maintain.

If it's important to you, measure it. If you don't think it's
worth measuring, it's obviously not important to you.

If you "need" maximum "efficiency", you probably should be
coding in machine language.
 
R

ragi

Hi All,

In terms of efficiency, whether normal function call or using a
function pointer.

thxs in advance,
ragi
 
F

Flash Gordon

ragi said:
Hi All,

In terms of efficiency, whether normal function call or using a
function pointer.

Either. This has been asked many times before on this group, so I
suggest searching the group for the reasons why it is either.
 
M

Malcolm

ragi said:
Hi All,

In terms of efficiency, whether normal function call or using a
function pointer.
It is hard to think of a situation where a normal call would be slower than
a fucntion pointer.
A function pointer may involve a small amount of overhead to load the
pointer itself and jump to it, but it is almost certainly trivial. A naive
compiler might find it harder to optimise function pointers by inlining.
 
A

Ancient_Hacker

ragi said:
Hi All,

In terms of efficiency, whether normal function call or using a
function pointer.

thxs in advance,
ragi

Sounds like a homework question, in which case you shoul dponder the
question yourself a bit.

The difference is unlikely to be of any significance. The pros and
cons are:

(1) A function pointer can be held in a register, so there's no need
to fetch the function address out of the code stream.

(2) but... if it's a normal function call, and it's already been
fetched, many modern CPU's can start fetching code from the function
address and even speculatively executing code there. If it's a
function pointer, this is much less likely to happen.

(3) and... a normal call the compiler might generate code inline,
which can be good.

(4) but... inline code usually can't be run at full speed the first
time, as most CPU's don't build micro-ops and do dependency analysis
until after the first pass. But if the code wasnt inlined, it's likely
to have been already analyzed by the CPU so it will run fast on every
usage after the first. and inline code is usually longer, which tends
to crowd or push other code out of the code cache.

(5) but... often inlined code will allow much more optimization, as
many optimizers have to flush all their accumulated info on a function
call.

So to be brief, it's very hard to tell which is better or faster.
 
C

CBFalconer

Ancient_Hacker said:
.... snip ...

(1) A function pointer can be held in a register, so there's no
need to fetch the function address out of the code stream.

Where did you get that idea? Chapter and verse, please.

I think you will find that a function pointer can be far too large
for a register, in fact registers do not even have to exist in a C
system. This is one of the reasons it is not legal to cast
function pointers.

--
Some informative links:
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html
 
C

Chris Torek

Where did you get that idea? Chapter and verse, please.

Well, he did not say "will", but "can". This is of course machine
dependent but he pointed that out elsewhere (if I remember right).
I think you will find that a function pointer can be far too large
for a register, in fact registers do not even have to exist in a C
system.

True -- but except for oddball cases like the AS/400 (a rare machine
where, apparently, it is *not* important to get the wrong answer
as fast as possible), most modern machines do tend to fit them in.
This is one of the reasons it is not legal to cast function pointers.

This is just wrong:

#include <stdio.h>
#include <math.h>

#define PI 3.141592653589793238462643383279502884 /* close enough */

int main(void) {
double (*fpd)(double);
void (*fpv)(void);

fpd = sin;
fpv = (void (*)(void))fpd;
printf("%f\n", ((double (*)(double))fpv)(PI / 4.0));
return 0;
}

Even the AS/400 has to manage this, somehow. :)
 
R

ragi

Hi Friends,

As a disadvantage, using a fn ptr requires one more memory access.

supposing i call f at location 0x1000
normal function call would translate to

call 0x1000 (no extra memory access req.)

if f were a function ptr.

ie;
in C code
f = 0x1000;
....
f();
the call (only the f();) would translate to:

call fn pointed to by f (Which means that the microproc, has to first
fetch the value pointed to by f, then jump there)

Normally, using a fn ptr than hardcoding would be a better design
especially if it were some callback.

ragi
 
W

Walter Roberson

ragi said:
As a disadvantage, using a fn ptr requires one more memory access.

Not necessarily!
supposing i call f at location 0x1000
normal function call would translate to
call 0x1000 (no extra memory access req.)

Not necessarily! There are a lot of platforms on which it would
translate to something more like

lea A0, 0x1000 ("load effective address into address register 0")
bsr A0 ("branch to subroutine whose address is in A0")

if f were a function ptr.
in C code
f = 0x1000;

lea A0, 0x1000 (load the given constant into an address register)

f();
the call (only the f();) would translate to:

bsr A0


In other words, exactly the same sequence.


Some of the processors do have the call (or bsr, or bal) instructions
that are able to work on relative addresses, and the optimizer might
be able to take advantage of that for "nearby" subroutines in the
same translation unit. However, it isn't uncommon for the relative
offset to be fairly limited (e.g., no more than 32 Kb away), so for
further subroutines, or for subroutines in other translation units,
and -especially- for library routines, it is common for a full
"load address" instructions to be used, so that the linker can more
easily relocate the code.


Note too that the address constant you have used for the example
is only 16 bits and so gives the impression of fitting in to a single
call. Tf, though, the address does not happen to be in the first 64 Kb
of address space (not being there is increasingly common these days),
it would come out more like call 0x000010000 with the call instruction
itself possibly needing 2 bytes and the address 4, for a total of 6
bytes. Now suppose you have a tight loop, such as

while (is_digit(*p++));

then according to the information you gave, this would always take
less instructions with the address hard-coded. But observe that

lea A0, 0x000010000
... various init loop stuff ...
HERE: bsr A0
... loop test stuff setting the condition code ...
... increment p
brnz HERE ... branch back of the test result was non-zero

here, the bsr A0 might only take 2 bytes per cycle. Therefore,
even for processors that have direct subroutine calls by
absolute address, they will not necessarily use that all the
time, as it is possible in a loop to amortize the cost of loading
the address over all of the loop iterations. Furthermore, when
the code is handled that way, the processor is more likely to be
able to cache the instructions that form the loop in a very fast
cache, possibly executing the entire loop at the microcode level,
since it would not have to assume that it was fetching new
instructions from main memory.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top