forked from solana-labs/solana
-
Notifications
You must be signed in to change notification settings - Fork 232
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
Adding additional logging when overflow occurs in calculate_stake_rew… #3783
Merged
Merged
Changes from 3 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
d8b2668
Adding additional logging when overflow occurs in calculate_stake_rew…
roryharr 90ef04b
Merge branch 'master' into log_stake_rewards_overflows
roryharr 3c0e51e
Updated code to use expects statements, and test case macros based on…
roryharr 377016d
Resolving Performance Degredation by removing formatted output
roryharr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -185,11 +185,17 @@ fn calculate_stake_rewards( | |||||
|
||||||
let rewards = points | ||||||
.checked_mul(u128::from(point_value.rewards)) | ||||||
.unwrap() | ||||||
.checked_div(point_value.points) | ||||||
.unwrap(); | ||||||
.expect(&format!( | ||||||
"Rewards should fit within u128, inputs were {} and {}", | ||||||
points, point_value.rewards | ||||||
)); | ||||||
|
||||||
let rewards = u64::try_from(rewards).unwrap(); | ||||||
// The unwrap is safe, as points_value.points is guaranteed to be non zero above. | ||||||
// Expect is verifying that the result fits in u64 | ||||||
let rewards = u64::try_from(rewards.checked_div(point_value.points).unwrap()).expect(&format!( | ||||||
"Rewards should fit within u64, inputs were {}, {} and {}", | ||||||
points, point_value.rewards, point_value.points | ||||||
)); | ||||||
|
||||||
// don't bother trying to split if fractional lamports got truncated | ||||||
if rewards == 0 { | ||||||
|
@@ -231,6 +237,8 @@ mod tests { | |||||
super::*, | ||||||
crate::{points::null_tracer, stake_state::new_stake}, | ||||||
solana_sdk::{native_token, pubkey::Pubkey}, | ||||||
std::u64, | ||||||
roryharr marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
test_case::test_case, | ||||||
}; | ||||||
|
||||||
#[test] | ||||||
|
@@ -610,6 +618,29 @@ mod tests { | |||||
); | ||||||
} | ||||||
|
||||||
#[test_case(u64::MAX, 1_000, u64::MAX => panics "Rewards should fit within u128")] | ||||||
#[test_case(1, u64::MAX, u64::MAX => panics "Rewards should fit within u64")] | ||||||
fn calculate_rewards_tests(stake: u64, rewards: u64, credits: u64) { | ||||||
let mut vote_state = VoteState::default(); | ||||||
|
||||||
let stake = new_stake(stake, &Pubkey::default(), &vote_state, u64::MAX); | ||||||
|
||||||
vote_state.increment_credits(0, credits); | ||||||
|
||||||
calculate_stake_rewards( | ||||||
0, | ||||||
&stake, | ||||||
&PointValue { | ||||||
rewards: rewards, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. clippy is also complaining about this line in CI https://buildkite.com/anza/agave/builds/15002#01938ee1-02e8-4df2-8494-112c107b5803:
Suggested change
|
||||||
points: 1, | ||||||
}, | ||||||
&vote_state, | ||||||
&StakeHistory::default(), | ||||||
null_tracer(), | ||||||
None, | ||||||
); | ||||||
} | ||||||
|
||||||
#[test] | ||||||
fn test_stake_state_calculate_points_with_typical_values() { | ||||||
let vote_state = VoteState::default(); | ||||||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for only doing this now, but I ran a bench on this PR, and just adding the string formatting has a surprising negative performance impact, causing this function to go from ~5.28ns to ~7ns.
Since rewards payouts are a huge bottleneck, I'm hesitant to do anything that will negatively impact performance. I also tried changing to
unwrap_or_else
to panic lazily, but it made no difference. If we use static strings, however, the performance is exactly the same. What do you think about using static strings instead? That would be just "Rewards should fit within u128" and "Rewards should fit within u64"There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting! I guess it can discard the values otherwise/re-use the register space. I wonder if it's a single value causing the perf differentiation (eg points).
Let me see if i can get setup on my side to measure and get a no perf delta improvement that still provides some useful data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah for sure! Here's my bench -- it requires making a few extra structs public to make it work, but I hope it provides a good start:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, I got it to work locally. Seeing similar results that means there is no way to log useful values without effecting performance.
One interesting/very surprising result:
test rewards::tests::bench_add_two ... bench: 38.25 ns/iter (+/- 0.54)
test rewards::tests::bench_add_two ... bench: 22.27 ns/iter (+/- 0.67)
Even printing constants as u32 is causing a performance degradation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On further testing, even having the expects statement is causing a performance delta.
I will close this out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On my testing, when I did
expect("static string")
it recovered the original performance, which makes sense since there's no extra work required. If you wanted to do that, I'd be down!There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested that and still saw significant performance delta.
Base code:
test rewards::tests::bench_calculate_stake_rewards ... bench: 8.78 ns/iter (+/- 0.32)
With expects using static string:
test rewards::tests::bench_calculate_stake_rewards ... bench: 23.16 ns/iter (+/- 0.43)
Edit: It was because the format call was still present, despite no formatting being used. Removing the formatting call I get the same results as with unwrap.