Uh oh!
There was an error while loading. Please reload this page.
Optimize layout calculations in HashMap - #51340
Conversation
rust-highfive
commented
Jun 4, 2018
r? @kennytm (rust_highfive has picked a reviewer for you, use r? to override) |
rust-highfive
commented
Jun 4, 2018
Amanieu
commented
Jun 4, 2018
(stupid git pull doesn't update submodules by default...) Playground link for playing around with the generated code: https://play.rust-lang.org/?gist=b233a122e3223db47521f5b0a0a3911c&version=nightly&mode=release |
Amanieu
commented
Jun 4, 2018
r? @SimonSapin |
7bf6245 to
0b56145Comparerust-highfive
commented
Jun 4, 2018
The job Click to expand the log.I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
There was a problem hiding this comment.
This is weird, the NonZeroUsize::get(self) function is marked #[inline] and the constructor is a const fn. Did you by chance happen to look at the generated LLVM-IR for calculate_layout ?
There was a problem hiding this comment.
Try the playground link that I posted above. If you remove the map then it generates worse code. What seems to happen is that LLVM will emit an overflowing multiply to calculate pairs.size, and will use the overflow flag to set pairs.align to either 0 (LayoutErr) or the actual alignment.
There was a problem hiding this comment.
Perhaps the comment should include the second sentence of that explanation?
There was a problem hiding this comment.
Every caller of calculate_layout only use one of the returned Layout or offset. Now that they’re mostly calculated separately, aren’t we better off having two separate functions?
There was a problem hiding this comment.
To me this feels like more of a temporary hack to deal with a LLVM bug, rather than a permanent solution. Logically the offset calculation belongs as part of the layout calculation.
There was a problem hiding this comment.
@nnethercote I added a reference to #51346 in the comment.
nnethercote
commented
Jun 4, 2018
Nice! Hopefully this will fix the rustc perf regression. rustc uses hash tables a lot :) |
gnzlbg
commented
Jun 4, 2018
Avoiding playground::new:pushraxmovrsi,rdimovecx,8movrax,rsimulrcxmovrcx,raxjo .LBB3_3movedx,16movrax,rsimulrdxjo .LBB3_3addrax,rcxjb .LBB3_3movrax,rcxpoprcxret.LBB3_3:call core::result::unwrap_failedud2which is at least shorter (don't know if better) than using playground::new:movecx,8xoresi,esimovrax,rdimulrcxmovr8,rax setno r9bjo .LBB3_7movedx,16xorecx,ecxmovrax,rdimulrdx setno dljo .LBB3_7mov sil,r9bshlrsi,3movcl,dlshlrcx,3cmprcx,rsi cmovae rsi,rcxleardx,[r8+rcx]addrdx,-1negrcxandrcx,rdxsubrcx,r8addrcx,r8jb .LBB3_7addrax,rcxjb .LBB3_7movrdx,rsinegrdxcmprax,rdxja .LBB3_7testrsi,rsije .LBB3_7learax,[rsi+15]andrax,rsijne .LBB3_7movrax,rcxret.LBB3_7:pushrbpmovrbp,rspcall core::result::unwrap_failedud2However, given that both situations should just generate: playground::original:learax,[8*rdi]retI don't think that |
Amanieu
commented
Jun 4, 2018
|
@Amanieu that one was as good as the original IIRC (that is, this PR fixes the perf regression). My point was that maybe it is worth fixing whatever codegen bug is causing the perf regression in the first place because, while we might add these workarounds in You mentioned the regression might be caused by making |
Amanieu
commented
Jun 4, 2018
@gnzlbg If you use my original playground link and remove the This is the codegen bug that I was talking about, which is caused by |
Can you explain how does that show that it is caused by |
It's obvious if you look at the generated LLVM IR: |
gnzlbg
commented
Jun 4, 2018
Looking only at playground::new_optimized:movrcx,rdimovedx,8movrax,rcxmulrdxmovrsi,raxmovedx,16xoredi,edimovrax,rcxmulrdx setno dillearax,[rsi+8*rdi]addrax,-1shlrdi,3negrdiandrdi,raxmovrax,rdiretand without playground::new_optimized:learax,[8*rdi]retIt looks like not using |
Mark-Simulacrum
commented
Jun 4, 2018
@bors p=1 for when this is approved |
This now produces the same assembly code as the previous implementation.
SimonSapin
commented
Jun 4, 2018
bors
commented
Jun 4, 2018
📌 Commit b69724f has been approved by |
bors
commented
Jun 4, 2018
Optimize layout calculations in HashMap This now produces the same assembly code as the previous implementation. cc #51163@nnethercote@gnzlbg@andjo403
bors
commented
Jun 4, 2018
☀️ Test successful - status-appveyor, status-travis |
nnethercote
commented
Jun 5, 2018
I just did some local measurements with Cachegrind and the numbers are looking much better -- the regression from #51163 looks to be entirely fixed. Thank you! |
nikic
commented
Jun 5, 2018
This doesn't seem to show any difference though. Am using it incorrectly? |
Mark-Simulacrum
commented
Jun 5, 2018
That should be accurate; I'm not sure why we're seeing a difference from @nnethercote's local benchmarks. |
Amanieu
commented
Jun 5, 2018
Note that #51226 also significantly improve the performance since it marked several |
nnethercote
commented
Jun 6, 2018
My measurements were with Cachegrind rather than perf-stat... that shouldn't make any difference though. |
nnethercote
commented
Jun 7, 2018
Can anyone think of reasons why I would see improvements on my machine, but the rustc-perf machine would not? Are the clang versions guaranteed to be the same? |
Mark-Simulacrum
commented
Jun 7, 2018
Clang is not installed on the perf collector (though not sure what specific clang you are referring to...); gcc is version 5.4.0. |
nnethercote
commented
Jun 8, 2018
Sorry, I meant LLVM, not clang. Are the LLVM versions guaranteed to be the same? |
Mark-Simulacrum
commented
Jun 8, 2018
Yes, LLVM should be version equivalent (by default), though the way it's compiled might be different, e.g. using gcc locally vs. clang on Travis. I suppose that could play a role, but it would be decidedly odd. |
This now produces the same assembly code as the previous implementation.
cc #51163@nnethercote@gnzlbg@andjo403