AcctIdx: hold ranges in memory uses multiple threads (#22031)
This commit is contained in:
committed by
GitHub
parent
5b464a32f5
commit
bdae2993e0
@ -870,13 +870,17 @@ impl Accounts {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hold_range_in_memory<R>(&self, range: &R, start_holding: bool)
|
pub fn hold_range_in_memory<R>(
|
||||||
where
|
&self,
|
||||||
R: RangeBounds<Pubkey> + std::fmt::Debug,
|
range: &R,
|
||||||
|
start_holding: bool,
|
||||||
|
thread_pool: &rayon::ThreadPool,
|
||||||
|
) where
|
||||||
|
R: RangeBounds<Pubkey> + std::fmt::Debug + Sync,
|
||||||
{
|
{
|
||||||
self.accounts_db
|
self.accounts_db
|
||||||
.accounts_index
|
.accounts_index
|
||||||
.hold_range_in_memory(range, start_holding)
|
.hold_range_in_memory(range, start_holding, thread_pool)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_to_collect_rent_eagerly<R: RangeBounds<Pubkey> + std::fmt::Debug>(
|
pub fn load_to_collect_rent_eagerly<R: RangeBounds<Pubkey> + std::fmt::Debug>(
|
||||||
@ -1331,12 +1335,12 @@ mod tests {
|
|||||||
fn test_hold_range_in_memory() {
|
fn test_hold_range_in_memory() {
|
||||||
let accts = Accounts::default_for_tests();
|
let accts = Accounts::default_for_tests();
|
||||||
let range = Pubkey::new(&[0; 32])..=Pubkey::new(&[0xff; 32]);
|
let range = Pubkey::new(&[0; 32])..=Pubkey::new(&[0xff; 32]);
|
||||||
accts.hold_range_in_memory(&range, true);
|
accts.hold_range_in_memory(&range, true, &test_thread_pool());
|
||||||
accts.hold_range_in_memory(&range, false);
|
accts.hold_range_in_memory(&range, false, &test_thread_pool());
|
||||||
accts.hold_range_in_memory(&range, true);
|
accts.hold_range_in_memory(&range, true, &test_thread_pool());
|
||||||
accts.hold_range_in_memory(&range, true);
|
accts.hold_range_in_memory(&range, true, &test_thread_pool());
|
||||||
accts.hold_range_in_memory(&range, false);
|
accts.hold_range_in_memory(&range, false, &test_thread_pool());
|
||||||
accts.hold_range_in_memory(&range, false);
|
accts.hold_range_in_memory(&range, false, &test_thread_pool());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1353,7 +1357,7 @@ mod tests {
|
|||||||
let range2_inclusive = range2.start..=range2.end;
|
let range2_inclusive = range2.start..=range2.end;
|
||||||
assert_eq!(0, idx.bin_calculator.bin_from_pubkey(&range2.start));
|
assert_eq!(0, idx.bin_calculator.bin_from_pubkey(&range2.start));
|
||||||
assert_eq!(0, idx.bin_calculator.bin_from_pubkey(&range2.end));
|
assert_eq!(0, idx.bin_calculator.bin_from_pubkey(&range2.end));
|
||||||
accts.hold_range_in_memory(&range, true);
|
accts.hold_range_in_memory(&range, true, &test_thread_pool());
|
||||||
idx.account_maps.iter().enumerate().for_each(|(_bin, map)| {
|
idx.account_maps.iter().enumerate().for_each(|(_bin, map)| {
|
||||||
let map = map.read().unwrap();
|
let map = map.read().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -1361,7 +1365,7 @@ mod tests {
|
|||||||
vec![range.clone()]
|
vec![range.clone()]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
accts.hold_range_in_memory(&range2, true);
|
accts.hold_range_in_memory(&range2, true, &test_thread_pool());
|
||||||
idx.account_maps.iter().enumerate().for_each(|(bin, map)| {
|
idx.account_maps.iter().enumerate().for_each(|(bin, map)| {
|
||||||
let map = map.read().unwrap();
|
let map = map.read().unwrap();
|
||||||
let expected = if bin == 0 {
|
let expected = if bin == 0 {
|
||||||
@ -1376,8 +1380,12 @@ mod tests {
|
|||||||
bin
|
bin
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
accts.hold_range_in_memory(&range, false);
|
accts.hold_range_in_memory(&range, false, &test_thread_pool());
|
||||||
accts.hold_range_in_memory(&range2, false);
|
accts.hold_range_in_memory(&range2, false, &test_thread_pool());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_thread_pool() -> rayon::ThreadPool {
|
||||||
|
crate::accounts_db::make_min_priority_thread_pool()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -13,6 +13,10 @@ use {
|
|||||||
log::*,
|
log::*,
|
||||||
ouroboros::self_referencing,
|
ouroboros::self_referencing,
|
||||||
rand::{thread_rng, Rng},
|
rand::{thread_rng, Rng},
|
||||||
|
rayon::{
|
||||||
|
iter::{IntoParallelIterator, ParallelIterator},
|
||||||
|
ThreadPool,
|
||||||
|
},
|
||||||
solana_measure::measure::Measure,
|
solana_measure::measure::Measure,
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
clock::{BankId, Slot},
|
clock::{BankId, Slot},
|
||||||
@ -742,21 +746,22 @@ impl<'a, T: IndexValue> AccountsIndexIterator<'a, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hold_range_in_memory<R>(&self, range: &R, start_holding: bool)
|
pub fn hold_range_in_memory<R>(&self, range: &R, start_holding: bool, thread_pool: &ThreadPool)
|
||||||
where
|
where
|
||||||
R: RangeBounds<Pubkey> + Debug,
|
R: RangeBounds<Pubkey> + Debug + Sync,
|
||||||
{
|
{
|
||||||
// forward this hold request ONLY to the bins which contain keys in the specified range
|
// forward this hold request ONLY to the bins which contain keys in the specified range
|
||||||
let (start_bin, bin_range) = self.bin_start_and_range();
|
let (start_bin, bin_range) = self.bin_start_and_range();
|
||||||
self.account_maps
|
// the idea is this range shouldn't be more than a few buckets, but the process of loading from disk buckets is very slow
|
||||||
.iter()
|
// so, parallelize the bucket loads
|
||||||
.skip(start_bin)
|
thread_pool.install(|| {
|
||||||
.take(bin_range)
|
(0..bin_range).into_par_iter().for_each(|idx| {
|
||||||
.for_each(|map| {
|
let map = &self.account_maps[idx + start_bin];
|
||||||
map.read()
|
map.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.hold_range_in_memory(range, start_holding);
|
.hold_range_in_memory(range, start_holding);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1460,12 +1465,12 @@ impl<T: IndexValue> AccountsIndex<T> {
|
|||||||
rv.map(|index| slice.len() - 1 - index)
|
rv.map(|index| slice.len() - 1 - index)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hold_range_in_memory<R>(&self, range: &R, start_holding: bool)
|
pub fn hold_range_in_memory<R>(&self, range: &R, start_holding: bool, thread_pool: &ThreadPool)
|
||||||
where
|
where
|
||||||
R: RangeBounds<Pubkey> + Debug,
|
R: RangeBounds<Pubkey> + Debug + Sync,
|
||||||
{
|
{
|
||||||
let iter = self.iter(Some(range), true);
|
let iter = self.iter(Some(range), true);
|
||||||
iter.hold_range_in_memory(range, start_holding);
|
iter.hold_range_in_memory(range, start_holding, thread_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_startup(&self, value: bool) {
|
pub fn set_startup(&self, value: bool) {
|
||||||
|
@ -4179,7 +4179,10 @@ impl Bank {
|
|||||||
fn collect_rent_in_partition(&self, partition: Partition) -> usize {
|
fn collect_rent_in_partition(&self, partition: Partition) -> usize {
|
||||||
let subrange = Self::pubkey_range_from_partition(partition);
|
let subrange = Self::pubkey_range_from_partition(partition);
|
||||||
|
|
||||||
self.rc.accounts.hold_range_in_memory(&subrange, true);
|
let thread_pool = &self.rc.accounts.accounts_db.thread_pool;
|
||||||
|
self.rc
|
||||||
|
.accounts
|
||||||
|
.hold_range_in_memory(&subrange, true, thread_pool);
|
||||||
|
|
||||||
let accounts = self
|
let accounts = self
|
||||||
.rc
|
.rc
|
||||||
@ -4213,7 +4216,9 @@ impl Bank {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.extend(rent_debits.into_unordered_rewards_iter());
|
.extend(rent_debits.into_unordered_rewards_iter());
|
||||||
|
|
||||||
self.rc.accounts.hold_range_in_memory(&subrange, false);
|
self.rc
|
||||||
|
.accounts
|
||||||
|
.hold_range_in_memory(&subrange, false, thread_pool);
|
||||||
account_count
|
account_count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user