-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
[Parallel Executor] Rolling Commit #6079
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Awesome! Before a full review, a few points we may want to consider before landing:
Otherwise, as noted, let's try to add a few extra unit / proptests that stress the committing logic |
…ptos-core into daniel-rolling-commit-debug
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
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.
Let's make sure try_commit does not starve other threads.
We can use parking lot rwlock for execution and validation statuses - please adjust the uses based on whether we only require a read, or whether we also update the respective statuses.
Another way to use it is to grab read lock (upgradable) first, and then upgrade it if writing becomes necessary, I suggested this flow for the try_commit execution status, as an example, not sure if it's useful elsewhere.
We can then also revert changes to mutex (no need to wrap try_lock, we won't be using it on aptos infallable).
and let's regenerate those numbers make sure we don't lose performance somehow (we shouldn't) |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
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.
beautiful
Arc, Condvar, | ||
}, | ||
}; | ||
|
||
const TXN_IDX_MASK: u64 = (1 << 32) - 1; | ||
|
||
// Type aliases. | ||
pub type TxnIndex = usize; |
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.
should we change this to u32? it seems cleaner for the validator index use
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.
Since TxnIndex is also used in many other places other than validation_idx, I will keep the current one.
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 am merging the definitions in my diff (MVHashMap redefined and a TODO anyway), and I can try to redefine it there.
|
||
if let Some(validation_status) = self.txn_status[*commit_idx].1.try_read() { | ||
// Acquired the validation status lock, now try the status lock. | ||
if let Some(status) = self.txn_status[*commit_idx].0.try_upgradable_read() { |
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.
Nit: similar to Zekun's comment, .0 and .1 are not very readable.
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.
Added comments.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
✅ Forge suite
|
This comment has been minimized.
This comment has been minimized.
✅ Forge suite
|
This PR implements the methodology called rolling commit to track the prefix of committed transaction in the parallel execution accurately, without introducing much overhead compared to the current lazy commit approach which can only commit all the transactions together.
Here are some p2p benchmark numbers compared to the previous commit method (lazy commit of the whole block) on my MBP with 10 cores/threads. The time unit is milliseconds. Note that the numbers here can be noisy and better experiments can be done if needed. Two versions of rolling commit protect txn status with Mutex and RwLock, respectively.
UPDATE
p2p benchmark numbers compared to the previous commit method (lazy commit of the whole block) on AWS ubuntu c5a.16xlarge instance. The time unit is milliseconds.
With 8 threads
With 16 threads
Broader Context
Rolling commit is needed for per-block limit & aggregator. We have a dedicated-thread solution implemented in this PR #5948 (which has additional validation overhead), but this is an attempt to remove the trade-offs and get the rolling commit almost for free. The idea is to track the waves of validations, and know when the last one happens.