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

[Parallel Executor] Rolling Commit #6079

Merged
merged 29 commits into from
Jan 28, 2023
Merged

[Parallel Executor] Rolling Commit #6079

merged 29 commits into from
Jan 28, 2023

Conversation

danielxiangzl
Copy link
Contributor

@danielxiangzl danielxiangzl commented Jan 5, 2023

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.

(# account, # txns) (100, 1k) (100, 10k) (100, 50k) (1k, 1k) (1k, 10k) (1k, 50k)
Lazy cmt 57 301 1318 52 257 1145
Rolling cmt w. Mutex 60 327 1480 55 299 1284
Rolling cmt w. RwLock 52 284 1271 50 249 1098
PR #5948 60 335 1525 56 314 1412

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

(# account, # txns) (100, 1k) (100, 10k) (1k, 1k) (1k, 10k)
Lazy cmt 81 562 76 496
Rolling cmt 82 558 75 494

With 16 threads

(# account, # txns) (100, 1k) (100, 10k) (1k, 1k) (1k, 10k)
Lazy cmt 64 375 57 291
Rolling cmt 64 372 57 289

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.

@danielxiangzl danielxiangzl added the CICD:run-e2e-tests when this label is present github actions will run all land-blocking e2e tests from the PR label Jan 6, 2023
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@danielxiangzl danielxiangzl marked this pull request as ready for review January 7, 2023 00:24
@danielxiangzl danielxiangzl requested a review from grao1991 January 9, 2023 19:43
@gelash gelash requested a review from runtian-zhou January 11, 2023 00:40
@gelash
Copy link
Contributor

gelash commented Jan 11, 2023

Awesome!

Before a full review, a few points we may want to consider before landing:

  • whether to yield (std::hint) and when
  • can committing thread when there are no tasks starve other threads out of locks for non negligible time (fairness)
  • try_lock (but likely why not)
  • can required_wave be simplified or removed (I think not)

Otherwise, as noted, let's try to add a few extra unit / proptests that stress the committing logic

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Copy link
Contributor

@gelash gelash left a 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).

aptos-move/block-executor/src/scheduler.rs Outdated Show resolved Hide resolved
aptos-move/block-executor/src/scheduler.rs Outdated Show resolved Hide resolved
aptos-move/block-executor/src/scheduler.rs Outdated Show resolved Hide resolved
aptos-move/block-executor/src/scheduler.rs Outdated Show resolved Hide resolved
@gelash
Copy link
Contributor

gelash commented Jan 20, 2023

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)

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Copy link
Contributor

@zekun000 zekun000 left a 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;
Copy link
Contributor

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

Copy link
Contributor Author

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.

Copy link
Contributor

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.

aptos-move/block-executor/src/scheduler.rs Outdated Show resolved Hide resolved
aptos-move/block-executor/src/scheduler.rs Show resolved Hide resolved

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() {
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added comments.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions
Copy link
Contributor

✅ Forge suite compat success on testnet_2d8b1b57553d869190f61df1aaf7f31a8fc19a7b ==> 15c7a147ac567f39763553b12e9fdeee7e43eabf

Compatibility test results for testnet_2d8b1b57553d869190f61df1aaf7f31a8fc19a7b ==> 15c7a147ac567f39763553b12e9fdeee7e43eabf (PR)
1. Check liveness of validators at old version: testnet_2d8b1b57553d869190f61df1aaf7f31a8fc19a7b
compatibility::simple-validator-upgrade::liveness-check : 8060 TPS, 4738 ms latency, 6900 ms p99 latency,no expired txns
2. Upgrading first Validator to new version: 15c7a147ac567f39763553b12e9fdeee7e43eabf
compatibility::simple-validator-upgrade::single-validator-upgrade : 4604 TPS, 8958 ms latency, 11800 ms p99 latency,no expired txns
3. Upgrading rest of first batch to new version: 15c7a147ac567f39763553b12e9fdeee7e43eabf
compatibility::simple-validator-upgrade::half-validator-upgrade : 4638 TPS, 8773 ms latency, 11500 ms p99 latency,no expired txns
4. upgrading second batch to new version: 15c7a147ac567f39763553b12e9fdeee7e43eabf
compatibility::simple-validator-upgrade::rest-validator-upgrade : 7069 TPS, 5342 ms latency, 9200 ms p99 latency,no expired txns
5. check swarm health
Compatibility test for testnet_2d8b1b57553d869190f61df1aaf7f31a8fc19a7b ==> 15c7a147ac567f39763553b12e9fdeee7e43eabf passed
Test Ok

@github-actions

This comment has been minimized.

@github-actions
Copy link
Contributor

✅ Forge suite land_blocking success on 15c7a147ac567f39763553b12e9fdeee7e43eabf

performance benchmark with full nodes : 6260 TPS, 6315 ms latency, 11100 ms p99 latency,(!) expired 600 out of 2673880 txns
Test Ok

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CICD:run-e2e-tests when this label is present github actions will run all land-blocking e2e tests from the PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants