This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: std::pow implementation

Whee.  I was wondering why my gcc inbox was getting so big.  Can I join
the party?

I realize I'm a bit late, but some of the arguments in this thread seem
so confused that I can't resist.

On Wed, 30 Jul 2003, Alexandre Oliva wrote:

> Therefore, inline the way you describe it, is useful only for
> functions that are *always* profitable to inline.  Any function that
> might or might not be profitable to inline should not be declared
> inline, and the compiler would never inline it.  This sounds silly to
> me.  Why not let the user tell the compiler `hey, look, this function
> is probably worth trying to inline', but letting the compiler decide
> whether it's actually profitable or not, depending not only on the
> context, but also on machine-dependent features?

We've had -finline-functions (aka -O3) for years; it does what you
suggest: let the compiler choose which functions to inline.  If we
assume that this option does a reasonable job, it can be used if you
want to write portable code and don't want to bother with performance
measurements and suchlike.

The question then becomes which effect the inline keyword should have?
I propose that it have the effect expected by most people who aren't
compiler hackers: let the function be inlined, if possible within
reasonable limits (*).  This is orthogonal to -finline-functions.
Otherwise, the inline keyword becomes meaningless and there is no
reason to use it - but people still want the functionality and must
resort to always_inline, which decreases portability.

Some people propose that inline should mean "I'd like this to go fast".
Do you propose that lack of inline means "I'd like this to go slow"?
This is a meaningless definition.  Either the compiler can make an
informed decision (possible in theory but not implemented in practice),
or it can't.  In the former case, inline is redundant.  In the latter
case, it is clearly better to trust the programmer (who is usually
an intelligent, sentient being) over the compiler (an unintelligent
entity using a bad algorithm).

Others come up with examples where the compiler could make a better
choice.  The fact of the matter is, it _doesn't_ make a better choice
today.  inline is unlike register; we do not have a good deciding
algorithm for it.  I cannot understand the attitude of "well, let
the compiler make a choice, it could have an algorithm that makes
reasonable choices" when noone has demonstrated the existence of such
an algorithm yet.  How about we make choices based on usefulness for
our users, rather than theoretical considerations?  We can't just
ignore the deficiencies of our current algorithms and handwave them
away with arguments of the "could" and "might" variety.

Let's take the example of a 2000 line function with a boolean argument.
If true, the function collapses to a one-liner, if false, it remains
a monster.  Proponents of inline-as-a-hint would have us believe that
we should let the compiler choose because it _could_, in theory, make
an informed decision.  In practice, the compiler's decision is random.

If you allow inline to direct the compiler to do what the user intends,
you can work around the problem by one or two wrapper functions (one
out-of-line one which inlines the monster, and another inline one
which passes true for the boolean and gets collapsed).  Such
techniques are common; I've used them myself, and I am very annoyed
that recent versions of gcc make a complete mess out of my code.

Let's take the other example of a 2000 line function that never collapses
to something short, but is marked inline.  We can assume inlining it
doesn't improve performance much.  It may even hurt.  This seems to be a
case of don't do that,  then.  If someone wants to write code this way,
let them - but don't take away my options just because a feature can be
misused.  Do you want the compiler to make "intelligent" decisiones
whether to transform an insertion sort you wrote into a quicksort?
Sometimes you want an insertion sort, and sometimes you want a function
to be always inlined.


(*) Reasons why I'd accept inline not being honoured:
  - the function would become too big for the machine (or any other reason
    why the code wouldn't work)
  - recursive functions
  - alloca or some other feature that causes stack size explosions
    is used.  We should warn - this is a case for always_inline
    (Likewise for any dodgy GNU extensions I'm forgetting right now)
  - the compiler would explode due to lack of memory - we should make an
    effort this doesn't become a frequent reason
  - the programmer used -Os (and we can prove the code would get bigger)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]