<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Sep 17, 2019 at 6:25 AM Michael Woerister <<a href="mailto:mwoerister@mozilla.com">mwoerister@mozilla.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><br>> By ld do you mean GNU ld?<br><br>Yes, GNU ld version 2.31.1 on Fedora 30.<br><br>> I know GNU ld does "work" with LLVM's gold plugin, but it's an untested combination and not recommended.<br><br>That's good to know! However, in this case no linker plugin is involved. All of LLVM is executed within the Rust compiler and the linker only ever gets to see regular object files.</div></blockquote><div><br></div><div>Ugh, I was confusing your PGO issue with an LTO issue - there is no plugin involved in non-LTO! And GNU ld should be fine with regular obj files produced by LLVM. Sorry for the confusion!</div><div><br></div><div>It sounds like David had the right intuition on what might be going on, I'll let him follow up with you on that as he has a better understanding of the instrumentation side.</div><div><br></div><div>Teresa</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Sep 16, 2019 at 7:07 PM Teresa Johnson <<a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Interesting. By ld do you mean GNU ld? I know GNU ld does "work" with LLVM's gold plugin, but it's an untested combination and not recommended. I wouldn't be surprised if there were some issues around it not passing necessary info to the gold plugin.<div><br></div><div>Teresa</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Sep 16, 2019 at 8:41 AM Michael Woerister <<a href="mailto:mwoerister@mozilla.com" target="_blank">mwoerister@mozilla.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">So one interesting observation has already come out of this: I<br>
confirmed that `rustc` indeed uses `-ffunction-sections` and<br>
`-fdata-sections` on all platforms except for macOS. When trying out<br>
different linkers for a small test case [1], however, I found that<br>
there were rather large differences in execution time:<br>
<br>
ld (no PGO) = 172 ms<br>
ld (PGO) = 196 ms<br>
<br>
gold (no PGO) = 182 ms<br>
gold (PGO) = 141 ms<br>
<br>
lld (no PGO) = 193 ms<br>
lld (PGO) = 171 ms<br>
<br>
So `gold` and `lld` both profit from PGO quite a bit, while `ld`<br>
linked programs are slower with PGO. I then noticed that branch<br>
weights for `ld` were missing from most branches, while the counts for<br>
the other linkers are correct. All of this suggests to me that<br>
something goes wrong when `ld` tries to link in the profiling runtime.<br>
<br>
I'll be investigating further.<br>
<br>
[1] <a href="https://github.com/michaelwoerister/rust-pgo-test-programs/tree/master/branch_weights" rel="noreferrer" target="_blank">https://github.com/michaelwoerister/rust-pgo-test-programs/tree/master/branch_weights</a><br>
<br>
<br>
On Thu, Sep 12, 2019 at 6:31 PM Teresa Johnson <<a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a>> wrote:<br>
><br>
><br>
><br>
> On Thu, Sep 12, 2019 at 8:18 AM Teresa Johnson <<a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a>> wrote:<br>
>><br>
>> I just have a couple suggestions off the top of my head:<br>
>> - have you tried using the new pass manager (-fexperimental-new-pass-manager)? That has access to additional analysis info during inlining and is able to make more precise PGO based inline decisions.<br>
><br>
><br>
> (although note the above shouldn't make the difference between no performance and a typical PGO performance boost)<br>
><br>
> Another thing I just thought of - are you using -ffunction-sections and -fdata-sections? These will allow for PGO based function layout in the linker (assuming you are using lld or gold).<br>
><br>
>> - have you tried collecting profile data with and without PGO to see if you can compare where cycles are being spent? That's my usual way of debugging performance differences related to inlining or profile changes.<br>
>> - just a comment that it is odd you are getting better performance without the pre-inlining - which typically helps because you get better context-sensitive profile info. Maybe sanity check that the pre inlining is kicking in for both the profile gen and use passes?<br>
>><br>
>> Teresa<br>
>><br>
>> On Thu, Sep 12, 2019 at 2:18 AM Michael Woerister via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br>
>>><br>
>>> Hi everyone,<br>
>>><br>
>>> As part of my work for Mozilla's Low Level Tools team I've<br>
>>> implemented PGO in the Rust compiler. The feature is<br>
>>> available since Rust 1.37 [1]. However, so far we have not<br>
>>> seen any actual performance gains from enabling PGO for<br>
>>> Rust code. Performance even seems to drop 1-3% with PGO<br>
>>> enabled. I wonder why that is and I'm hoping that someone<br>
>>> here might have experience debugging PGO effectiveness.<br>
>>><br>
>>><br>
>>> PGO in the Rust compiler<br>
>>> ------------------------<br>
>>><br>
>>> The Rust compiler uses IR-level instrumentation (the<br>
>>> equivalent of Clang's `-fprofile-generate`/`-fprofile-use`).<br>
>>> This has worked pretty well and even enables doing PGO for<br>
>>> mixed Rust/C++ codebases when also using Clang.<br>
>>><br>
>>> The Rust compiler has regression tests that make sure that:<br>
>>><br>
>>> - instrumentation shows up in LLVM IR for the `generate` phase,<br>
>>>   and that<br>
>>><br>
>>> - profiling data is actually used during the `use` phase, i.e.<br>
>>>   that cold functions get marked with `cold` and hot functions<br>
>>>   get marked with `inline`.<br>
>>><br>
>>> I also verified manually that `branch_weights` are being set<br>
>>> in IR. So, from my perspective, the PGO implementation does<br>
>>> what it is supposed to do.<br>
>>><br>
>>> However, as already mentioned, in all benchmarks I've seen so<br>
>>> far performance seems to stay the same at best and often even<br>
>>> suffers slightly. Which is suprising because for C++ code<br>
>>> using Clang's version of IR-level instrumentation & PGO brings<br>
>>> signifcant gains (up to 5-10% from what I've seen in<br>
>>> benchmarks for Firefox).<br>
>>><br>
>>> One thing we noticed early on is that disabling the<br>
>>> pre-inlining pass (`-disable-preinline`) seems to consistently<br>
>>> improve the situation for Rust code. Doing that we sometimes<br>
>>> see performance wins of almost 1% over not using PGO. This<br>
>>> again is very different to C++ where disabling this pass<br>
>>> causes dramatic performance loses for the Firefox benchmarks.<br>
>>> And 1% performance improvement is still well below<br>
>>> expectations, I think.<br>
>>><br>
>>> So my questions to you are:<br>
>>><br>
>>> - Has anybody here observed something similar while<br>
>>>   wokring on or with PGO?<br>
>>><br>
>>> - Are there certain known characteristics of LLVM IR code<br>
>>>   that inhibit PGO's effectiveness and that IR produced by<br>
>>>   `rustc` might exhibit?<br>
>>><br>
>>> - Does anybody know of a good source that describes how to<br>
>>>   effectively debug a problem like this?<br>
>>><br>
>>> - Does anybody know of a small example program in C/C++<br>
>>>   that is known to profit from PGO and that could be<br>
>>>   re-implemented in Rust for comparison?<br>
>>><br>
>>> Thanks a lot for reading! Any help is appreciated.<br>
>>><br>
>>> -Michael<br>
>>><br>
>>> [1] <a href="https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html#profile-guided-optimization" rel="noreferrer" target="_blank">https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html#profile-guided-optimization</a><br>
>>> _______________________________________________<br>
>>> LLVM Developers mailing list<br>
>>> <a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
>>> <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
>><br>
>><br>
>><br>
>> --<br>
>> Teresa Johnson | Software Engineer | <a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a> |<br>
><br>
><br>
><br>
> --<br>
> Teresa Johnson | Software Engineer | <a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a> |<br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr"><div dir="ltr"><div><span style="font-family:Times;font-size:medium"><table cellspacing="0" cellpadding="0"><tbody><tr style="color:rgb(85,85,85);font-family:sans-serif;font-size:small"><td style="border-top:2px solid rgb(213,15,37)" nowrap>Teresa Johnson |</td><td style="border-top:2px solid rgb(51,105,232)" nowrap> Software Engineer |</td><td style="border-top:2px solid rgb(0,153,57)" nowrap> <a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a> |</td><td style="border-top:2px solid rgb(238,178,17)" nowrap><br></td></tr></tbody></table></span></div></div></div>
</blockquote></div>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><span style="font-family:Times;font-size:medium"><table cellspacing="0" cellpadding="0"><tbody><tr style="color:rgb(85,85,85);font-family:sans-serif;font-size:small"><td nowrap style="border-top:2px solid rgb(213,15,37)">Teresa Johnson |</td><td nowrap style="border-top:2px solid rgb(51,105,232)"> Software Engineer |</td><td nowrap style="border-top:2px solid rgb(0,153,57)"> <a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a> |</td><td nowrap style="border-top:2px solid rgb(238,178,17)"><br></td></tr></tbody></table></span></div></div></div></div>