Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

storage: avoid EncodeMVCCValue struct comparison #88989

Merged
merged 1 commit into from
Oct 3, 2022

Conversation

erikgrinaker
Copy link
Contributor

@erikgrinaker erikgrinaker commented Sep 29, 2022

In Go 1.19, struct comparisons saw a significant performance regression, apparently due to the use of memeqbody. This patch changes EncodeMVCCValue to use field comparisons instead of struct comparisons, which yields a significant performance gain.

Unfortunately, this prevents mid-stack inlining. However, the struct comparison regression is significantly larger than the inlining gains. We should reconsider this once Go 1.20 lands, where the regression has been fixed.

name                                                              old time/op  new time/op  delta
EncodeMVCCValue/header=empty/value=tombstone-24                   5.96ns ± 1%  4.66ns ± 0%  -21.85%  (p=0.000 n=9+9)
EncodeMVCCValue/header=empty/value=short-24                       5.93ns ± 0%  4.66ns ± 0%  -21.40%  (p=0.000 n=9+9)
EncodeMVCCValue/header=empty/value=long-24                        5.92ns ± 0%  4.66ns ± 0%  -21.31%  (p=0.000 n=10+10)
EncodeMVCCValue/header=local_walltime/value=tombstone-24          51.9ns ± 1%  49.5ns ± 1%   -4.81%  (p=0.000 n=9+10)
EncodeMVCCValue/header=local_walltime/value=short-24              54.2ns ± 1%  52.5ns ± 1%   -3.25%  (p=0.000 n=10+10)
EncodeMVCCValue/header=local_walltime/value=long-24               1.34µs ± 2%  1.36µs ± 1%   +1.69%  (p=0.001 n=10+9)
EncodeMVCCValue/header=local_walltime+logical/value=tombstone-24  56.3ns ± 0%  53.3ns ± 1%   -5.40%  (p=0.000 n=10+10)
EncodeMVCCValue/header=local_walltime+logical/value=short-24      58.8ns ± 0%  56.3ns ± 2%   -4.18%  (p=0.000 n=10+9)
EncodeMVCCValue/header=local_walltime+logical/value=long-24       1.36µs ± 3%  1.36µs ± 1%     ~     (p=0.269 n=10+9)

Resolves #88818.

Release note: None

In Go 1.19, struct comparisons saw a significant performance regression,
apparently due to the use of `memeqbody`. This patch changes
`EncodeMVCCValue` to use field comparisons instead of struct
comparisons, which yields a significant performance gain.

Unfortunately, this prevents mid-stack inlining. However, the struct
comparison regression is significantly larger than the inlining gains.
We should reconsider this once Go 1.20 lands, where the regression has
been fixed.

```
name                                                              old time/op  new time/op  delta
EncodeMVCCValue/header=empty/value=tombstone-24                   5.96ns ± 1%  4.66ns ± 0%  -21.85%  (p=0.000 n=9+9)
EncodeMVCCValue/header=empty/value=short-24                       5.93ns ± 0%  4.66ns ± 0%  -21.40%  (p=0.000 n=9+9)
EncodeMVCCValue/header=empty/value=long-24                        5.92ns ± 0%  4.66ns ± 0%  -21.31%  (p=0.000 n=10+10)
EncodeMVCCValue/header=local_walltime/value=tombstone-24          51.9ns ± 1%  49.5ns ± 1%   -4.81%  (p=0.000 n=9+10)
EncodeMVCCValue/header=local_walltime/value=short-24              54.2ns ± 1%  52.5ns ± 1%   -3.25%  (p=0.000 n=10+10)
EncodeMVCCValue/header=local_walltime/value=long-24               1.34µs ± 2%  1.36µs ± 1%   +1.69%  (p=0.001 n=10+9)
EncodeMVCCValue/header=local_walltime+logical/value=tombstone-24  56.3ns ± 0%  53.3ns ± 1%   -5.40%  (p=0.000 n=10+10)
EncodeMVCCValue/header=local_walltime+logical/value=short-24      58.8ns ± 0%  56.3ns ± 2%   -4.18%  (p=0.000 n=10+9)
EncodeMVCCValue/header=local_walltime+logical/value=long-24       1.36µs ± 3%  1.36µs ± 1%     ~     (p=0.269 n=10+9)
```

Release note: None
@erikgrinaker erikgrinaker requested review from nicktrav, nvanbenschoten and a team September 29, 2022 11:19
@erikgrinaker erikgrinaker requested a review from a team as a code owner September 29, 2022 11:19
@erikgrinaker erikgrinaker self-assigned this Sep 29, 2022
@cockroach-teamcity
Copy link
Member

This change is Reviewable

@erikgrinaker
Copy link
Contributor Author

Any bright ideas on how we can retain the mid-stack inlining here?

Copy link
Collaborator

@jbowens jbowens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose we could manually inline it (the logic itself is tiny), and litter warnings to update the manually inlined code in EncodeMVCCValue in many places. I don't think it's worth it though.

:lgtm:

Reviewed all commit messages.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @nicktrav and @nvanbenschoten)

Copy link
Member

@nvanbenschoten nvanbenschoten left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This :lgtm: for the time being. It is unfortunate that we need to make these kinds of changes (adding code complexity and losing valuable inlining budget). I'd feel better about merging this if we had an issue tracking Go 1.20 and suggesting that we revert this and #88911 once the regression in Go is resolved.

Reviewed 4 of 4 files at r1, all commit messages.
Reviewable status: :shipit: complete! 2 of 0 LGTMs obtained (waiting on @nicktrav)

@erikgrinaker
Copy link
Contributor Author

TFTRs!

bors r+

I'd feel better about merging this if we had an issue tracking Go 1.20 and suggesting that we revert this and #88911 once the regression in Go is resolved.

#89199

@craig
Copy link
Contributor

craig bot commented Oct 3, 2022

Build failed (retrying...):

@craig
Copy link
Contributor

craig bot commented Oct 3, 2022

Build succeeded:

@craig craig bot merged commit d36efd1 into cockroachdb:master Oct 3, 2022
@erikgrinaker erikgrinaker deleted the mvccvalue-struct-comparison branch October 30, 2022 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

storage: performance regression in EncodeMVCCKey and EncodeMVCCValue
4 participants