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 "unoptimizi ng" 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.
----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==---- http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
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.
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.
>
(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:
news:news.annou nce.newusers
>(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.
In article <44EFC916.45CBC 585@yahoo.com>
CBFalconer <cbfalconer@mai neline.netwrote :
>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.1415926535897 932384626433832 79502884 /* close enough */
int main(void) {
double (*fpd)(double);
void (*fpv)(void);
Even the AS/400 has to manage this, somehow. :-)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
In article <1156605571.218 781.286060@m73g 2000cwd.googleg roups.com>,
ragi <ragipaul@gmail .comwrote:
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.
--
Okay, buzzwords only. Two syllables, tops. -- Laurie Anderson
Comment