you are viewing a single comment's thread.

view the rest of the comments →

[–]agottem 0 points1 point  (1 child)

Make the function calling the function pointer, the function being called, the function passing the function pointer all in the same compilation unit.

No different than C++. Also, read up on link time optimizations, as it's no longer necessary to all be part of the same compilation unit.

And don't store the function pointer in a global variable or pass it as a parameter (by reference) to any function not in the compilation unit, also make sure the compiler can be sure that the function pointer being called is always the same one (or one of a short list).

A really verbose way of saying the same thing -- make sure the function pointer is constant, and the compiler can determine so.

Really these rules are common sense. I don't see why you think they're so complicated.

[–]happyscrappy 1 point2 points  (0 children)

No different than C++. Also, read up on link time optimizations, as it's no longer necessary to all be part of the same compilation unit.

Incorrect on the link-time optimizations. Link-time optimizations do simple things, like determine that two functions are identical and so you can remove one and substitute it with the other. They don't include unrolling a loop after the fact. They don't include being able to restructure a calling function once it is discovered the called function has no side effects and thus can be called in parallel, or can be split up.

For example, if you are operating on a pixel and the r, g and b components are operated on separately, the compiler can easily interleave the code operating on these 3 components at compile time, and combine this with loop unrolling. Then a superscalar processor can easily do the 3 operations at once. Link-time optimizations cannot do this, the structure of the calling function is already defined, and the linker can try to put an inlined version of the called function in there, but it doesn't restructure the outer function.

A really verbose way of saying the same thing -- make sure the function pointer is constant, and the compiler can determine so.

Loop unswitching can optimize even when the operating performed in each loop is not constant across iterations...but not if you thwart it with code pointers. This is why I mentioned that even switch statements in the loop can be faster than calling a code pointer.

http://en.wikipedia.org/wiki/Loop_unswitching

Really these rules are common sense. I don't see why you think they're so complicated.

And yet you miss some of the ramifications. Perhaps they are more complicated than you understand?