Thread overview
Re: inlining
Dec 07, 2010
Jonathan M Davis
Dec 07, 2010
Lutger Blijdestijn
Dec 07, 2010
spir
Dec 07, 2010
Lutger Blijdestijn
Dec 07, 2010
Lutger Blijdestijn
Dec 07, 2010
spir
December 07, 2010
On Tuesday 07 December 2010 03:05:28 spir wrote:
> Hello,
> 
> Does dmd inline when appropriate (eg single-line func)? or is there a hint keyword? or what else? Eg how to have this inlined:
> 
> private bool isPrecomposedHangulSylable (Code code) {
>     /** whether code is a precomposed Hangul syllable ;-) */
>     return (code >= FIRST_HANGUL_SYLLABLE) && (code <=
> LAST_HANGUL_SYLLABLE); }

C++ has the inline keyword, and it is used only as a hint to the compiler. The compiler is free to follow it or ignore it as it sees fit, so its usefulness is debateable. D does _not_ have the inline keyword. It just leaves it up to the compiler entirely. Note that the -inline flag enables inlining.

IIRC, no functions which have lazy parameters or include inline assembly will ever be inlined. And, of course, if a function is long, the compiler is unlikely to choose to inline it (though maybe it would choose to if the function is only ever called once - that's up to the inliner).

Excluding functions with lazy parameters (or which call a function with any lazy parameters) or which include inline assembly, any non-virtual function should be inlineable. So, any functions which are not members of a class could be inlined. Class functions which are static could be inlined. private member functions could be inlined. And final functions which override no other function could be inlined (assuming that the compiler does indeed make such a function non-virtual - it should since it can, but I don't know how smart it is about that).

Generally, inlining isn't something to worry about. The compiler will do it if the -inline flag is used, and whatever would be appropriate to inline will be inlined. It's likely only a concern when you're trying to eek every last ounce of speed out of a program, and at that point, you'll have to look at the generated assembly code to figure out whether a function is actually inlined or not. The one place that it makes some sense to worry about it is if you're dealing with functions that you really think should be inlined, then don't use lazy parameters (or call functions with lazy parameters within that function) and don't use inline assembly. But since it's generally abnormal to do either of those, it's not generally an issue. The one function that I'm aware which regularly causes issues with that is enforce(), and there has been some talk of making it non-lazy, or making a non-lazy version of it, or somehow making the compiler smart enough to choose whether to make it lazy or not.

In any case, if you want to enable inlining, use the -inline flag. It would be typical to use that with -release and -O. Don't use it for debug builds though, since that'll screw with debuggers (just like -O can).

- Jonathan M Davis
December 07, 2010
Jonathan M Davis wrote:

> On Tuesday 07 December 2010 03:05:28 spir wrote:
>> Hello,
>> 
>> Does dmd inline when appropriate (eg single-line func)? or is there a hint keyword? or what else? Eg how to have this inlined:
>> 
>> private bool isPrecomposedHangulSylable (Code code) {
>>     /** whether code is a precomposed Hangul syllable ;-) */
>>     return (code >= FIRST_HANGUL_SYLLABLE) && (code <=
>> LAST_HANGUL_SYLLABLE); }
> 
> C++ has the inline keyword, and it is used only as a hint to the compiler. The compiler is free to follow it or ignore it as it sees fit, so its usefulness is debateable. D does _not_ have the inline keyword. It just leaves it up to the compiler entirely. Note that the -inline flag enables inlining.
> 
> IIRC, no functions which have lazy parameters or include inline assembly will ever be inlined. And, of course, if a function is long, the compiler is unlikely to choose to inline it (though maybe it would choose to if the function is only ever called once - that's up to the inliner).
...
> - Jonathan M Davis

There are some other conditions that prevent inlining, it's best to check for it. iirc also functions with loops, delegate and ref parameters cannot be inlined for example. I'm not so sure about ref, that may have been improved since the last time I checked. Perhaps also for some class of delegates, at least ldc supposedly can inline some functions with delegate parameters.

December 07, 2010
On Tue, 07 Dec 2010 13:44:18 +0100
Lutger Blijdestijn <lutger.blijdestijn@gmail.com> wrote:

> There are some other conditions that prevent inlining, it's best to check for it. iirc also functions with loops, delegate and ref parameters cannot be inlined for example. I'm not so sure about ref, that may have been improved since the last time I checked. Perhaps also for some class of delegates, at least ldc supposedly can inline some functions with delegate parameters.

What do you mean with ref, ref parameters? If yes, why ar they problematic?

Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com

December 07, 2010
spir wrote:

> On Tue, 07 Dec 2010 13:44:18 +0100
> Lutger Blijdestijn <lutger.blijdestijn@gmail.com> wrote:
> 
>> There are some other conditions that prevent inlining, it's best to check for it. iirc also functions with loops, delegate and ref parameters cannot be inlined for example. I'm not so sure about ref, that may have been improved since the last time I checked. Perhaps also for some class of delegates, at least ldc supposedly can inline some functions with delegate parameters.
> 
> What do you mean with ref, ref parameters? If yes, why ar they problematic?
> 
> Denis
> -- -- -- -- -- -- --
> vit esse estrany ☣
> 
> spir.wikidot.com

this:

void foo(ref int a) { a++; }

At the time I checked, this function could not be inlined by dmd, which can cost performance in some cases.
December 07, 2010
Lutger Blijdestijn wrote:

> spir wrote:
> 
>> On Tue, 07 Dec 2010 13:44:18 +0100
>> Lutger Blijdestijn <lutger.blijdestijn@gmail.com> wrote:
>> 
>>> There are some other conditions that prevent inlining, it's best to check for it. iirc also functions with loops, delegate and ref parameters cannot be inlined for example. I'm not so sure about ref, that may have been improved since the last time I checked. Perhaps also for some class of delegates, at least ldc supposedly can inline some functions with delegate parameters.
>> 
>> What do you mean with ref, ref parameters? If yes, why ar they problematic?
>> 
>> Denis
>> -- -- -- -- -- -- --
>> vit esse estrany ☣
>> 
>> spir.wikidot.com
> 
> this:
> 
> void foo(ref int a) { a++; }
> 
> At the time I checked, this function could not be inlined by dmd, which can cost performance in some cases.

ok I checked it, it seems the dmd has improved in the meantime and is able to inline this case now.

For reference:

void foo(ref int a ) { a++; }
void bar(int* a ) { a++; }

void main()
{
    int a;
    foo(a);
    bar(&a);
}

compile with -profile -inline -O and run it, it will produce a trace.log and trace.def file. The trace.def contain the optimal order in which to link the functions, the trace.log file contains a call graph and a table of timings. (you won't see anything interesting here, because everything is inlined). It's a great way to check for performance bottlenecks.
December 07, 2010
On Tue, 07 Dec 2010 16:20:45 +0100
Lutger Blijdestijn <lutger.blijdestijn@gmail.com> wrote:

> Lutger Blijdestijn wrote:
> 
> > spir wrote:
> > 
> >> On Tue, 07 Dec 2010 13:44:18 +0100
> >> Lutger Blijdestijn <lutger.blijdestijn@gmail.com> wrote:
> >> 
> >>> There are some other conditions that prevent inlining, it's best to check for it. iirc also functions with loops, delegate and ref parameters cannot be inlined for example. I'm not so sure about ref, that may have been improved since the last time I checked. Perhaps also for some class of delegates, at least ldc supposedly can inline some functions with delegate parameters.
> >> 
> >> What do you mean with ref, ref parameters? If yes, why ar they problematic?
> >> 
> >> Denis
> >> -- -- -- -- -- -- --
> >> vit esse estrany ☣
> >> 
> >> spir.wikidot.com
> > 
> > this:
> > 
> > void foo(ref int a) { a++; }
> > 
> > At the time I checked, this function could not be inlined by dmd, which can cost performance in some cases.
> 
> ok I checked it, it seems the dmd has improved in the meantime and is able to inline this case now.
> 
> For reference:
> 
> void foo(ref int a ) { a++; }
> void bar(int* a ) { a++; }
> 
> void main()
> {
>     int a;
>     foo(a);
>     bar(&a);
> }
> 
> compile with -profile -inline -O and run it, it will produce a trace.log and trace.def file. The trace.def contain the optimal order in which to link the functions, the trace.log file contains a call graph and a table of timings. (you won't see anything interesting here, because everything is inlined). It's a great way to check for performance bottlenecks.

Right. Tried & worked as you say. Thenk for the tip.

denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com