This is definitely good advice. One of the problems we had in "the
early days" was that LLVM heuristics didn't seem to quite be tuned for
our case, so we wound up tossing around `always`, and I think we have
seen far overdone it (and probably already overdid it in the
beginning). It'd be interesting to see whether the LLVM heuristics can
be tuned at all to better estimate the benefts of inlining in Rust
specifically.

And no, I don't have any examples right now :)



Niko

On Thu, May 30, 2013 at 03:15:48PM +1200, James Miller wrote:
> Hello Everyone,
> 
> I've been doing work around optimizations recently, and noticed that libextra 
> was taking an 
> inordinate amount of time to build. My investigations led me to find that 
> well over half the time 
> spent was on Loop Invariant Code motion, i.e. moving expressions that don't 
> change out of the loop.
> 
> One of the more common cases turns this:
> 
>     while i < n {
>         data.field[i] = something(i);
>         i += 1;
>     }
> 
> into this:
> 
>    let tmp = data.field;
>    while i < n {
>        tmp[i] = something(i);
>    }
> 
> since, the field access is invariant.
> 
> Anyway, the BigInt module uses this pattern a lot. It also has 112 functions 
> marked with 
> #[inline(always)]. This does two things: causes massive code bloat, 2 orders 
> of magnitude worth of 
> code bloat, and makes later passes work much, much harder. Many of the 
> functions in BigInt would 
> have been inlined multiple times into one function, and in some cases, those 
> functions would be 
> further inlined into other functions, despite blowing past the normal inline 
> cost limit.
> 
> This meant that a fairly simple, standard pass, was being called on over 100x 
> more code than it 
> needed to be. If you want to know why a full build takes so long, there is 
> why.
> 
> Inlining is a pretty standard optimization, and is potentially done for every 
> function that isn't 
> marked with `#[inline(never)]`, but the compiler is smart enough to know when 
> it's not worth it.  
> `#[inline(always)]` is a very strong statement, and should be reserved for 
> cases where you are 
> certain that the function absolutely needs to be inlined, no exceptions. 
> Remember that "always" 
> means it, so every single function that uses it will get a copy.
> 
> Inlining is not a magic bullet for performance and the compiler passes are 
> far smarter at knowing 
> what is more efficient than you are.
> 
> Thank you for your time,
> James Miller
> _______________________________________________
> Rust-dev mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to