Skip to content

Commit

Permalink
accounts-db: send batches of accounts to the background hasher (solan…
Browse files Browse the repository at this point in the history
…a-labs#810)

Instead of sending accounts individually, send batches of accounts for
background hashing.

Before this change we used to send accounts individually, and the
background thread used to do:

    loop {
        let account = receiver.recv();
        account.hash();
        // go back to sleep in recv()
    }

Because most accounts are small and hashing them is very fast, the
background thread used to sleep a lot, and required many syscalls from
the sender in order to be woken up.

Batching reduces the number of syscalls.
  • Loading branch information
alessandrod authored and jeffwashington committed Apr 19, 2024
1 parent 9de8214 commit 3872454
Showing 1 changed file with 24 additions and 19 deletions.
43 changes: 24 additions & 19 deletions accounts-db/src/accounts_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1316,7 +1316,7 @@ pub struct AccountsDb {

write_cache_limit_bytes: Option<u64>,

sender_bg_hasher: Option<Sender<CachedAccount>>,
sender_bg_hasher: Option<Sender<Vec<CachedAccount>>>,
read_only_accounts_cache: ReadOnlyAccountsCache,

/// distribute the accounts across storage lists
Expand Down Expand Up @@ -2752,17 +2752,19 @@ impl AccountsDb {
}
}

fn background_hasher(receiver: Receiver<CachedAccount>) {
fn background_hasher(receiver: Receiver<Vec<CachedAccount>>) {
info!("Background account hasher has started");
loop {
let result = receiver.recv();
match result {
Ok(account) => {
// if we hold the only ref, then this account doesn't need to be hashed, we ignore this account and it will disappear
if Arc::strong_count(&account) > 1 {
// this will cause the hash to be calculated and store inside account if it needs to be calculated
let _ = (*account).hash();
};
Ok(accounts) => {
for account in accounts {
// if we hold the only ref, then this account doesn't need to be hashed, we ignore this account and it will disappear
if Arc::strong_count(&account) > 1 {
// this will cause the hash to be calculated and store inside account if it needs to be calculated
let _ = (*account).hash();
};
}
}
Err(err) => {
info!("Background account hasher is stopping because: {err}");
Expand Down Expand Up @@ -6388,7 +6390,7 @@ impl AccountsDb {
Box::new(std::iter::empty())
};

txn_iter
let (account_infos, cached_accounts) = txn_iter
.enumerate()
.map(|(i, txn)| {
let mut account_info = AccountInfo::default();
Expand All @@ -6407,17 +6409,20 @@ impl AccountsDb {

let cached_account =
self.accounts_cache.store(slot, pubkey, account_shared_data);
// hash this account in the bg
match &self.sender_bg_hasher {
Some(ref sender) => {
let _ = sender.send(cached_account);
}
None => (),
};
});
account_info
(account_info, cached_account)
})
})
.collect()
.unzip();

// hash this accounts in bg
match &self.sender_bg_hasher {
Some(ref sender) => {
let _ = sender.send(cached_accounts);
}
None => (),
};

account_infos
}

fn store_accounts_to<'a: 'c, 'b, 'c>(
Expand Down

0 comments on commit 3872454

Please sign in to comment.