Question about function decay

S

Snis Pilbor

Hello,

Is there any actual difference between calling a function directly
by name, vs. calling it by a function pointer which points to it? I
read at the FAQ that the function name can be thought of as decaying to
a pointer, but is this *literally* true?

The reason I'm wondering is because I'd like to do the following sort
of optimization. Suppose deep in a time-sensitive function I have
something like

if ( global_boolean )
this_function();
else
that_function();

Where global_boolean is, as the name suggests, a global boolean which
changes from time to time due to things outside the function in
question, and infrequently. My idea is I could just make a global
function pointer, global_fncptr, and change the above 4 lines to

(*global_funcptr)();

Then wherever global_boolean were changed, I would also change
global_funcptr accordingly. Assuming global_boolean gets changed much
less frequently than the time-sensitive function gets called, it
intuitively seems like this will save time needlessly checking the
value of global_boolean. But that's assuming that calling my functions
with the global pointer is identical to calling them by name.

Thanks for any insight you can give on this =)

Snis Pilbor
 
J

jacob navia

Snis said:
Hello,

Is there any actual difference between calling a function directly
by name, vs. calling it by a function pointer which points to it? I
read at the FAQ that the function name can be thought of as decaying to
a pointer, but is this *literally* true?

The reason I'm wondering is because I'd like to do the following sort
of optimization. Suppose deep in a time-sensitive function I have
something like

if ( global_boolean )
this_function();
else
that_function();

Where global_boolean is, as the name suggests, a global boolean which
changes from time to time due to things outside the function in
question, and infrequently. My idea is I could just make a global
function pointer, global_fncptr, and change the above 4 lines to

(*global_funcptr)();

Then wherever global_boolean were changed, I would also change
global_funcptr accordingly. Assuming global_boolean gets changed much
less frequently than the time-sensitive function gets called, it
intuitively seems like this will save time needlessly checking the
value of global_boolean. But that's assuming that calling my functions
with the global pointer is identical to calling them by name.

Thanks for any insight you can give on this =)

Snis Pilbor

All this has no importance in modern CPUs (Pentiums/AMDs PowerPC or
SPARCs)

The test for global_boolean is a memory read, and since it is very often
used it is in the cache already. This is nothing, maybe 1 or 2 cycles.

A slight improvement is attained with the function pointer method since
it eliminates a jump, there is less pipeline turbulence, but since it
is an indirect call (through a function pointer) it will never be
predicted correctly...

Did you MEASURE anything to see if this is a bottleneck?
Why do you think this is important?
 
K

Keith Thompson

Snis Pilbor said:
Is there any actual difference between calling a function directly
by name, vs. calling it by a function pointer which points to it? I
read at the FAQ that the function name can be thought of as decaying to
a pointer, but is this *literally* true?

It's literally true in the abstract machine, but the compiler is
allowed to generate whatever code it likes as long as it behaves as
specified (the "as-if" rule).

Whether it's literally true in the actual generated machine code is
likely to depend on the compiler and on the CPU architecture.

If the CPU has an instruction that makes direct function calls faster
than indirect ones, most likely the compiler will use it.
The reason I'm wondering is because I'd like to do the following sort
of optimization. Suppose deep in a time-sensitive function I have
something like

if ( global_boolean )
this_function();
else
that_function();

Where global_boolean is, as the name suggests, a global boolean which
changes from time to time due to things outside the function in
question, and infrequently. My idea is I could just make a global
function pointer, global_fncptr, and change the above 4 lines to

(*global_funcptr)();

Then wherever global_boolean were changed, I would also change
global_funcptr accordingly. Assuming global_boolean gets changed much
less frequently than the time-sensitive function gets called, it
intuitively seems like this will save time needlessly checking the
value of global_boolean. But that's assuming that calling my functions
with the global pointer is identical to calling them by name.

The only way to tell is to measure it. If there's no significant
difference, just write the code as clearly as possible.
 
F

Frederick Gotham

Snis Pilbor posted:
(*global_funcptr)();


Sounds like a good idea. You might consider omitting the unnecessary
dereference and parentheses:

global_funcptr();
 
K

Keith Thompson

Frederick Gotham said:
Snis Pilbor posted:



Sounds like a good idea. You might consider omitting the unnecessary
dereference and parentheses:

global_funcptr();

Yes, they're unnecessary, but IMHO it's a good idea to include them
anyway, just as a visual reminder that global_funcptr is a pointer
object, not a function.

Function calls through a pointer object are sufficiently rare that
it's worth it to treat them specially.
 
F

Flash Gordon

Keith Thompson wrote:

The only way to tell is to measure it. If there's no significant
difference, just write the code as clearly as possible.

I would go further. Write it as clearly as possible first, then measure,
and if there is a performance problem and you have already optimised the
algorithm and design, then look at whether this or that
micro-optimisation might help, measuring as you go.

This is for the OPs benefit, not Keith's. I'm sure Keith would not
bother looking at micro-optimisations unless required.
 

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
473,997
Messages
2,570,240
Members
46,830
Latest member
HeleneMull

Latest Threads

Top