Function pointers: performance penalty?

J

jacob navia

Phil Carmody a écrit :
Direct function calls through fixed pointers can indeed often be faster
than calls via function pointers.

But where did he mention the former? Message-id and line number please.


Maybe you're too busy making ASSumptions.

Phil

This person then, calls a constant value "a fixed pointer". When I use
a call instruction, the offset to the start of the called function is
an immediate number embedded in the instruction stream. For this
person this is "a fixed pointer"...

When I write
int a = 543;

then, with the same logic, I am assigning a pointer to an integer,
since 543 is a "fixed pointer". Strange that the compiler doesn't
complain.

Then, (as always) this person starts with insults:

"You are making ASSumptions"

of course that is not an insult to anybody... just , well, just
the caps lock key stuck.

<quote Antoninus>
"Phil" is obviously clueless - a couple days ago he showed us all that
he doesn't know what a heap is, now we learn that he's completely
ignorant about function pointers too.

All Carmodey brings to this group is a sycophantic blind support for
Heathfield, and a lot of bile directed against anyone and everyone who
dares to point out how inadequate his purported knowledge of C is.
<end quote>
 
B

bartc

Phil Carmody said:
Direct function calls through fixed pointers can indeed often be faster
than calls via function pointers.

But where did he mention the former? Message-id and line number please.

So, function pointers are faster than... what then?
Maybe you're too busy making ASSumptions.

I've now looked at compiler output for the following program snippet, for
x86 compilers lccwin32, gcc 3.4.5 and DMC. None use indirect calls even at
maximum optimisation levels:

int fib(n) {
if (n<2)
return n;
else
return fib(n- 2)+fib(n- 1);
}

I've even temporarily modified the output of one my compiler projects for a
very similar language to C. Changing the two calls in this function to
memory-indirect calls, at first made it 10% faster! Very interesting.
Unfortunately when I repeated the test it was 10% slower! (But trying to get
meaningful and consistent timings with Intel processors is not easy.)

(Interestingly, my compiler was some 30% faster, on fib(40), than any of the
highly optimised compilers above, usually the performance is abysmal
compared with a proper compiler.)
 
P

Phil Carmody

By the way, I am sure that those interested could have a better-informed
discussion over in comp.arch.

Why - do they actually ask sensible questions over there?

Phil
 
P

Phil Carmody

Keith Thompson said:
Could you please expand on this statement? Was it intended as
a joke? If not, what exactly do you mean?

Was it meaningful?
Was it a direct analogue to the question asked?

If you haven't answered "no, yes" in that order, then let's try a
non-computing analogue:

Subject: Oranges: heavier?
Are oranges heavy? If so, how much heavier are they?

Phil
 
F

Flash Gordon

jacob navia wrote:

There are TWO costs associated with an indirect function call (i.e.
through a function pointer)

(1) The direct cost of pipeline problems as I described in my other
message

I've come across processors with a "call in two instructions time"
instrution, which avoids breaking the pipeline because the processor
executes all of the instructions in the pipeline when the call
instruction is encountered.
(2) The INDIRECT cost because the call graph is not explicit, what makes
many optimizations impossible. This second cost is often neglected but
it is very real.

There may or may not be a cost, it depends on what opportunities there
might be for optimising with a direct call. For example, it might be a
call to a function in a third-party pre-compiled library, so there would
not be any optimisation possible. As others said, it all depends.
And I will forget about the nonsense of heathfield that tries to make
a distinction between assembler mnemonics and machine code,

I was using assemblers where the mapping was not 1:1 in the 80s.
or even
kuyper that says that all function calls are pointer function calls
with some citation from the C standard... (even saying that loading the
value of the call into the instruction pointer is a "pointer" call).

I didn't spot anyone saying anything like that, although I might have
missed the odd post.
 
K

Keith Thompson

Phil Carmody said:
Was it meaningful?
Was it a direct analogue to the question asked?
[...]

So you were pointing out that the question, as asked, was
meaningless. And apparently we were supposed to know that your
meaningless answer, unlike the meaningless question, was intended
ironically.

Thanks for (finally) clarifying that.
 
A

Alan Curry

Observe:

1) source (cat foo.c)

#include <stdio.h>
#include <stdlib.h>

int foo(int i)
{ [...]
2) readable contents of binary (strings foo) after a normal make:

Might be more convincing if you'd said strings -n 3 since the default
threshold is 4 consecutive printable characters.
 
P

Phil Carmody

bartc said:
So, function pointers are faster than... what then?

Looks like you're finally working it out (clue - if you don't
understand something, there are often additional hints in my
headers).

Anyway, if you think that I can't say they're faster, then
similarly you must agree that others can't say they're slower
for precisely the same reason?

Phil
 
P

Phil Carmody

Keith Thompson said:
Phil Carmody said:
Was it meaningful?
Was it a direct analogue to the question asked?
[...]

So you were pointing out that the question, as asked, was
meaningless. And apparently we were supposed to know that your
meaningless answer, unlike the meaningless question, was intended
ironically.

Thanks for (finally) clarifying that.

Well, there was always the X-Planation header. ;-)

Phil
 
