glen herrmannsfeldt wrote:
>> But is that necessarily a disadvantage? The overhead of a function call
>> is not that large. Inlining only matters if either the inlines code is
>> small - which avoids the calling overhead or when it can be used for
>> simplification (e.g. the compiler knows via inlining that the stride is
>> 1). Instead of inlining, a compiler might also clone a procedure and
>> apply the simplification there.
>
> But inlining also allows for other optimizations that might otherwise
> not be possible. Especially constant folding and common subexpression
> optimization.
Well, cloning also does so: It might clone a procedure where e.g. one
argument is eliminated as it is used as a constant.
Such kind of optimizations - which can be done by inlining or by cloning
- can be very profitable. Also avoiding the generation of temporaries
and inline replacements of library functions can help with the
performance. However, not always is an inline version faster than a
highly optimized library function - only if the inline-generated version
permits additional optimizations or is also highly optimized.
> The general assumption of optimizers is that loops will be run
> enough times that it pays to move evaluations out of the loop.
> In any real case, I suppose with the exception of loops with
> constant limits, the compiler really doesn't know. (Anyone want
> to bring back the FREQUENCY statement?)
Typically, the interesting loops do not have constant limits. Actually,
for loops more interesting are dependency information. Like OpenMP's
"!$omp simd" or Fortran 2008's DO CONCUCRRENT. If the compiler knows
that the loop order can be modified, it can apply vectorization (=
SIMD), which it otherwise couldn't.
gfortran currently treats do concurrent like a normal loop. However,
with GCC 4.9, it will make use of it.
(Also OpenMP 4 will be [mostly] supported, including "!$omp simd". C/C++
users will presumably also be able to use Cilk+'s features, including
"#pragma simd" - and Fortran-inspired array and elemental handling.)
> In the case of very simple (say one operation) functions, an inline
> statement function is likely better than a not-inline internal
> or external function.
I think it depends. Assume:
do i = 1, 1000000
if (mod(i,10000)) then
call func()
else
x = sin(i*x)
end
end do
Here, inlining "func" could make the program slower as it is only used
on a rare path but might cause that the hot path is not in the cache.
(Not the best example, but you might get the idea.)
Thus, inlining is not always profitable. The fewer instructions the
to-be inlined function has, the higher the chance that inlining is useful.
What also helps is if the compiler can see all users of a procedure. For
instance, with internal procedures, the compiler knows that a procedure
is only used in the host procedure and the siblings of the internal
procedure.
In that case, inlining can eliminate the original procedure, which makes
inlining more profitable.
In newer gfortran versions, also module procedures which are PRIVATE are
regarded as being limited to that module. (Unless they are externally
visible, e.g. via a generic name or by being using in a specification
expression in the interface of a public procedure.)
Similar optimizations apply to module variables, except that GCC doesn't
do apply as much optimization to SAVEd variables as it could be.
> Does gfortran inline statement functions?
Yes, it directly inserts the statement-function code in place.
If you want to see what it does, compile with -fdump-tree-original
-fdump-tree-optimized which gives you an internal representation of the
generated code. The code looks C like and is relatively readable, but it
does not contain the full information. (For instance, derived-type
declarations are missing or Fortran's INTENT which is used for
optimization by the GCC middle end.)
The dumps are written in separate files.
Tobiasg