March 20, 2014 Re: inlining... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ola Fosheim Grøstad | On Thursday, 20 March 2014 at 08:35:22 UTC, Ola Fosheim Grøstad wrote:
> Nothing prevents you to introduce exceptions as an extension though. I want inline(0.5) as default, but also be able to write inline(1) for inline always and inline(0) for inline never.
>
> func1(){} // implies inline(0.5) weighting
> inline func2(){} // same as inline(1) weighting, inline always
> inline(0.75) fun31(){} // increase the heuristics weighting
> inline(0) func4(){} // never-ever inline
>
It looks promising when seen like that, but introducing explicit inlining/deinlining to me correspond to a precise process:
1. Bottleneck is identified.
2. "we could {inline|deinline} this call at this particular place and see what happens"
3. Apply inline directive for this call. Only "always" or "never" is ever wanted for me, and for 1 level only.
4. Measure and validate like all optimizations.
Now after this, even if the inlining become harmful for other reasons, I want this inlining to be maintained, whatever the cost, not subject to random rules I don't know of. When you tweak inlining, you are supposed to know what you are doing, and it's not just an optimization, it's an essential tool that enables other optimizations, help disambiguate aliasing, help the auto-vectorizer, help constant propagation...
In the large majority of cases it can be left to the compiler, and in the 1% cases that matters I want to do it explicitely full stop.
|
March 20, 2014 Re: inlining... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On 2014-03-19 09:35, Manu wrote: > I don't already have it, otherwise I'd be making use of it. D has no > control over the inliner. GDC/LDC offer attributes, but then it's really > annoying that D has no mechanism to make use of compiler-specific > attributes in a portable way (ie, attribute aliasing), so I can't make > use of those without significantly interfering with my code. Can't you create a tuple with different attributes depending on which compiler is currently compiling? Something like this: version (LDC) alias attributes = TypeTuple!(@attribute("forceinline"); else version (GDC) alias attributes = TypeTuple!(@attribute("forceinline")); else version (DigitalMars) alias attributes = TypeTuple!(); else static assert(false); @(attributes) void foo () { } // This assume that "attributes" will be expanded -- /Jacob Carlborg |
March 21, 2014 Re: inlining... | ||||
---|---|---|---|---|
| ||||
Posted in reply to ponce | On Thursday, 20 March 2014 at 15:26:35 UTC, ponce wrote:
> Now after this, even if the inlining become harmful for other reasons, I want this inlining to be maintained, whatever the cost, not subject to random rules I don't know of. When you
The rules aren't random. The inliner conceptually use weighting anyway, you just increase the threshold for a specific call-tree. E.g. if a function is on the borderline of being inlined the probability is 50% if you add some noise to the selection with a magnitude that equals the "typical approximation error" of the heuristics. "inline(0.75)" should increase the probability to 75%. Today all functions have an implied "inline(0.5)". I think you should have this kind of control for all compiler heuristics thresholds that are "arbitrary", not only inlining.
Call site inlining is primarily useful for inlining external code. The alternative is usually to replace libraries with your own version.
|
March 24, 2014 Re: inlining... | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | Maybe we could have both declare site inlining and call site inlining. with declare site, what we mean is that this function's body is used so commonly that we make it into a function only because we don't want duplicate code, not because it should be a standalone function. with call site inlining, one can inline thirdparty functions which is not declared inline. I think the `inline` Manu suggested should not be viewed as a mere optimization thing, but more like a code generation utility which happens to be faster. In this point of view, this kind of `inline` should be controlled by the coder, not the compiler. To make it clear that we are not talking about optimization, maybe we should call it another name, like 'mixin function'? BTW, the Kotlin language recently get a new released, which added support for declare site force inline, the team argues its necessity here: http://blog.jetbrains.com/kotlin/2014/03/m7-release-available/#more-1439 in the comments: >It’s traditional to think about inlining as a mere optimization, but this dates back to the times >when software was shipped as one huge binary file. > >Why we think inline should be a language feature: >1. Other language features (to be implemented soon) depend on it. Namely, non-local returns >and type-dependent functions. Basically, inline functions are very restricted macros, and this >>is definitely a language feature. >2. Due to dynamic linking and binary compatibility issues it can not be up to the compiler >whether to inline something or not on the JVM: if bodies of inline functions change, all >dependent code should be recompiled, i.e. it’s the library author’s liability to preserve >functionality, so such functions must be explicitly marked. On Thursday, 20 March 2014 at 02:08:16 UTC, Manu wrote: > On 20 March 2014 06:23, > <7d89a89974b0ff40.invalid@internationalized.invalid>wrote: > >> On Wednesday, 19 March 2014 at 12:35:30 UTC, Manu wrote: >> >>> Okay, do you have use cases for any of this stuff? Are you just making it >>> up, or do you have significant experience to say this is what you need? >>> >> >> I don't need anything, I hand optimize prematurely. And I don't want to do >> that. >> >> But yes, inner loops benefits from exhaustive inlining because you get to >> move common expressions out of the loop or change them to delta increments. >> It is only when you trash the caches that inlining does not pay off. >> >> I do it by hand. I don't want to do it by hand. >> >> >> If you ask me, I have no value in recursive inlining, infact, that would >>> anger me considerably. >>> >> >> Why? You could always set the depth to 1, or make 1 the default. >> >> And it isn't difficult to implement. >> > > The problem is upside down. If you want to inline multiple levels, you > start from the leaves and move downwards, not from the root moving upwards > (leaving a bunch of leaves perhaps not inlined), which is what you're > really suggesting. > Inlining should be strictly deliberate, there's nothing to say that every > function called in a tree should be inlined. There's a high probability > there's one/some that shouldn't be among a few that should. > > Remember too, that call-site inlining isn't the only method, there would > also be always-inline. I think always-inline is what you want for some > decidedly trivial functions (although these will probably be heuristically > inlined anyway), not call-site inlining. I just don't see how recursive > call-site inlining is appropriate, considering that call trees are often > complex, subject to change, and may even call functions that you don't have > source for. You can cascade the mixin keyword if you want to, that's very > simple. I'd be highly surprised if you ever encountered a call tree where > you wanted to inline everything (and the optimiser didn't do it for you). > As soon as you encounter a single function in the tree that shouldn't be > inlined, then you'll be forced to do it one level at a time anyway. |
Copyright © 1999-2021 by the D Language Foundation