B

bartc

Phil Carmody said:
Was it meaningful?
Was it a direct analogue to the question asked?

No. One was a reasonable question that was understood by most participants
in the thread. The other was apparently a statement of fact by you, and
presumably incorrect.
If you haven't answered "no, yes" in that order, then let's try a
non-computing analogue:

Subject: Oranges: heavier?
Are oranges heavy? If so, how much heavier are they?

That's not the same thing. The implication in the question was clear. A
better analogy would be: Wrapped oranges: is there a weight penalty
associated with the use of wrapped oranges? If so how bad it it?

Which of course depends on the weight of the specific orange and the
properties of the wrapping material. In a few cases a wrapped orange might
be lighter.

For most people, this is not critical. But if you have a lot of oranges...
 
K

Keith Thompson

Phil Carmody said:
Keith Thompson said:
Phil Carmody said:
Is there a performance penalty associated with the use of function
pointers? If so, how bad is it?

Nope, function pointers are faster.

Could you please expand on this statement? Was it intended as
a joke? If not, what exactly do you mean?

Was it meaningful?
Was it a direct analogue to the question asked?
[...]

So you were pointing out that the question, as asked, was
meaningless. And apparently we were supposed to know that your
meaningless answer, unlike the meaningless question, was intended
ironically.

Thanks for (finally) clarifying that.

Well, there was always the X-Planation header. ;-)

Obviously the rest of us just aren't clever enough for your subtle
humor. You might want to consider dumbing it down for us. Or,
equivalently, just write more clearly and directly.

If taken seriously, your "Nope, function pointers are faster" would
have been a dumb statement; it's incomplete (faster than what?) and
most likely incorrect in most contexts if given the obvious
interpretation (function calls made via a pointer-to-function object
are faster than equivalent calls using the name of the function).

You're probably smart enough not to make such mistakes very often,
but I suggest not assuming that everyone else *knows* you're smart
enough not to make such mistakes. As you've seen in this thread,
it didn't work; several people assumed you were serious, and several
others were just confused.

When I write something here, I consider it more my responsibility
to make myself understood than my readers' responsibility to
understand me.
 
P

Phil Carmody

bartc said:
No. One was a reasonable question that was understood by most
participants in the thread. The other was apparently a statement of
fact by you, and presumably incorrect.


That's not the same thing. The implication in the question was
clear. A better analogy would be: Wrapped oranges: is there a weight
penalty associated with the use of wrapped oranges? If so how bad it
it?

That's a worse analogy. I would consider unwrapped oranges to
satisfy the same needs that I originally wanted wrapped oranges
for, and I would consider wrapped oranges to satisfy the same
needs that I originally wanted unwrapped oranges for. The concept
of chosing one or the other is perfectly natural, no matter which
one I had first looked at.

But I would rarely, if ever, treat direct calls to functions
and calls via function pointers to be mutually interchangeable
in the same way. Chosing one or the other would seldom be
an option if I'm already considering function pointers.

If I'm considering function pointers, I'm most likely not looking
at a scenario where direct calls to functions make much sense.
So the comparison should surely not by default be against direct
calls to functions but to other mechanisms of selecting code paths
dynamically, such as switch statements, or echelons of ifs, or
whatever. In which case, function pointers would quite often win.
Unless the compiler not only implemented the fixed function calls
within a switch statement as a jump table, but also realised that
the jumps were all to calls, and thence optimised it to a call
table rather than a jump table. In which case, what it did was
simply create an array of function pointers, because function
pointers were faster for that task.

So my apparently meaningless initial answer wasn't there *just* to
get you to question the question (such as the way an answer of
nothing more than 'mu' might do, perhaps, or a more direct "what
would you be doing otherwise?"), but also to encourage you to
think why I deliberately chose what seemed to be exactly the
wrong answer if you barge through with all assumptions blazing
regarding the original question.

For what I use them for, function pointers /are/ faster*.

Phil

[* than all simple alternatives available to me in the languages
where I use them.]
 
S

Seebs

Why - do they actually ask sensible questions over there?

comp.arch is surprisingly good much of the time, once you learn to filter
stuff a bit.

It tends to be a bit over my head, but I keep thinking someday I'll
get more serious about learning this stuff.

-s
 
S

Seebs

Might be more convincing if you'd said strings -n 3 since the default
threshold is 4 consecutive printable characters.

That depends! Many modern systems, rather than "finding sequences of
printable characters", "find strings" -- meaning, for a file in a known
binary format, they will actually decode the headers and display all
of the symbols and string literals defined, regardless of length.

.... Which, let me tell you, is a bit of a shock if you don't know about
it.

-s
 
J

James Kuyper

bartc said:
No. One was a reasonable question that was understood by most
participants in the thread. ...

Maybe you can enlighten the rest of us to what seems to be missing from
the the original question, and which Rui has failed to explain, despite
repeated requests: "performance penalty" relative to what?
That's not the same thing. The implication in the question was clear. A
better analogy would be: Wrapped oranges: is there a weight penalty
associated with the use of wrapped oranges? If so how bad it it?

Which of course depends on the weight of the specific orange and the
properties of the wrapping material. In a few cases a wrapped orange
might be lighter.

It also depends upon which alternative you're considering to to
"wrapped oranges": it might be "boxed oranges" or "bagged oranges". One
thing it cannot be, if we're to maintain this analogy, is "unwrapped
oranges", because direct function calls are almost never an adequate
substitute for function pointers in contexts where function pointers are
appropriate.
 
S

Seebs

But as it turns out, bartc didn't mean that the function is called by
a name lookup. So I'm darned if I can work out what he /does/ mean -
if you don't call it by name lookup (which is a weird way to do it
but it is at least a vaguely plausible mechanism) and you don't call
it via its address, how the heck /do/ you call it?

