February 24, 2014 Re: DIP56 Provide pragma to control function inlining | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 2/23/2014 5:12 PM, Andrei Alexandrescu wrote: > This makes inlining dependent on previously-seen code. Would that make parallel > compilation more difficult? I don't understand the question. Inlining always depends on the compiler having seen the function body. > I've always thought the obvious/simple way would be an attribute such as > @forceinline and @noinline that applies to individual functions. Since inlining can't be done without the function body, putting the pragma in the function body makes sense. |
February 24, 2014 Re: DIP56 Provide pragma to control function inlining | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lionello Lunesu | On 2/23/2014 5:47 PM, Lionello Lunesu wrote:
> On 24/02/14 06:12, Walter Bright wrote:
>> On 2/23/2014 1:41 PM, Namespace wrote:
>>> pragma(inline, true);
>>> pragma(inline, false);
>>> pragma(inline, default);
>>
>> 'default' being a keyword makes for an ugly special case in how pragmas
>> are parsed.
>>
>
> Aren't true and false keywords as well?
Yes, but the are also expressions. default is not.
|
February 24, 2014 Re: DIP56 Provide pragma to control function inlining | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 23/02/14 20:07, Walter Bright wrote:
> http://wiki.dlang.org/DIP56
>
> Manu has needed always inlining, and I've needed never inlining. This
> DIP proposes a simple solution.
void A()
{
}
void B()
{
pragma(inline, true) A();
}
void C()
{
B();
}
Reading that code, I would guess that within B(), the call to A() would get inlined. Reading the DIP, it appears that the pragma controls whether B() gets inlined.
When the pragma is used outside of the scope at the function declaration it would work more like "inline" or "__inline" in C++, correct?
L.
|
February 24, 2014 Re: DIP56 Provide pragma to control function inlining | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Sun, 23 Feb 2014 21:05:32 -0500, Walter Bright <newshound2@digitalmars.com> wrote: > On 2/23/2014 5:45 PM, Brad Roberts wrote: >> At this point, you're starting to argue that the entire DIP isn't relevant. I >> agree with the majority that if you're going to have the directive, then it >> needs to be enforcement, not suggestion. > > 1. It provides information to the compiler about runtime frequency that it cannot obtain otherwise. This is very useful information for generating better code. But you are under-utilizing the message. There is the case that one wants inlining, even when -inline isn't passed to the compiler, for functions that would have been inlined if -inline was specified. That is your case, right? But there is a case where the compiler for some reason has decided that inlining a function is not worth it, so even with -inline it doesn't do it. However, without the inlining, the function becomes horrendously slow. For example, functions that contain lazy parameters. > 2. Making it a hard requirement then means the user will have to put versioning in it. It becomes inherently non-portable. There is no way to predict what some other version of some other compiler on some other system will do. This is not a problem. The whole point is, if the compiler doesn't support the inlining, the code is useless. I WANT it to fail, there is no reason to version it out. > 3. In the end, the compiler should make the decision. Inlining does not always result in faster code, as I pointed out in another post. Huh? Then why even have the feature if the compiler is going to ignore your request! This feature sounds completely useless to me, it certainly adds no real value that warrants adding a pragma. It may as well be called pragma(please_inline_pretty_pretty_please_ill_be_your_best_friend) > 4. I don't see that users really are asking for inlining or not. They are asking for the fastest code. As such, providing hints about usage frequencies are entirely appropriate. Micromanaging the method used is not so appropriate. After all, the reason one uses a compiler in the first place rather than assembler is to not micromanage the actual instructions. Compilers are not infallible. They may make mistakes, or not have enough information, which is the point of this feature. What is to say they don't make mistakes even with the correct amount of information? And the reason I use a compiler rather than assembler is because I hate writing assembler :) > Perhaps the lesson is the word 'inline' carries certain expectations with it, and the feature would be better positioned as something like: > > pragma(usage, often); > pragma(usage, rare); This is totally the wrong tack. First, I may have no idea how often a function will be used. Second, usage frequency has nothing to do with how inlining may affect the performance of an individual call. If an inlined function always executes faster than calling the function, I always want to inline. For example, foo: void foo(ref int x) { ++x; } -Steve |
February 24, 2014 Re: DIP56 Provide pragma to control function inlining | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 2/23/14, 4:33 PM, Walter Bright wrote:
> On 2/23/2014 3:55 PM, Mike wrote:
>> The difference is it was explicitly told do do something and didn't.
>> That's
>> insubordination.
>
> I view this as more in the manner of providing the equivalent of runtime
> profiling information to the optimizer, in indirectly saying how often a
> function is executed.
>
> Optimizing is a rather complicated process, and particular optimizations
> very often have weird and unpredictable interactions with other
> optimizations.
>
> For example, in the olden days, C compilers had a 'register' storage
> class. Optimizers' register allocation strategy was so primitive it
> needed help. Over time, however, it became apparent that uses of
> 'register' became bit-rotted due to maintenance, resulting in all the
> wrong variables being enregistered. Compiler register allocation got a
> lot better, almost always being better than the users'. Not only that,
> but with generic code, and optimization rewrites of code, many variables
> would disappear and new ones would take their place. Different CPUs
> needed different register allocation strategies. What to do with
> 'register' then?
>
> The result was compilers began to take the 'register' as a hint, and
> eventually moved to totally ignoring 'register', as it turned out to be
> a pessimization.
>
> I suspect that elevating one particular optimization hint to being an
> absolute command may not turn out well. Inlining already has performance
> issues, as it may increase the size of an inner loop beyond what will
> fit in the cache, for just one unexpected result. For another it may
> mess up the register allocation of the caller. "Inlining makes it
> faster" is not always true. Do you really want to weld this in as an
> absolute requirement in the language?
I'll add an anecdote - in HHVM we owe a lot of speedups to the careful use of "never inline" and "always inline" gcc pragmas IN ADDITION TO the usual "inline" directives. We have factual proof that gcc makes the wrong inline decisions BOTH WAYS if left to decide.
If we define pragmas for inlining, "always inline" must mean always inline no questions asked and "never inline" must mean always prevent inlining no questions asked. Anything else would be a frustrating waste of time.
Andrei
|
February 24, 2014 Re: DIP56 Provide pragma to control function inlining | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 2/23/14, 5:55 PM, bearophile wrote:
> Andrei Alexandrescu:
>
>> I've always thought the obvious/simple way would be an attribute such
>> as @forceinline and @noinline that applies to individual functions.
>
> Seems good. And what do you think the D compiler should do when you use
> @forceinline and it can't inline?
Compile-time error, no two ways about it.
Andrei
|
February 24, 2014 Re: DIP56 Provide pragma to control function inlining | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 2/23/14, 6:12 PM, Walter Bright wrote:
> On 2/23/2014 5:12 PM, Andrei Alexandrescu wrote:
>> This makes inlining dependent on previously-seen code. Would that make
>> parallel
>> compilation more difficult?
>
> I don't understand the question. Inlining always depends on the compiler
> having seen the function body.
Decision to inline at line 2000 may be caused by a pragma in line 2.
Andrei
|
February 24, 2014 Re: DIP56 Provide pragma to control function inlining | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 2/23/14, 6:05 PM, Walter Bright wrote: > 4. I don't see that users really are asking for inlining or not. They > are asking for the fastest code. As such, providing hints about usage > frequencies are entirely appropriate. Micromanaging the method used is > not so appropriate. After all, the reason one uses a compiler in the > first place rather than assembler is to not micromanage the actual > instructions. In HHVM we plainly ask for specific decisions on inlining or not. We have a reasonably good understanding of how and where our code has trouble with ICache misses, and adjust our inline decisions and validate using experiments. A decision to force inlining or against it already indicates a failure of the compiler's heuristics to address the situation. Keeping it an option is insisting on failing. > Perhaps the lesson is the word 'inline' carries certain expectations > with it, and the feature would be better positioned as something like: > > pragma(usage, often); > pragma(usage, rare); That's an interesting unrelated idea. But if we defined pragmas to "force inline" and "never inline" we must damn sure make sure the compiler always does that. It's "listen to your customers" as plainly as it gets. Andrei |
February 24, 2014 Re: DIP56 Provide pragma to control function inlining | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Monday, 24 February 2014 at 04:14:08 UTC, Andrei Alexandrescu wrote:
> I'll add an anecdote - in HHVM we owe a lot of speedups to the careful use of "never inline" and "always inline" gcc pragmas IN ADDITION TO the usual "inline" directives. We have factual proof that gcc makes the wrong inline decisions BOTH WAYS if left to decide.
>
> If we define pragmas for inlining, "always inline" must mean always inline no questions asked and "never inline" must mean always prevent inlining no questions asked. Anything else would be a frustrating waste of time.
I think there is another, distinct use case for an inline pragma where "try to inline" is useful - namely, turning on the equivalent of the compiler "-inline" switch for just one function. I believe this is the original rationale behind the DIP (enabling inlining for certain functions even in debug builds, because otherwise the debug builds become so slow as to be unusable). In this case, whether the compiler actually succeeds at inlining the function doesn't matter as long as it does the same thing as for an optimized (-inline) build.
Thus, I think there should be "try to inline" (same as -inline) and "always inline" (failure stops compilation).
|
February 24, 2014 Re: DIP56 Provide pragma to control function inlining | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Monday, 24 February 2014 at 02:05:31 UTC, Walter Bright wrote: > 1. It provides information to the compiler about runtime frequency that it cannot obtain otherwise. This is very useful information for generating better code. This answers to your own previous question: this is what makes "inline" a special optimization. > 3. In the end, the compiler should make the decision. Inlining does not always result in faster code, as I pointed out in another post. Honestrly, in the small profiling I've done in my life, at least inlining never made my code slower. But I do realize this is not relevant to the discussion. > Perhaps the lesson is the word 'inline' carries certain expectations with it, and the feature would be better positioned as something like: > > pragma(usage, often); > pragma(usage, rare); Yes, I think "inline" carries huge expectations: the expectation for the compiler to comply. If the plan is hinting frequency information, then "usage" makes way more sense. It might be used in if blocks and in switch cases too, when branch prediction might be sloppy or unoptimal. |
Copyright © 1999-2021 by the D Language Foundation