Skip to content

Commit

Permalink
Reduce ProgramCache write-lock contention
Browse files Browse the repository at this point in the history
  • Loading branch information
ryoqun committed Apr 25, 2024
1 parent 8e331e1 commit cc12279
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 9 deletions.
7 changes: 7 additions & 0 deletions program-runtime/src/loaded_programs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,7 @@ pub struct ProgramCacheForTxBatch {
/// The epoch of the last rerooting
pub latest_root_epoch: Epoch,
pub hit_max_limit: bool,
pub loaded_missing: bool,
}

impl ProgramCacheForTxBatch {
Expand All @@ -654,6 +655,7 @@ impl ProgramCacheForTxBatch {
upcoming_environments,
latest_root_epoch,
hit_max_limit: false,
loaded_missing: false,
}
}

Expand All @@ -669,6 +671,7 @@ impl ProgramCacheForTxBatch {
upcoming_environments: cache.get_upcoming_environments_for_epoch(epoch),
latest_root_epoch: cache.latest_root_epoch,
hit_max_limit: false,
loaded_missing: false,
}
}

Expand Down Expand Up @@ -725,6 +728,10 @@ impl ProgramCacheForTxBatch {
self.replenish(*key, entry.clone());
})
}

pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
}

pub enum ProgramCacheMatchCriteria {
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4162,7 +4162,7 @@ impl Bank {
programs_modified_by_tx,
} = execution_result
{
if details.status.is_ok() {
if details.status.is_ok() && !programs_modified_by_tx.is_empty() {
let mut cache = self.transaction_processor.program_cache.write().unwrap();
cache.merge(programs_modified_by_tx);
}
Expand Down
23 changes: 15 additions & 8 deletions svm/src/transaction_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,14 +292,20 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {

execution_time.stop();

const SHRINK_LOADED_PROGRAMS_TO_PERCENTAGE: u8 = 90;
self.program_cache
.write()
.unwrap()
.evict_using_2s_random_selection(
Percentage::from(SHRINK_LOADED_PROGRAMS_TO_PERCENTAGE),
self.slot,
);
// Skip eviction when there's no chance this particular tx batch has increased the size of
// ProgramCache entries. Note that this flag is deliberately defined, so that there's still
// at least one other batch, which will evict the program cache, even after the occurrences
// of cooperative loading.
if programs_loaded_for_tx_batch.borrow().loaded_missing {
const SHRINK_LOADED_PROGRAMS_TO_PERCENTAGE: u8 = 90;
self.program_cache
.write()
.unwrap()
.evict_using_2s_random_selection(
Percentage::from(SHRINK_LOADED_PROGRAMS_TO_PERCENTAGE),
self.slot,
);
}

debug!(
"load: {}us execute: {}us txs_len={}",
Expand Down Expand Up @@ -395,6 +401,7 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
}
// Submit our last completed loading task.
if let Some((key, program)) = program_to_store.take() {
loaded_programs_for_txs.as_mut().unwrap().loaded_missing = true;
if program_cache.finish_cooperative_loading_task(self.slot, key, program)
&& limit_to_load_programs
{
Expand Down

0 comments on commit cc12279

Please sign in to comment.