Maybe you don't; the compiler might have optimized it away.

More likely, I think, would be that you call it as an immediate value
which is looked up by the assembler during the assembly phase, such that
the generated binary just has a jump with an immediate offset of some
sort.

-s
 
S

Seebs

Maybe you can enlighten the rest of us to what seems to be missing from
the the original question, and which Rui has failed to explain, despite
repeated requests: "performance penalty" relative to what?

I assumed "to calling a function by name the ordinary way".

e.g.:

extern int (*p)(int) = putc;

p('\n');
putc('\n');

I would guess that there's no meaningful answer. I would not expect to
see a significant difference in performance between these -- it wouldn't
have even occurred to me to expect that there might be one, although perhaps
there is on some targets.

-s
 
A

Alan Curry

Fair enough. So I did that, without it changing the results. Then I
renamed foo to foofoofoo (in both the caller and the call), and
re-ran the original test, again without it changing the results.

Oops, also need -a to search the whole file.
But as it turns out, bartc didn't mean that the function is called by
a name lookup. So I'm darned if I can work out what he /does/ mean -
if you don't call it by name lookup (which is a weird way to do it
but it is at least a vaguely plausible mechanism) and you don't call
it via its address, how the heck /do/ you call it?

With a direct call instruction, you can determine the destination address if
you know the address of the call instruction, the opcode used, and the value
of its argument. An indirect call requires some extra information from
another memory location and/or another register.
 
S

Seebs

In other words, it's (effectively) a pointer dereference.

Not exactly. At least on some chips, an immediate call is different from
a call through a register; in particular, it's MUCH easier to branch-predict,
because you actually know the exact next location, while a call through
an address register (or an address stored in memory) might be riskier.
(Consider, for instance, what happens to an address stored in memory on
a multi-core machine...)

But!

So far as I can tell, the difference is essentially always trivial. Jacob
pointed out some resources on serious issues with indirect function execution
costs, but they appeared to be primarily about virtual methods in C++, which
are a WILDLY different kind of beast.

-s
 
P

Phil Carmody

Keith Thompson said:
Phil Carmody said:
Keith Thompson said:
Is there a performance penalty associated with the use of function
pointers? If so, how bad is it?

Nope, function pointers are faster.

Could you please expand on this statement? Was it intended as
a joke? If not, what exactly do you mean?

Was it meaningful?
Was it a direct analogue to the question asked?
[...]

So you were pointing out that the question, as asked, was
meaningless. And apparently we were supposed to know that your
meaningless answer, unlike the meaningless question, was intended
ironically.

Thanks for (finally) clarifying that.

Well, there was always the X-Planation header. ;-)

Obviously the rest of us just aren't clever enough for your subtle
humor. You might want to consider dumbing it down for us. Or,
equivalently, just write more clearly and directly.

If taken seriously, your "Nope, function pointers are faster" would
have been a dumb statement; it's incomplete (faster than what?)

Why didn't you all challenge the OP equivalently?
and
most likely incorrect in most contexts if given the obvious
interpretation (function calls made via a pointer-to-function object
are faster than equivalent calls using the name of the function).

You're probably smart enough not to make such mistakes very often,

As mentioned to Bartc, if you select the right context there isn't
even any mistake.
but I suggest not assuming that everyone else *knows* you're smart
enough not to make such mistakes. As you've seen in this thread,
it didn't work; several people assumed you were serious, and several
others were just confused.

And what happened when Nick asked:
"""
Message-ID: <3a9651ff-3c8d-4bc3-bf70-2a7255d72cfc@g31g2000yqc.googlegroups.com>
If you don't use a funtion pointer what will you do instead
and is that cheaper?
"""
?

Nothing.

And what happens when he then re-iterates:

"""
Message-ID: said:
If you don't use a funtion pointer what will you do instead
and is that cheaper?

you never addressed this point.
If you don't use a function pointer what will you use?
"""
?

Nothing.

Irony apparently worked far better /in the long run/ than the simpler
more direct approach Nick adopted. More direct? It's about as straight
and direct as you can get, and yet it was apparently completely over-
looked! That's quite a negative thing to highlight about the readership
of c.l.c.

It would have been fun if Richard had contributed just a 'mu', to see
what response that would have got.
When I write something here, I consider it more my responsibility
to make myself understood than my readers' responsibility to
understand me.

Whilst that's true, I've never particularly like spoon-feeding
unless there's been a specific request to take things in slow
steady increments.

Phil
 

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

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top